ORA-28000账户锁定需先查状态再针对性处理:若account_status为LOCKED(TIMED),主因是FAILED_LOGIN_ATTEMPTS超限;若为EXPIRED,则属密码过期,二者策略独立,修改PASSWORD_LIFE_TIME不解除登录锁定。

因为“密码永不过期”只解决 PASSWORD_LIFE_TIME,而账户被锁通常由 FAILED_LOGIN_ATTEMPTS 触发——两者是独立控制的安全策略,改一个不等于另一个自动失效。
查清账户到底是被哪种策略锁的
ORA-28000 报错本身不说明原因,必须主动查状态和配置:
-
SELECT username, account_status FROM dba_users WHERE username = 'YOUR_USER';—— 如果返回LOCKED(TIMED),基本就是登录失败次数超限;如果是EXPIRED(GRACE)或EXPIRED,才是密码过期问题 -
SELECT resource_name, limit FROM dba_profiles WHERE profile = 'DEFAULT' AND resource_name IN ('PASSWORD_LIFE_TIME', 'FAILED_LOGIN_ATTEMPTS');—— 看两个关键值是否真被改成了UNLIMITED,别只记得改了前者 - 注意:用户可能没用
DEFAULTprofile,要先查SELECT username, profile FROM dba_users WHERE username = 'YOUR_USER';,再针对性查对应 profile
FAILED_LOGIN_ATTEMPTS 被忽略的典型场景
即使你设了 PASSWORD_LIFE_TIME UNLIMITED,只要还有程序在用旧密码连,就会持续触发锁定:
- 应用连接池(如 Tomcat 的
context.xml、Spring Boot 的application.yml)里还配着旧密码,启动后反复重试连接 - 定时任务脚本(Shell/Python)硬编码了旧密码,每分钟执行一次,10次就锁
- 监控工具(Zabbix、Prometheus exporter)或 DBA 自动巡检脚本,密码没同步更新
- Oracle 客户端(如 SQL*Plus、SQL Developer)保存了旧密码的连接配置,有人手动点开就触发一次失败
真正生效的修改操作顺序不能乱
改完 profile 后,已有问题账户不会自动恢复,必须补两步:
- 对已锁账户,必须显式执行
ALTER USER username ACCOUNT UNLOCK;—— 仅改 profile 不会自动解锁 - 对已过期账户,必须执行
ALTER USER username IDENTIFIED BY new_password;—— 即使设了永不过期,过期状态也得靠改密码来清除 - 如果用户在 PDB 中,
ALTER PROFILE ...和ALTER USER ...都得在对应 PDB 容器内执行(ALTER SESSION SET CONTAINER = pdb_name;),CDB 级设置不透传
容易被绕过的“UNLIMITED”陷阱
UNLIMITED 在 Oracle 里不是万能开关,有些情况它根本不生效:
- 如果 profile 被显式赋给用户,但该 profile 本身被
ALTER PROFILE ... LIMIT FAILED_LOGIN_ATTEMPTS 3;改成小数值,那UNLIMITED就没意义 - Oracle 12c 及以后,
COMMON USER(CDB 用户)的 profile 限制优先级高于 PDB 内同名 profile,容易误判生效位置 -
FAILED_LOGIN_ATTEMPTS设为UNLIMITED后,错误登录不再锁账户,但也不会记录失败尝试——这意味着你失去了发现异常扫描行为的线索
最常被忽略的一点:锁住的不是“密码”,而是“账户”。密码策略管生命周期,登录策略管访问入口,两者像两道门禁,钥匙(密码)没过期,不代表有人拿错钥匙反复捅锁孔(失败登录)不会触发警报。











