C##公共用户不能在PDB中直接登录是Oracle多租户架构的设计限制,因其密码哈希仅存储于CDB$ROOT的user$表中(spare4非空),PDB中仅为元数据同步视图且无有效认证凭据,故认证必失败;业务连接应使用PDB内创建的本地用户。

公共用户(C##开头)不能在PDB中直接登录,这是设计限制,不是配置错误
为什么 C## 用户在 PDB 中查得到却登录失败
公共用户存在于 CDB$ROOT 和所有 OPEN 状态的 PDB 中,但 Oracle 明确禁止在非 CDB$ROOT 容器中对公共用户进行密码认证。即使 dba_users 在 PDB 里能查到 C##MESCDBFLINK 且状态为 OPEN,实际连接时监听器或会话层会拒绝认证请求,典型报错是 ORA-01017 或静默失败。
根本原因是:公共用户的密码凭证只在 CDB$ROOT 的 user$ 表中维护;PDB 中的同名记录只是元数据同步视图,不承载可验证的密码哈希值。
- 执行
SELECT username, password, spare4 FROM user$ WHERE name = 'C##MESCDBFLINK'—— 只有在 CDB$ROOT 下才返回非空spare4(即密码哈希) - 在 PDB 中查该表,
spare4为空或为占位值,认证无依据 -
ALTER USER C##MESCDBFLINK IDENTIFIED BY ...在 PDB 中执行会报ORA-65096或静默忽略,不生效
本地连接时误用 SID 导致“看似连到 PDB”实则连回 CDB
很多用户以为 sqlplus / as sysdba 或 sqlplus sys/password@localhost:1521/ORCLPDB 就进了 PDB,其实不然。Oracle 19c 默认监听注册的是 CDB 的服务名(如 MESCDB),而 PDB 的服务名(如 MESDB)需满足两个条件才会被监听识别:
- PDB 当前处于
OPEN状态(SHOW PDBS确认) - 未手动关闭其服务:
SELECT name, network_name FROM v$services WHERE con_id =;若network_name为空,说明服务未注册
常见陷阱:tnsnames.ora 中写 SERVICE_NAME = MESDB,但监听器日志显示 TNS-12514: Service not registered —— 此时客户端实际连上的仍是 CDB 的默认服务,认证发生在 CDB$ROOT,但用户可能没权限或密码已过期(如 ORA-65162)。
如何验证当前连接的真实容器和用户归属
不要依赖连接字符串判断,进库后立刻执行:
SELECT SYS_CONTEXT('USERENV', 'CON_NAME') AS con_name,
SYS_CONTEXT('USERENV', 'SESSION_USER') AS session_user,
SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA') AS current_schema
FROM DUAL;
再查用户状态:
SELECT username, account_status, expiry_date, common, con_id FROM cdb_users WHERE username = 'C##MESCDBFLINK';
- 如果
con_name是CDB$ROOT但account_status是EXPIRED,就对应ORA-65162场景,必须在 CDB$ROOT 下改密:ALTER USER C##MESCDBFLINK IDENTIFIED BY newpass; - 如果
con_name是MESDB但common = 'YES'且account_status是OPEN,仍登录失败 —— 这就是前述的设计限制,应放弃在 PDB 中登录公共用户
真正该用什么用户登录 PDB
业务系统、应用连接、日常开发,一律使用本地用户(non-common user),即在目标 PDB 内创建、不带 C## 前缀的用户:
- 先切容器:
ALTER SESSION SET CONTAINER=MESDB; - 确认 PDB OPEN:
ALTER PLUGGABLE DATABASE MESDB OPEN; - 建用户:
CREATE USER mesapp IDENTIFIED BY pwd123 DEFAULT TABLESPACE users; - 授权:
GRANT CONNECT, RESOURCE TO mesapp; - 连接:
sqlplus mesapp/pwd123@localhost:1521/MESDB(注意是 SERVICE_NAME,不是 SID)
公共用户只用于跨容器管理操作(如备份、统一审计、PDB 生命周期控制),不该出现在应用连接池或业务 SQL 中。混淆这点,是绝大多数 ORA-01017 和 ORA-65096 的根源。











