liuziyi

liuziyi

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 远程连接的备库归档删除脚本、监控脚本等必须同步更新密码,否则会认证失败导致作业中断。

注意事项(务必逐条确认)

  1. 改密后要同步所有引用方:定时任务、crontab 脚本、Data Guard 归档删除脚本、监听器、监控/备份工具等,任何仍用旧密码的组件都会报 ORA-28001/ORA-01017。
  2. 12c 起 SYS 也受 profile 密码策略约束(12c 之前 SYS 豁免 PASSWORD_LIFE_TIME/PASSWORD_GRACE_TIME),升级后需重新评估 SYS 是否会过期。
  3. 改密与改 profile 建议在维护窗口执行,SYS 属于关键账户,避免影响在线业务与依赖 SYS 的作业。
  4. 不要用 SYS/SYSTEM 作为应用连接账号,应为应用单独建用户并使用独立 profile。
  5. 特殊字符处理:密码含 $、反引号、\、" 时,在 Shell 脚本中容易被二次解析,建议交互式在 SQL*Plus 中执行,或在脚本中做转义。
  6. 修改 profile 后立即验证:确认目标用户 EXPIRY_DATE 已更新、ACCOUNT_STATUS=OPEN。
  7. 改密后务必用新密码实连一次(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 不更新问题

posted on 2026-10-14 11:42  刘子毅  阅读(11)  评论(0)    收藏  举报

导航