oracle密码过期,并修改sysdba的密码
问题:
Oracle 数据库管理员账号(SYS / SYSTEM)密码已过期或需要主动变更,登录时报 ORA-28001: the password has expired(或先出现 ORA-28002 宽限期警告),需要一套可执行的标准改密流程与一键脚本。
方案:
场景一:密码已过期 —— 用本地 OS 认证登录后修改(最常用、最稳妥)
OS 认证(/ as sysdba)不受密码过期影响,是过期后的首选入口。
1. 以 oracle 操作系统用户设置环境变量并登录
export ORACLE_SID=<你的实例名>
export ORACLE_HOME=<你的ORACLE_HOME路径>
sqlplus / as sysdba
2. 确认账户状态与过期时间
SET PAGESIZE 200
SET LINESIZE 200
COLUMN username FORMAT A20
COLUMN account_status FORMAT A20
SELECT username, account_status, expiry_date
FROM dba_users
WHERE username IN ('SYS','SYSTEM');
ACCOUNT_STATUS = EXPIRED(GRACE)→ 已进入宽限期(对应ORA-28002),仍可登录但必须改密;ACCOUNT_STATUS = EXPIRED→ 已彻底过期(对应ORA-28001),普通登录被拒。
3. 修改密码(含解锁)
ALTER USER sys IDENTIFIED BY "新密码";
ALTER USER system IDENTIFIED BY "新密码";
ALTER USER system ACCOUNT UNLOCK; -- 若账户被锁定才需要
密码含特殊字符、区分大小写时必须用双引号包裹;同时要满足目标 profile 的密码复杂度要求(若启用了
PASSWORD_VERIFY_FUNCTION)。
4. 验证
SELECT username, account_status, expiry_date
FROM dba_users
WHERE username IN ('SYS','SYSTEM');
ACCOUNT_STATUS 应为 OPEN,EXPIRY_DATE 更新为新的到期时间(设为 UNLIMITED 时为空)。
场景二:无法本地登录 / CDB 与 PDB 环境
- 多租户(12c 及以上):SYS 是公共用户,但业务管理员用户在各 PDB 中。需先切容器再改:
或在根容器直接以ALTER SESSION SET CONTAINER = <PDB名>; ALTER USER <管理员用户> IDENTIFIED BY "新密码";ALTER USER <用户> IDENTIFIED BY "新密码" CONTAINER=CURRENT;限定范围。 - 忘记密码 / 账户彻底不可用:用
orapwd重建密码文件(见场景四)。
场景三:从策略上让管理员密码不再过期(治本)
1. 查看当前密码策略
SELECT profile, resource_name, "LIMIT"
FROM dba_profiles
WHERE resource_name LIKE 'PASSWORD%'
ORDER BY profile, resource_name;
注意:
DBA_PROFILES的列名LIMIT是保留字,查询时必须写成"LIMIT"。
2. 将有效期设为永不过期(可按需选择全局或单独 profile)
-- 方式一:改默认 profile(影响所有使用 DEFAULT 的用户)
ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;
-- 方式二(推荐):为管理员/应用新建独立 profile,只对该 profile 生效
CREATE PROFILE admin_prof LIMIT PASSWORD_LIFE_TIME UNLIMITED;
ALTER USER system PROFILE admin_prof;
⚠️ 关键点:修改 PASSWORD_LIFE_TIME 对状态仍为 OPEN 的用户会立即重算 EXPIRY_DATE;但对已经进入 EXPIRED / EXPIRED(GRACE) 的用户不会自动恢复,仍必须用 ALTER USER ... IDENTIFIED BY ... 重置一次密码。
场景四:修改 SYS 密码后 PTIME 不更新 / ASM 与密码文件
- 改 SYS 密码后
sys.user$的PTIME不更新:命中 Bug 28538439,或隐藏参数_enable_ptime_update_for_sys为FALSE。处理:ALTER SYSTEM SET "_enable_ptime_update_for_sys" = TRUE SCOPE = SPFILE; -- 重启实例后再次改密,PTIME 即正常更新(或打对应补丁) - ASM 实例改 SYS 密码:ASM 不支持用
ALTER USER直接改 SYS 密码(会报ORA-00600 [15051]/ORA-01109)。正确做法是保证REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE,关闭实例后用orapwd重建密码文件:orapwd file=$ORACLE_HOME/dbs/orapw<ASM_SID> password=<sys密码> force=y - RAC / Data Guard:SYS 改密后,各节点密码文件需保持同步;使用 SYS 远程连接的备库归档删除脚本、监控脚本等必须同步更新密码,否则会认证失败导致作业中断。
注意事项(务必逐条确认)
- 改密后要同步所有引用方:定时任务、crontab 脚本、Data Guard 归档删除脚本、监听器、监控/备份工具等,任何仍用旧密码的组件都会报
ORA-28001/ORA-01017。 - 12c 起 SYS 也受 profile 密码策略约束(12c 之前 SYS 豁免
PASSWORD_LIFE_TIME/PASSWORD_GRACE_TIME),升级后需重新评估 SYS 是否会过期。 - 改密与改 profile 建议在维护窗口执行,SYS 属于关键账户,避免影响在线业务与依赖 SYS 的作业。
- 不要用 SYS/SYSTEM 作为应用连接账号,应为应用单独建用户并使用独立 profile。
- 特殊字符处理:密码含
$、反引号、\、"时,在 Shell 脚本中容易被二次解析,建议交互式在 SQL*Plus 中执行,或在脚本中做转义。 - 修改 profile 后立即验证:确认目标用户
EXPIRY_DATE已更新、ACCOUNT_STATUS=OPEN。 - 改密后务必用新密码实连一次(
sqlplus 用户/新密码@服务名 as sysdba)确认生效。
一键脚本(以 oracle 用户执行,打印输出、不落地文件)
使用前请先
export ORACLE_SID=<实例名>、export ORACLE_HOME=<路径>;脚本不硬编码密码,交互式读取。
#!/bin/bash
# Oracle 管理员密码过期处理一键脚本
# 用法:以 oracle 操作系统用户执行,先设置 ORACLE_SID / ORACLE_HOME
# ./oracle_pwd_fix.sh [用户名,默认 SYS]
set -u
TARGET_USER="${1:-SYS}"
if [ -z "${ORACLE_SID:-}" ]; then
echo "错误:未设置 ORACLE_SID,请先 export ORACLE_SID=<实例名>"; exit 1
fi
if [ -z "${ORACLE_HOME:-}" ]; then
echo "错误:未设置 ORACLE_HOME,请先 export ORACLE_HOME=<路径>"; exit 1
fi
echo "==================================================="
echo " 目标用户 : ${TARGET_USER}"
echo " 实例 SID : ${ORACLE_SID}"
echo "==================================================="
echo "== [1/4] 当前账户状态 =="
sqlplus -S / as sysdba <<EOF
SET PAGESIZE 200
SET LINESIZE 200
COLUMN username FORMAT A20
COLUMN account_status FORMAT A20
SELECT username, account_status, expiry_date
FROM dba_users
WHERE username = UPPER('${TARGET_USER}');
EOF
echo
read -r -s -p "请输入 ${TARGET_USER} 的新密码: " NEWPW; echo
read -r -s -p "请再次输入新密码: " NEWPW2; echo
if [ -z "$NEWPW" ]; then echo "密码不能为空,退出"; exit 1; fi
if [ "$NEWPW" != "$NEWPW2" ]; then echo "两次输入不一致,退出"; exit 1; fi
echo "== [2/4] 修改密码并解锁账户 =="
sqlplus -S / as sysdba <<EOF
ALTER USER ${TARGET_USER} IDENTIFIED BY "${NEWPW}" ACCOUNT UNLOCK;
EOF
echo "== [3/4] 修改后状态 =="
sqlplus -S / as sysdba <<EOF
SET PAGESIZE 200
SET LINESIZE 200
COLUMN username FORMAT A20
COLUMN account_status FORMAT A20
SELECT username, account_status, expiry_date
FROM dba_users
WHERE username = UPPER('${TARGET_USER}');
EOF
echo "== [4/4] 完成 =="
echo "请使用新密码验证连接:"
echo " sqlplus ${TARGET_USER}/<新密码>@<服务名> as sysdba"
echo "并同步更新所有使用该账户的脚本、监控、Data Guard 作业。"
补充:若还需取消过期策略,在上述脚本基础上追加一步即可(二选一):
ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;但请记住:对已过期的用户,改 profile 不会自动解锁,必须重置密码。
参考资料:
- Oracle 官方文档:
ALTER USER、CREATE/ALTER PROFILE、DBA_USERS/DBA_PROFILES视图说明 - 支持文档 289898.1:SYS 用户不接收 ORA-28002/ORA-28001 的行为说明
- 支持文档 162818.1:修改
PASSWORD_LIFE_TIME后连接立即报 ORA-28002 - 支持文档 452076.1:ASM 实例修改 SYS 密码需用
orapwd重建密码文件 - Bug 28538439:SYS 用户
PTIME不更新问题
浙公网安备 33010602011771号