1. 问题背景与现象解析
最近在部署Oracle APEX应用时,不少开发者遇到了ORDS连接数据库报错574的问题。这个错误看似简单,但背后隐藏着一个容易被忽视的关键细节——ORDS_PUBLIC_USER用户过期。作为一名长期与Oracle打交道的DBA,我发现这个问题在社区中被反复提及,今天就来彻底剖析这个"顽疾"。
当你在启动ORDS后访问APEX应用或ORDS接口时,可能会遇到这样的错误提示:
code复制ORDS was unable to make a connection to the database. The database user specified by db.username configuration setting is expired. The connection pool named: |default|lo| had the following error(s): UCP-29: Failed to get a connection
这个错误的核心在于ORDS配置的数据库用户密码已经过期。有趣的是,大多数开发者都知道要处理APEX_PUBLIC_USER的密码过期问题,却常常忽略ORDS_PUBLIC_USER这个同样关键的用户。这两个用户就像APEX系统的"左右手"——APEX_PUBLIC_USER负责前端应用的数据访问,而ORDS_PUBLIC_USER则负责REST数据服务的连接管理。
2. 问题诊断与确认
2.1 确认问题用户
在开始修复前,我们需要先确认确实是ORDS_PUBLIC_USER导致的连接问题。打开终端执行以下命令:
bash复制ords config list
这个命令会列出ORDS的所有配置信息。重点关注db.username对应的值,正常情况下应该显示ORDS_PUBLIC_USER。如果这个用户过期,就会触发我们看到的连接错误。
2.2 检查用户状态
为了进一步确认,我们可以直接查询数据库中的用户状态。以SYSDBA身份登录SQL*Plus,执行:
sql复制SELECT username, account_status, expiry_date
FROM dba_users
WHERE username IN ('ORDS_PUBLIC_USER', 'APEX_PUBLIC_USER');
如果看到ORDS_PUBLIC_USER的account_status显示为"EXPIRED",那就确认了问题的根源。值得注意的是,即使你之前已经处理过APEX_PUBLIC_USER的过期问题,ORDS_PUBLIC_USER可能仍然处于过期状态,这就是为什么问题会反复出现。
3. 完整解决方案
3.1 创建永不过期策略
首先我们需要确保ORDS_PUBLIC_USER不会被密码策略所困扰。Oracle数据库默认使用DEFAULT配置文件,其中的密码有效期通常设置为180天。我们可以创建一个专门的永不过期配置文件:
sql复制CREATE PROFILE PASSWORD_UNLIMITED LIMIT
PASSWORD_LIFE_TIME UNLIMITED
PASSWORD_GRACE_TIME UNLIMITED;
注意:如果你已经创建过类似的配置文件,可以跳过这一步。建议在生产环境中为所有服务账户创建专门的密码策略。
3.2 应用永不过期策略
将ORDS_PUBLIC_USER分配到新创建的配置文件:
sql复制ALTER USER ORDS_PUBLIC_USER PROFILE PASSWORD_UNLIMITED;
这个操作相当于给用户上了"免死金牌",从此不再受密码过期策略的限制。但这里有个关键点:这个操作只对未来的密码过期有效,如果用户已经处于过期状态,仅修改配置文件是不够的。
3.3 重置用户密码
对于已经过期的用户,必须通过密码重置来恢复其状态:
sql复制ALTER USER ORDS_PUBLIC_USER IDENTIFIED BY "Ords_2025@Pub";
密码设置建议:
- 长度至少12个字符
- 包含大小写字母
- 包含数字和特殊字符
- 避免使用常见单词或简单模式
安全提示:在生产环境中,建议使用密码管理器生成并保存这类服务账户密码。
3.4 同步ORDS配置
重置数据库密码后,必须同步更新ORDS的配置。这里有个版本差异需要注意:
对于ORDS 21及更高版本:
bash复制ords config secret db.password
执行后会提示交互式输入密码,这种方式更安全,不会在命令历史中留下痕迹。
对于较旧版本的ORDS:
bash复制ords config set db.password "Ords_2025@Pub"
3.5 重启ORDS服务
完成所有配置后,需要重启ORDS服务使更改生效:
bash复制# 查找并终止现有ORDS进程
ps -ef | grep ords
kill -9 <进程ID>
# 启动新的ORDS服务
nohup ords serve > ords.log 2>&1 &
验证服务是否正常:
bash复制tail -f ords.log
观察日志中是否有错误信息,正常情况下应该看到服务成功启动的消息。
4. 深度解析与原理
4.1 ORDS连接机制剖析
ORDS(Oracle REST Data Services)作为APEX的中间层,其连接数据库的流程是这样的:
- 启动时读取配置文件中的db.username和db.password
- 使用这些凭证初始化连接池
- 将连接池提供给APEX应用或REST服务使用
当密码过期时,连接池初始化阶段就会失败,导致整个服务不可用。这就是为什么我们看到的错误信息是"Failed to get a connection"。
4.2 密码策略的影响
Oracle的密码策略通过profile实现,主要控制以下方面:
- PASSWORD_LIFE_TIME:密码有效期(天)
- PASSWORD_GRACE_TIME:过期后的宽限期
- PASSWORD_REUSE_TIME:密码重用时间限制
- PASSWORD_REUSE_MAX:密码重用次数限制
DEFAULT profile通常设置PASSWORD_LIFE_TIME=180,这就是为什么大约半年后服务账户会突然"罢工"。
4.3 账号状态管理
Oracle用户账号有以下几种状态:
- OPEN:正常状态
- EXPIRED:密码过期
- LOCKED:因登录失败过多被锁定
- EXPIRED & LOCKED:同时过期和被锁定
关键点在于:ALTER USER...ACCOUNT UNLOCK只能解除LOCKED状态,对EXPIRED状态无效。这就是为什么很多开发者尝试解锁后问题依旧。
5. 最佳实践与预防措施
5.1 初始化环境时的预防配置
在首次部署APEX+ORDS环境时,就应该执行以下操作:
sql复制-- 创建专用profile
CREATE PROFILE APEX_SERVICES LIMIT
PASSWORD_LIFE_TIME UNLIMITED
PASSWORD_GRACE_TIME UNLIMITED
FAILED_LOGIN_ATTEMPTS UNLIMITED;
-- 应用到服务账户
ALTER USER APEX_PUBLIC_USER PROFILE APEX_SERVICES;
ALTER USER ORDS_PUBLIC_USER PROFILE APEX_SERVICES;
5.2 定期检查清单
建议每月检查以下项目:
- 服务账户状态:
sql复制SELECT username, account_status, expiry_date FROM dba_users
WHERE username IN ('ORDS_PUBLIC_USER', 'APEX_PUBLIC_USER');
- ORDS配置一致性:
bash复制ords config list | grep -E 'db.username|db.password'
- 连接池健康状态:
检查ORDS日志中的连接池相关消息
5.3 自动化监控方案
对于生产环境,可以设置自动化监控:
sql复制-- 创建监控视图
CREATE VIEW EXPIRING_SERVICE_ACCOUNTS AS
SELECT username, account_status, expiry_date
FROM dba_users
WHERE username IN ('ORDS_PUBLIC_USER', 'APEX_PUBLIC_USER')
AND account_status != 'OPEN';
然后通过DBMS_SCHEDULER设置定期检查,发现问题时自动发送告警。
6. 高级技巧与疑难解答
6.1 多租户环境(CDB/PDB)处理
在CDB架构下,需要注意:
- 必须在正确的PDB中执行用户操作:
sql复制ALTER SESSION SET CONTAINER=<pdb_name>;
- ORDS配置也需要指定PDB:
bash复制ords config set db.serviceName <pdb_service_name>
6.2 ORDS连接池调优
如果遇到性能问题,可以调整连接池参数:
properties复制# 在ords配置文件中添加
jdbc.MaxLimit=20
jdbc.MinLimit=5
jdbc.InitialLimit=5
6.3 常见错误代码速查
| 错误代码 | 含义 | 解决方案 |
|---|---|---|
| ORA-28001 | 账号已过期 | 重置密码 |
| ORA-01017 | 无效凭证 | 检查ORDS配置密码 |
| UCP-29 | 连接池获取失败 | 检查数据库连接性 |
| HTTP 574 | ORDS数据库连接问题 | 检查用户状态和密码 |
6.4 密码同步验证技巧
验证密码是否同步的一个技巧是:
bash复制ords config list | grep db.password
如果显示[hidden]表示密码已正确设置,如果显示旧密码或为空,则说明同步失败。
7. 经验总结与个人建议
在实际运维中,我发现这类问题往往发生在系统运行一段时间后,特别是在没有完善监控的生产环境中。以下是我总结的几个关键点:
-
双重检查原则:处理ORDS连接问题时,一定要同时检查APEX_PUBLIC_USER和ORDS_PUBLIC_USER两个账户,它们就像一对"双胞胎",经常需要同样对待。
-
版本适配意识:不同ORDS版本在密码配置命令上有所差异,特别是在21版本这个分水岭。建议在操作前先确认版本:
ords --version -
预防优于修复:与其等到问题发生,不如在系统部署初期就建立完善的密码策略。可以考虑创建一个名为"APEX_SERVICES"的专用profile,统一管理所有相关服务账户。
-
文档记录习惯:每次密码变更都应记录在安全的文档中,包括:
- 修改时间
- 修改人
- 新密码复杂度
- 影响的系统组件
-
测试验证流程:任何配置变更后,都应建立完整的验证链:
- 数据库端用户状态检查
- ORDS配置验证
- 服务重启测试
- 应用功能抽查
最后提醒一点:虽然永不过期策略解决了运维中的一大痛点,但也要注意平衡安全性与便利性。建议定期(如每年)主动更换这些服务账户的密码,而不是完全依赖永不过期策略。