在Oracle数据库使用过程中,"密码过期导致用户登录失败"是高频故障------默认情况下,Oracle的DEFAULT概要文件会设置密码有效期(通常180天),到期后用户会被限制登录,甚至批量用户过期会导致业务中断。
一、前置准备:登录数据库(必看)
所有操作需以 SYSDBA超级权限 登录(普通用户无权限修改配置和用户状态),推荐两种登录方式:
方式1:本地操作系统认证(推荐,无需数据库密码)
bash
[oracle@localhost ~]$ sqlplus / as sysdba
# 成功登录提示
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
方式2:远程/密码认证(需知道SYS密码)
bash
[oracle@localhost ~]$ sqlplus sys/你的SYS密码@数据库IP:端口/服务名 as sysdba
注意:若登录报错
ORA-12154: TNS: 无法解析指定的连接标识符,需先检查tnsping服务名是否配置正确。
二、核心操作:从查询到解决( step by step )
1. 第一步:查询当前密码过期策略
先确认数据库默认的密码有效期配置,避免盲目修改:
sql
-- 设置查询结果显示宽度(避免字段截断)
SQL> set lines 999
SQL> set pages 100
-- 查询DEFAULT概要文件的密码有效期
SQL> SELECT profile, resource_name, limit
FROM dba_profiles
WHERE profile='DEFAULT'
AND resource_name IN ('PASSWORD_LIFE_TIME', 'PASSWORD_GRACE_TIME');
结果说明:
PASSWORD_LIFE_TIME:密码有效期(示例中为180天,UNLIMITED表示无限制)PASSWORD_GRACE_TIME:密码过期后的宽限期(宽限期内仍可登录,过期后锁定)- 若查询结果为空,说明
DEFAULT概要文件未设置该参数,默认可能继承系统默认值(180天)
2. 第二步:取消密码期限限制(全局生效)
修改DEFAULT概要文件,让所有使用该配置的用户密码永不过期(生产环境最常用方案):
sql
-- 取消密码有效期+宽限期限制
SQL> ALTER PROFILE DEFAULT LIMIT
PASSWORD_LIFE_TIME UNLIMITED -- 密码永不过期
PASSWORD_GRACE_TIME UNLIMITED; -- 取消宽限期(可选,避免弹窗提醒)
执行结果:
提示Profile altered.表示修改成功,即时生效(新创建的用户自动继承,已有用户无需额外配置)。
扩展:单独为某个用户设置策略(按需选择)
若不想全局修改DEFAULT策略,可创建自定义概要文件,仅应用于特定用户:
sql
-- 1. 创建自定义概要文件(无密码过期限制)
CREATE PROFILE no_expire_profile LIMIT PASSWORD_LIFE_TIME UNLIMITED;
-- 2. 给目标用户分配该概要文件
ALTER USER SCOTT PROFILE no_expire_profile;
3. 第三步:排查过期/异常用户
修改策略后,需处理已过期的用户(策略修改不自动恢复已过期状态):
(1)查询所有过期用户(精准定位问题用户)
sql
SQL> SELECT username, account_status, expiry_date
FROM dba_users
WHERE account_status LIKE 'EXPIRED%';
结果说明:
EXPIRED:密码已过期,无法登录EXPIRED(GRACE):密码过期但仍在宽限期内,登录时会提示修改密码- 示例中
SCOTT用户状态为EXPIRED,需优先处理
(2)查询所有用户状态(全面检查)
若需确认是否有"锁定+过期"的复合问题,执行:
sql
SQL> SELECT username, account_status, expiry_date, profile
FROM dba_users
ORDER BY account_status;
结果说明:
可直观看到每个用户的:
- 状态(是否过期/锁定)
- 密码过期时间
- 使用的概要文件(确认是否应用了
DEFAULT策略)
4. 第四步:解锁被锁定的用户
若用户状态为LOCKED(密码错误次数过多导致),需先解锁(仅解锁账号,不解决密码过期):
sql
-- 解锁单个用户(示例:SCOTT)
SQL> ALTER USER SCOTT ACCOUNT UNLOCK;
执行结果(如图5所示):
提示User altered.表示解锁成功。若需批量解锁,可拼接SQL:
sql
-- 批量生成解锁SQL(复制结果执行)
SELECT 'ALTER USER ' || username || ' ACCOUNT UNLOCK;'
FROM dba_users
WHERE account_status LIKE 'LOCKED%';
5. 第五步:保留原密码,重置过期用户(核心需求)
最实用的场景:用户不想修改密码,仅需恢复过期状态。Oracle密码哈希存储在sys.user$表,通过提取哈希值可实现"重置密码但保留原密码"。
(1)查询用户密码哈希(确认存储位置)
sql
-- 示例:查询SCOTT用户的密码哈希
SQL> SELECT name, spare4, password
FROM sys.user$
WHERE name = 'SCOTT';
结果说明:
- Oracle 12c+ 版本:密码哈希主要存储在
spare4字段(格式为S:XXX) - Oracle 11g及以下:密码哈希存储在
password字段 - 后续重置需拼接这两个字段(兼容新旧版本)
(2)批量生成「保留原密码」的重置SQL
无需手动拼接,直接执行以下SQL生成批量处理脚本:
sql
SQL> SELECT
'ALTER USER ' || su.name || ' IDENTIFIED BY VALUES '''
|| su.spare4 || NVL(';' || su.password, '') || ''';' AS 重置脚本
FROM sys.user$ su
JOIN dba_users du
ON su.name = du.username
AND du.account_status LIKE 'EXPIRED%';
结果说明:
查询结果会生成针对每个过期用户的重置SQL,例如:
ALTER USER SCOTT IDENTIFIED BY VALUES 'S:XXX;XXX';
(3)执行生成的重置SQL
复制上一步输出的"重置脚本",批量执行:
sql
-- 示例:执行SCOTT用户的重置SQL
SQL> ALTER USER SCOTT IDENTIFIED BY VALUES 'S:XXX;XXX';
执行结果:
提示User altered.表示成功,此时用户可使用原密码正常登录(密码过期状态已恢复)。
6. 第六步:手动修改密码(按需选择)
若需为用户设置新密码(而非保留原密码),直接执行:
sql
-- 示例:修改CESHI用户密码为123456(需符合密码策略)
SQL> ALTER USER CESHI IDENTIFIED BY 123456;
注意:
-
密码需符合当前概要文件的策略(如长度≥8位、包含字母+数字+特殊字符),否则会报错
ORA-28003: 口令验证失败。 -
若需简化密码策略(生产环境不推荐),可修改
DEFAULT概要文件:sqlALTER PROFILE DEFAULT LIMIT PASSWORD_MIN_LENGTH 6 -- 最小长度6位 PASSWORD_COMPLEXITY 'NONE'; -- 取消复杂度要求
三、生产环境关键注意事项(避坑必看)
-
操作前备份 :修改
DEFAULT概要文件或批量处理用户前,建议备份相关表:sqlCREATE TABLE dba_profiles_bak AS SELECT * FROM dba_profiles; CREATE TABLE dba_users_bak AS SELECT * FROM dba_users; -
权限控制 :所有操作必须以
SYSDBA身份执行,普通用户会提示ORA-01031: 权限不足。 -
版本兼容性 :
- 12c+ 版本必须使用
spare4字段拼接,仅用password会导致密码失效。 - 11g及以下版本无
spare4字段,直接使用password字段即可。
- 12c+ 版本必须使用
-
批量操作测试 :批量处理前,先选择1个非核心用户(如
SCOTT)测试流程,确认无问题后再推广。 -
定期检查 :建议每月执行一次过期用户查询,提前发现问题:
sql-- 定时任务查询脚本 SELECT username, account_status, expiry_date FROM dba_users WHERE account_status LIKE 'EXPIRED%' OR (expiry_date IS NOT NULL AND expiry_date < SYSDATE + 30); -- 提前30天预警
四、常见报错及解决方案
| 报错信息 | 原因 | 解决方案 |
|---|---|---|
| ORA-01031: 权限不足 | 未以SYSDBA身份登录 | 重新执行sqlplus / as sysdba登录 |
| ORA-28003: 口令验证失败 | 密码不符合当前概要文件策略 | 1. 按策略修改密码;2. 放宽密码策略(见步骤6) |
| ORA-01918: 用户不存在 | 用户名拼写错误(Oracle用户名区分大小写,默认大写) | 执行SELECT username FROM dba_users;确认用户名 |
| ORA-01940: 无法删除当前连接的用户 | 解锁/修改用户时,用户正在连接数据库 | 先kill会话:ALTER SYSTEM KILL SESSION 'sid,serial#';(sid/serial#从v$session查询) |