在Oracle数据库的日常运维中,相信不少人都遇到过这样的报错:ORA-28000: the account is locked。一个原本用得好好的账号,突然就登录不上了,排查半天才发现是因为密码连续输错,触发了账户锁定策略。这个行为的背后,其实是Oracle概要文件(Profile)中的FAILED_LOGIN_ATTEMPTS参数在控制。理解这个参数的工作机制,掌握查看和修改它的方法,是每一位DBA和开发人员都应该具备的基本技能。

一、FAILED_LOGIN_ATTEMPTS参数的工作原理
FAILED_LOGIN_ATTEMPTS是Oracle概要文件中的一个资源限制参数,它规定了账户在被锁定之前允许连续登录失败的次数。Oracle从10g版本开始,默认的概要文件DEFAULT中该参数的值为10,也就是说,如果一个账户连续10次输入错误的密码,这个账户就会被自动锁定,之后即使输入正确的密码也无法登录,必须等锁定期结束或者由管理员手动解锁。
这里有一个非常容易被忽视的细节:触发锁定的判断依据是连续失败次数。如果失败几次之后成功登录了一次,失败计数就会被重置。另外,锁定的对象是账户本身,而不是某个具体的客户端IP,也就是说无论从哪台机器发起连接,失败次数都会累加到同一个账户上。这一点在有应用服务器频繁重试连接的场景下尤其危险,比如某个应用的连接池配置了错误密码,应用一启动就会疯狂重试,短短几秒钟内就能把账户锁死,连带其他正常使用该账户的服务全部瘫痪。
与FAILED_LOGIN_ATTEMPTS配合工作的还有一个参数叫PASSWORD_LOCK_TIME,它指定账户被锁定后的自动解锁时长,默认值是1天。如果设置为UNLIMITED,则表示账户一旦锁定就不会自动解锁,必须管理员执行ALTER USER ... UNLOCK语句才能恢复。
二、如何查看当前的登录失败限制配置
要查看某个账户当前生效的概要文件以及具体的限制值,可以通过数据字典视图DBA_PROFILES来查询。下面的SQL可以列出DEFAULT概要文件中与密码相关的全部参数:
SELECT profile, resource_name, resource_type, limit FROM dba_profiles WHERE profile = 'DEFAULT' ORDER BY resource_name;
查询结果中重点关注这几行:FAILED_LOGIN_ATTEMPTS显示允许的失败次数,PASSWORD_LOCK_TIME显示锁定时长,PASSWORD_LIFE_TIME显示密码有效期。如果想确认某个用户绑定的是哪个概要文件,可以查询DBA_USERS视图:
SELECT username, profile, account_status FROM dba_users WHERE username = 'SCOTT';
其中ACCOUNT_STATUS字段能直观反映账户当前状态。常见的状态值包括OPEN(正常)、LOCKED(被锁定,等待自动解锁或手动解锁)、LOCKED(TIMED)(因登录失败被锁定,PASSWORD_LOCK_TIME到期后会自动恢复)以及EXPIRED(GRACE)(密码过期宽限期)。看到LOCKED(TIMED)基本就可以断定是触发了登录失败策略。如果想进一步确认是谁在反复尝试登录失败,可以开启审计功能,在11g及之后的版本中,登录失败审计默认就是开启的,可以通过查询审计记录或者告警日志来定位失败的来源IP和程序。
三、修改登录失败次数限制与解锁账户
调整FAILED_LOGIN_ATTEMPTS需要修改概要文件,使用ALTER PROFILE语句。例如把DEFAULT概要文件的失败次数放宽到30次:
-- 修改概要文件,放宽失败次数限制 ALTER PROFILE DEFAULT LIMIT FAILED_LOGIN_ATTEMPTS 30; -- 也可以设置为不限制,即永不因登录失败锁定账户(不建议在生产环境使用) ALTER PROFILE DEFAULT LIMIT FAILED_LOGIN_ATTEMPTS UNLIMITED; -- 同时调整锁定时长为30分钟(单位为天,0.0208约等于30分钟) ALTER PROFILE DEFAULT LIMIT PASSWORD_LOCK_TIME 0.0208;
需要注意的是,ALTER PROFILE修改的是整个概要文件,所有绑定到该概要文件的账户都会受到影响。如果只想对个别账户放宽限制,更优雅的做法是单独创建一个概要文件并绑定给特定用户:
-- 创建专用概要文件 CREATE PROFILE APP_PROFILE LIMIT FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 1; -- 将概要文件绑定到指定用户 ALTER USER APP_USER PROFILE APP_PROFILE;
对于已经被锁定的账户,管理员使用SYSDBA身份登录后执行解锁语句即可立即恢复,无需等待自动解锁:
-- 解锁账户 ALTER USER SCOTT ACCOUNT UNLOCK; -- 如果密码也忘了,可以顺便重置密码(11g之后建议同时替换原有密码哈希避免失效) ALTER USER SCOTT IDENTIFIED BY new_password;
这里还有一个实战中常见的坑:在11g之前,用ALTER USER重置密码时如果不指定原密码,会导致旧密码失效;而Oracle 11g之后可以在重置语句中同时保留原密码哈希,避免影响其他使用该密码的客户端。另外,如果密码本身已经过期(PASSWORD_LIFE_TIME默认180天),仅解锁账户是不够的,还需要处理密码过期问题,否则应用会一直报ORA-28001错误。
四、生产环境的使用建议与安全权衡
把FAILED_LOGIN_ATTEMPTS改成UNLIMITED虽然能一劳永逸地避免账户被锁,但这种做法等同于关闭了一道重要的防线。登录失败锁定机制本质上是一种抵御暴力破解的手段,攻击者如果可以无限次尝试密码,数据库的安全性会大幅下降。因此更推荐的做法是:保留合理的失败次数限制,同时确保应用侧的连接配置正确,并在监控告警中加入账户锁定事件的通知,这样既能防暴力破解,又能在异常发生时第一时间响应。
对于应用系统使用的数据库账号,建议采用如下策略:为应用账号创建独立的概要文件,失败次数可以适当放宽(比如20到50次),并设置较短的锁定时长(比如10到30分钟),这样即使应用配置出错导致连接风暴,也能在短时间内自动恢复;而人工使用的运维账号则保持默认的10次限制,锁定时长设为1天,提高安全性。此外,还应该结合审计视图定期检查登录失败记录,及时识别出异常IP的扫描行为。可以通过下面的SQL查看审计记录中的失败登录(需要具有相应权限):
SELECT os_username, username, userhost, terminal, timestamp, returncode FROM dba_audit_trail WHERE returncode IN (1017, 28000) ORDER BY timestamp DESC;
其中returncode为1017表示用户名或密码错误,28000表示账户已被锁定。通过定期分析这些记录,可以提前发现密码猜解攻击的苗头,把安全事件扼杀在萌芽阶段。总的来说,FAILED_LOGIN_ATTEMPTS虽小,但它连接着可用性和安全性两端,合理的配置加上完善的监控,才能让Oracle数据库在安全与稳定之间取得平衡。
Oracle登录失败次数FAILED_LOGIN_ATTEMPTS用户账户锁定修改时间:2026-09-09 15:53:06