Oracle 12c R1 默认不支持 PDB 使用独立 Undo 表空间,仅支持 Shared Undo 模式,所有 PDB 共用 CDB$ROOT 的 UNDOTBS1;R2 起才支持 Local Undo,需启用 LOCAL_UNDO_ENABLED=TRUE 并重启。
Oracle 12c R1 默认不支持 PDB 使用独立 Undo 表空间
因为 oracle 12c r1 的多租户架构只实现了 shared undo 模式:整个 cdb 只有一个活动的 undotbs1 表空间,所有 pdb(包括 cdb$root 和 pdb$seed)强制共用它。这不是设计疏漏,而是 r1 版本的临时限制——官方明确说明该模式仅用于平滑升级过渡。
你无法在 R1 中为某个 PDB 手动创建或指定自己的 Undo 表空间,哪怕执行 CREATE UNDO TABLESPACE 也会报错:ORA-65040: operation not allowed from within a pluggable database(除非当前容器是 CDB$ROOT,但创建出的 Undo 仍属全局共享)。
Oracle 12c R2 起才真正支持 Local Undo 模式
R2(12.2.0.1+)引入了 LOCAL_UNDO_ENABLED=TRUE 配置,允许每个 PDB 拥有专属 Undo 表空间。启用后:
- Oracle 自动为每个已打开的 PDB 创建一个
UNDO表空间(命名如UNDOTBS2、UNDOTBS3) -
SELECT con_id, tablespace_name FROM cdb_tablespaces WHERE contents = 'UNDO'会返回多行,每行对应一个容器 - 切换模式必须重启数据库,并使用
STARTUP UPGRADE+ALTER DATABASE LOCAL UNDO ON/OFF
注意:RAC 环境下,Local Undo 还要求每个实例为每个 PDB 维护独立的 active undo segment,否则可能触发 ORA-01555 或事务回滚失败。
Shared Undo 下 PDB 表空间“看似可用”实则受限
你在 PDB 里查 DBA_TABLESPACES 确实能看到 UNDOTBS1,但它只是视图映射,并非真正归属该 PDB:
- 该表空间的文件路径、状态、自动扩展等属性全部由
CDB$ROOT控制 - PDB 内部事务产生的 undo record 全部写入同一物理文件,无隔离性
- 一旦该文件损坏(比如误删
undotbs1.dbf),所有 PDB 同时无法 open,且恢复时必须从 CDB 层面整体处理
这也是为什么 R1 环境下做 PDB 拔插、闪回、热克隆等操作风险极高——Undo 不是“按 PDB 切分”的,根本做不到容器级时间点恢复。
Local Undo 切换失败的典型表现
执行 ALTER DATABASE LOCAL UNDO ON 后重启,却仍看到 LOCAL_UNDO_ENABLED=FALSE,常见原因有:
- 没在
CDB$ROOT下执行命令,或执行时数据库未处于UPGRADE模式 - CDB 中已有 PDB 处于
MOUNTED状态(非READ WRITE),导致 Oracle 无法自动为其创建 undo 表空间 - 磁盘空间不足,或
DB_CREATE_FILE_DEST未设置,Oracle 创建新 undo 文件失败且静默跳过
验证是否生效,别只看 database_properties,务必再跑一次:SELECT con_id, tablespace_name FROM cdb_tablespaces WHERE contents = 'UNDO' AND con_id > 2 —— 如果只有 con_id=1 一行,说明切换未真正落地。











