ODA/Oracle 19c CDB/PDB 环境下报错ORA-65162:common user密码过期问题排查与处理_2026-05-15

1、问题现象

业务系统连接 Oracle 数据库时失败,页面提示类似:

复制代码
ORA-65162: The password of the common user has expired

从报错可以看出,这不是网络端口问题,也不是监听服务异常,而是 Oracle common user 密码过期

本次涉及两个 CDB:

复制代码
MESCDB
UTF8CDB

相关用户为:

复制代码
C##MESCDBFLINK
C##UTF8CDBFLINK

这类 C## 开头的用户,一般属于 CDB common user


二、确认当前 CDB/PDB 环境

登录数据库服务器后,进入对应实例:

复制代码
su - oracle
export ORACLE_SID=mescdb1
sqlplus / as sysdba

查看 PDB:

复制代码
show pdbs;

示例结果:

复制代码
CON_ID  CON_NAME   OPEN MODE
------  --------   ----------
2       PDB$SEED   READ ONLY
3       MESDB      READ WRITE
5       RZMESDB    READ WRITE

确认当前容器:

复制代码
show con_name;

如果是 common user,建议在 CDB$ROOT 下处理。

复制代码
alter session set container=CDB$ROOT;

三、查询用户状态

先通过 cdb_users 查询用户状态:

复制代码
set lines 200 pages 200
col con_name for a15
col username for a35
col account_status for a30
col expiry_date for a20
col profile for a25
col common for a8

select u.con_id,
       c.name con_name,
       u.username,
       u.account_status,
       u.expiry_date,
       u.profile,
       u.common
from cdb_users u
join v$containers c on u.con_id = c.con_id
where u.username = upper('C##MESCDBFLINK')
order by u.con_id;

排查结果如下:

复制代码
CON_ID  CON_NAME   USERNAME        ACCOUNT_STATUS  EXPIRY_DATE           PROFILE   COMMON
------  --------   --------------  --------------  -------------------   -------   ------
1       CDB$ROOT   C##MESCDBFLINK  EXPIRED         2026-05-13 09:57:06   DEFAULT   YES
3       MESDB      C##MESCDBFLINK  OPEN                                  DEFAULT   YES
5       RZMESDB    C##MESCDBFLINK  OPEN                                  DEFAULT   YES

这里可以明确看出:

复制代码
CDB$ROOT 下账号状态为 EXPIRED

虽然 PDB 中显示为 OPEN,但是 common user 在 CDB$ROOT 中密码过期后,连接 PDB 仍然会失败。


四、创建专用 Profile,设置密码永不过期

生产环境不建议直接修改 DEFAULT profile,因为可能影响其他用户。

更稳妥的方式是:单独创建业务账号专用 profile

复制代码
alter session set container=CDB$ROOT;

先检查 profile 是否存在:

复制代码
select profile
from dba_profiles
where profile = 'C##APP_PROFILE'
group by profile;

如果不存在,创建:

复制代码
create profile C##APP_PROFILE limit
  PASSWORD_LIFE_TIME UNLIMITED
  PASSWORD_GRACE_TIME UNLIMITED;

说明:

复制代码
PASSWORD_LIFE_TIME  UNLIMITED  表示密码永不过期
PASSWORD_GRACE_TIME UNLIMITED  表示不进入密码过期宽限期

五、将 common user 切换到新 Profile

C##MESCDBFLINK 为例:

复制代码
alter user C##MESCDBFLINK profile C##APP_PROFILE container=all;

然后使用原密码重置并解锁:

复制代码
alter user C##MESCDBFLINK identified by "原密码" account unlock container=all;

如果密码中包含特殊字符,比如 #,必须使用双引号包起来:

复制代码
alter user C##MESCDBFLINK identified by "******" account unlock container=all;

注意:

这里建议使用原密码重置,这样业务系统连接配置不用同步修改。


六、验证处理结果

再次查询用户状态:

复制代码
select u.con_id,
       c.name con_name,
       u.username,
       u.account_status,
       u.expiry_date,
       u.profile,
       u.common
from cdb_users u
join v$containers c on u.con_id = c.con_id
where u.username = 'C##MESCDBFLINK'
order by u.con_id;

正常结果应类似:

复制代码
CON_ID  CON_NAME   USERNAME        ACCOUNT_STATUS  EXPIRY_DATE  PROFILE          COMMON
------  --------   --------------  --------------  -----------  ---------------  ------
1       CDB$ROOT   C##MESCDBFLINK  OPEN                         C##APP_PROFILE   YES
3       MESDB      C##MESCDBFLINK  OPEN                         C##APP_PROFILE   YES
5       RZMESDB    C##MESCDBFLINK  OPEN                         C##APP_PROFILE   YES

