必须在CDB$ROOT中创建以C##开头的公共用户并授予PDB_DB A角色才能管理所有PDB;在PDB中创建用户或授PDB_DB A权限均会失败,因该角色仅在CDB$ROOT有效且需CONTAINER=ALL。
不能在pdb中创建“管理所有pdb”的用户——这类权限只存在于cdb$root,且必须用前缀创建公共用户。
试图在某个pdb里建一个能跨pdb操作的账号,
oracle
会直接拒绝(如
或
)。真正可行的做法,是回到cdb$root,用公共用户+公共角色组合实现集中管控。
为什么
在PDB里失败?
Oracle 12c强制区分用户类型:
PDB内只能创建
本地用户
(local user),名字不能带
,但权限范围严格限制在当前PDB内
想管理多个PDB(比如启停、备份、查所有PDB状态),必须是
公共用户
(common user),名字必须以
或
开头,且只能在
中创建
直接在PDB里执行
会报
如何在CDB$ROOT中创建可管理全部PDB的公共用户
切换到根容器后,按顺序执行以下操作:
确认当前容器:
,结果必须是
创建公共用户:
(
是关键,缺了就只是CDB$ROOT本地用户)
授予CDB级管理权限:
(注意:不是
角色,
才是专为PDB管理设计的公共角色)
可选但推荐:
,以便查询
视图(如
、
)
和
角色到底差在哪?
这是最容易混淆也最危险的一点:
oracle知识库
oracle知识库下载
下载
是传统单机数据库的角色,包含大量CDB级系统权限(如
、
),在CDB环境里授予它等于开放整个容器,
不推荐给非SYS用户
是12c新增的公共角色,权限聚焦在PDB生命周期操作:
、
、
等,且自动适配
语义
在PDB中执行
会报
,因为
角色在PDB上下文不可见
连接与使用这个CDB管理员用户的注意事项
即使用户建对了,连错地方依然白搭:
必须用
连接,
不能指定PDB服务名
(否则进的是PDB,看不到其他PDB)
连接后默认仍在
,查
确认;要操作某PDB,仍需
,但此时你有权限
不要在PDB里尝试
——该角色只在CDB$ROOT有效,PDB中执行会报
如果需要让某个PDB用户也能执行
,必须由CDB管理员显式授予
权限并授权
,且该用户本身也得是
开头的公共用户
最关键的细节往往藏在容器边界上:一个
漏写,一个
少切,或者连错了服务名,都会让看似完整的授权链彻底失效。多租户不是加了个PDB开关,而是把权限模型从平面拉成了立体——CDB$ROOT是控制塔,每个PDB是独立舱室,钥匙(用户)和门禁卡(角色)必须严格匹配层级。
c##ora-65094ora-65047CREATE USER u1 IDENTIFIED BY pwdC##C##c##CDB$ROOTCREATE USER admin IDENTIFIED BY p123ORA-65096: invalid common user or role nameSELECT SYS_CONTEXT('USERENV', 'CON_NAME') FROM DUALCDB$ROOTCREATE USER C##pdb_admin IDENTIFIED BY secure_pwd CONTAINER=ALLCONTAINER=ALLGRANT SYSDBA, PDB_DBA TO C##pdb_admin CONTAINER=ALLDBAPDB_DBAGRANT SELECT_CATALOG_ROLE TO C##pdb_admin CONTAINER=ALLCDB_*CDB_PDBSCDB_USERSPDB_DBADBADBAALTER DATABASEDROP TABLESPACEPDB_DBAALTER PLUGGABLE DATABASE ... OPENCREATE PLUGGABLE DATABASEDROP PLUGGABLE DATABASECONTAINER=ALLGRANT DBA TO u1ORA-01917: user or role 'DBA' does not existDBAsqlplus C##pdb_admin/secure_pwd@cdb_service_name AS SYSDBACDB$ROOTSHOW CON_NAMEALTER SESSION SET CONTAINER=pdb_nameGRANT PDB_DBA TO u1ORA-01917ALTER PLUGGABLE DATABASE ... OPENSET CONTAINERPDB_DBAC##CONTAINER=ALLALTER SESSION