oracle 12c rac部署cdb/pdb必须建库时启用多租户,不可后期补救;dbca须勾选“创建为容器数据库”,新建pdb默认mounted,rac中需在各节点手动open并绑定资源计划,连接必须使用注册的service_name。
oracle 12c rac 中部署 cdb/pdb 不是“在 rac 上加个容器”,而是必须从建库阶段就按多租户模式构建;否则后续无法补救——rac 环境下误建为非 cdb,连 create pluggable database 都会报 ora-65096 或 ora-65131。
DBCA 创建 CDB 时必须显式勾选“创建为容器数据库”
这是整个多租户架构的起点,且不可逆。RAC 环境中使用 DBCA 图形界面或静默模式都一样:在“配置选项”页(非模板页之后)必须勾选 Create as Container Database。不勾选,生成的数据库就是传统非 CDB,哪怕后续在 RAC 中启用了所有集群服务,也无法承载 PDB。
静默命令示例(关键参数不能漏):
dbca -silent -createDatabase \ -createAsContainerDatabase true \ -templateName $ORACLE_HOME/assistants/dbca/templates/General_Purpose.dbc \ -gdbname orcl \ -storageType ASM \ -diskGroupName DATA \ -characterSet AL32UTF8 \ -totalMemory 4096
注意:-createAsContainerDatabase true 是强制开关,-storageType ASM 和 -diskGroupName 必须匹配 RAC 的 ASM 配置,否则 DBCA 会失败并卡在磁盘校验环节。
新建 PDB 后默认 MOUNTED,RAC 节点间状态不同步是常见故障源
RAC 中每个实例都可连接同一 CDB,但 PDB 的 OPEN 状态不是自动广播的。DBCA 创建完第一个 PDB(如 orclpdb)后,它在所有节点上初始状态都是 MOUNTED,而非 READ WRITE。若只在一个节点执行 ALTER PLUGGABLE DATABASE orclpdb OPEN;,其他节点仍看到 MOUNTED,导致应用连接失败或报 ORA-01033: ORACLE initialization or shutdown in progress。
正确做法是:
- 先确认当前连接的是 CDB$ROOT:
SHOW CON_NAME输出应为CDB$ROOT - 查所有节点上的 PDB 状态:
SELECT CON_ID, NAME, OPEN_MODE, INST_ID FROM GV$PDBS WHERE NAME = 'ORCLPDB';(用GV$视图,不是V$) - 对每个
INST_ID对应的实例,分别执行打开命令;或更稳妥地,在所有 RAC 节点上逐个运行:ALTER PLUGGABLE DATABASE orclpdb OPEN READ WRITE;
漏掉任一节点,应用路由到该节点时就会因 PDB 未打开而中断。
资源隔离靠 CDB 级资源计划,不是 RAC 的 instance caging
RAC 的 CPU 资源限制(如 instance caging)作用于整个实例,无法区分 CDB 内部的 PDB。真正控制 PDB 资源配额的是 CDB 级别的 DBMS_RESOURCE_MANAGER,且必须绑定到每个 PDB 单独生效。
典型操作链:
- 在 CDB$ROOT 中创建资源计划:
EXEC DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA();→ 定义消费者组、计划指令 - 将计划绑定到指定 PDB:
ALTER PLUGGABLE DATABASE orclpdb RESOURCE MANAGER PLAN = 'MYPDB_PLAN'; - 验证是否生效:
SELECT * FROM DBA_RSRC_PLANS@orclpdb;(注意必须跨容器查询,或在 PDB 内连进去查)
若跳过绑定步骤,即使计划已存在,PDB 仍共享 CDB 全局资源池,无法实现 CPU/IO 隔离。RAC 中尤其要注意:资源计划变更不会自动同步到其他节点,需在所有节点上执行绑定语句,或通过 srvctl 重启 PDB 触发重载。
连接串必须带 service_name,且该 service 必须已注册到 SCAN Listener
RAC 下访问 PDB 不能靠 tnsnames.ora 里写死的 HOST=rac-node1,必须用 SCAN 地址 + 正确的 SERVICE_NAME。这个 service 名不是 PDB 名,而是由 DBMS_SERVICE.CREATE_SERVICE 显式创建、并通过 srvctl add service 注册进集群的。
例如:
- 在 PDB 内执行:
EXEC DBMS_SERVICE.CREATE_SERVICE('hrpdb_svc', 'hrpdb_svc'); - 在任意节点执行:
srvctl add service -d orcl -s hrpdb_svc -r "orcl1,orcl2" -P BASIC - 启动 service:
srvctl start service -d orcl -s hrpdb_svc
此时客户端连接串才能用:hrpdb_svc.scan.example.com:1521/hrpdb_svc。若直接用 orclpdb 作为 service_name,SCAN Listener 不识别,会返回 ORA-12514: TNS:listener does not currently know of service requested in connect descriptor。
最关键的细节:service 注册后,需等约 30 秒让 SCAN Listener 刷新服务列表,立即测试常失败;且 srvctl config service -d orcl 必须显示该 service 已分配到全部预期实例,缺一则负载不均。











