跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

如何创建CDB公共用户_C##前缀强制规则与CONTAINER=ALL

C##前缀是Oracle 12c+中创建公共用户的强制校验逻辑,非可选建议;系统硬编码校验用户名是否匹配^C##.*(大小写敏感),不依赖参数或字典,且必须在CDB$ROOT中执行并显式指定CONTAINER=ALL。 为什么
C##
前缀在 CDB 公共用户中不是“可选建议”,而是强制校验逻辑 oracle 12c+ 中创建公共用户(即跨 pdb 生效的用户)时,
create user
语句若未以
c##
开头,会直接报错
ora-65096: invalid common user or role name
。这不是配置开关或参数控制的结果,而是 oracle 内部对公共用户名称做的硬编码校验——它只检查前缀是否匹配正则
^c##.*
(大小写敏感),不查字典、不读参数、不走策略。 常见错误现象: 执行
CREATE USER admin IDENTIFIED BY pwd CONTAINER=ALL;
→ 立刻报
ORA-65096
用双引号包住:
CREATE USER "c##admin" ...
→ 仍报错,因为校验发生在解析阶段,忽略引号 在非 CDB 环境下执行相同语句 → 不报错,但该用户无法在 CDB 中被识别为公共用户
CONTAINER=ALL
必须显式指定,且仅在特定会话上下文中有效 即使用户名带
C##
,漏写
CONTAINER=ALL
或写成
CONTAINER=CURRENT
,创建的仍是本地用户(只存在于当前 PDB),不会同步到其他 PDB 或 ROOT。这个子句不是“默认开启”的选项。 使用场景与限制: 必须在
CDB$ROOT
中执行,不能在任意 PDB 中运行 执行前需确认当前会话容器:
SELECT SYS_CONTEXT('USERENV', 'CON_NAME') FROM DUAL;
返回必须是
CDB$ROOT
CONTAINER=ALL
不能和
DEFAULT TABLESPACE
指向某个 PDB 的表空间混用,否则报
ORA-65048: error encountered when processing the current DDL statement in pluggable database
正确示例:
CREATE USER c##monitor IDENTIFIED BY monitor123 DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp CONTAINER=ALL;
公共用户的权限授予必须同样加
CONTAINER=ALL
,否则权限不跨容器 给公共用户赋权时,如果用
GRANT SELECT_CATALOG_ROLE TO c##monitor;
而不加
CONTAINER=ALL
,该权限只生效于当前容器(通常是 ROOT),PDB 中该用户依然无权查
V$
视图等。 关键点:
GRANT
和
REVOKE
对公共用户操作时,
CONTAINER=ALL
是独立开关,不继承自
CREATE USER
语句 系统权限(如
SELECT_CATALOG_ROLE
)、对象权限(如
SELECT
on
SYS.V_$SESSION
)都需显式指定 角色本身可以是公共角色(用
CREATE ROLE r_name CONTAINER=ALL
创建),但角色授权仍要加
CONTAINER=ALL
典型遗漏:
GRANT CREATE SESSION TO c##monitor CONTAINER=ALL;
—— 没这句,用户连登录都不行 容易被忽略的兼容性细节:字符集、密码复杂度、PDB 级别限制 名字合规只是第一步;真正上线时卡住的往往是下游约束: 所有 PDB 的字符集必须与 CDB ROOT 一致,否则公共用户在某些 PDB 中可能无法解析用户名(尤其含非 ASCII 字符时) 密码策略由 CDB ROOT 的
VERIFY_FUNCTION
控制,但各 PDB 可覆盖该函数;若某 PDB 启用了更严策略,用户首次登录该 PDB 时可能因密码不满足要求被拒绝 若某个 PDB 处于
READ ONLY
状态,公共用户在其中仍可查询,但无法创建对象、甚至无法执行某些 DDL(如
ALTER SESSION
设置 NLS 参数) 最常被跳过的验证动作:在至少两个不同 PDB(包括一个刚
CREATE PLUGGABLE DATABASE
出来的空库)中,用
c##xxx
用户实际登录并执行
SELECT COUNT(*) FROM V$SESSION;
—— 这一步才能暴露权限同步或容器可见性问题。

相关文章