重点看三项:

复制代码
ACCOUNT_STATUS = OPEN
EXPIRY_DATE    为空
PROFILE        = C##APP_PROFILE

再确认 profile 策略:

复制代码
select profile, resource_name, limit
from dba_profiles
where profile = 'C##APP_PROFILE'
and resource_name in (
  'PASSWORD_LIFE_TIME',
  'PASSWORD_GRACE_TIME',
  'FAILED_LOGIN_ATTEMPTS',
  'PASSWORD_LOCK_TIME'
)
order by resource_name;

示例结果:

复制代码
PROFILE          RESOURCE_NAME          LIMIT
---------------  ---------------------  ---------
C##APP_PROFILE   FAILED_LOGIN_ATTEMPTS  DEFAULT
C##APP_PROFILE   PASSWORD_GRACE_TIME    UNLIMITED
C##APP_PROFILE   PASSWORD_LIFE_TIME     UNLIMITED
C##APP_PROFILE   PASSWORD_LOCK_TIME     DEFAULT

这里说明:

复制代码
密码已经永不过期;
但如果密码连续输错,仍然可能按 DEFAULT 策略锁定。

七、CDB common user 和 PDB local user 的区别

本次处理的两个用户:

复制代码
C##MESCDBFLINK
C##UTF8CDBFLINK

都属于 common user,特点是:

复制代码
用户名以 C## 开头
COMMON = YES

这种用户应在:

复制代码
CDB$ROOT

中处理,并使用:

复制代码
container=all

例如:

复制代码
alter user C##MESCDBFLINK profile C##APP_PROFILE container=all;

如果是普通业务用户,例如:

复制代码
STEELMES
MES_ADMIN
HYTOMES
QMS
LZMES
RZMES

如果查询结果为:

复制代码
COMMON = NO

则说明它们是 PDB local user,只属于某个具体 PDB。

这类用户不需要在 CDB$ROOT 中修改,直接切换到所属 PDB 处理即可:

复制代码
alter session set container=MESDB;

create profile APP_PROFILE limit
  PASSWORD_LIFE_TIME UNLIMITED
  PASSWORD_GRACE_TIME UNLIMITED;

alter user STEELMES profile APP_PROFILE;

如果账号已过期或锁定,再用原密码重置解锁:

复制代码
alter user STEELMES identified by "原密码" account unlock;

八、总结

本次问题的核心原因是:

复制代码
Oracle CDB common user 在 CDB$ROOT 中密码过期,导致业务系统连接 PDB 失败。

关键排查 SQL:

复制代码
select u.con_id,
       c.name con_name,
       u.username,
       u.account_status,
       u.expiry_date,
       u.profile,
       u.common
from cdb_users u
join v$containers c on u.con_id = c.con_id
where u.username = upper('用户名')
order by u.con_id;

关键处理思路:

复制代码
common user:在 CDB$ROOT 中处理,使用 container=all
local user :进入对应 PDB 中处理,不使用 container=all

最终处理方式:

复制代码
创建专用 profile
设置 PASSWORD_LIFE_TIME 为 UNLIMITED
设置 PASSWORD_GRACE_TIME 为 UNLIMITED
将业务连接用户切换到该 profile
使用原密码重置并解锁账号

一句话总结:
C## 用户看 CDB$ROOT,普通业务用户进 PDB;谁家的账号谁家管,别在生产环境里乱改 DEFAULT。

相关推荐
deadbird11 分钟前
Xbox 无线适配器 Linux 设置指南
linux
睡不醒男孩03082312 分钟前
TiDB数据库调研
数据库·tidb
Menahem22 分钟前
解决 SSH 报错:WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
运维·ssh·github
珠***格24 分钟前
实操落地|防逆流装置的安装规范、调试标准与故障处置
网络·数据库·人工智能·分布式·能源·边缘计算
wait a minutes35 分钟前
Ubuntu 升级后 NVIDIA 驱动修复指南
linux·运维·ubuntu
|_⊙37 分钟前
Linux 信号
运维·服务器·前端
xdpcxq10291 小时前
基于Blazor实现的跟踪光伏智能运维平台
运维
Omics Pro1 小时前
3种蛋白结构输入方式!已申报欧洲发明专利
数据库·人工智能·python·机器学习·plotly
itfallrain2 小时前
Spring 构造器循环依赖排查:@RequiredArgsConstructor + @Lazy 到底有没有生效
数据库·python·spring
bush42 小时前
嵌入式linux学习记录十二,mmap
java·linux·学习