Oracle 在线 PDB Relocate(零停机迁移)

Oracle 在线 PDB Relocate(零停机迁移)

适用版本:Oracle Database 12.2 / 19c / 23ai 文档版本:v1.0 / 2026-07


1. 概述

PDB Relocate 是 12.2 引入的零停机 PDB 迁移机制[1],将 PDB 从源 CDB 迁移到目标 CDB,应用几乎无感知。

适用场景

  • CDB 间迁移 PDB
  • 硬件/OS 升级
  • 数据库合并/拆分
  • 平衡 CDB 负载

2. Relocate 原理

2.1 工作流程

1. 源 PDB 保持 OPEN(业务正常)
2. 目标 CDB 创建 Relocate PDB(通过 DB Link)
3. 目标 CDB 通过增量备份同步数据
4. 数据同步完成后,源 PDB 短暂关闭
5. 目标 PDB 打开,接管业务
6. 源 PDB 删除

2.2 停机时间

  • 数据同步:在线进行,无停机
  • 切换:秒级(仅切换瞬间)

3. 前置条件

3.1 源 CDB 要求

-- 1. 源 PDB 必须处于 READ WRITE
SELECT name, open_mode FROM v$pdbs WHERE name='HRPDB';

-- 2. 归档模式
ARCHIVE LOG LIST;

-- 3. 启用本地 UNDO(19c+)
SELECT name, local_undo FROM v$pdbs;

3.2 目标 CDB 要求

  • 12.2+ 版本
  • 字符集兼容
  • 时区兼容
  • COMPATIBLE 参数 >= 源 CDB

3.3 网络配置

# tnsnames.ora
HRPDB_SRC =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = src-host)(PORT = 1521))
    (CONNECT_DATA = (SERVICE_NAME = hrpdb))
  )

4. 执行 Relocate

-- 在目标 CDB 创建 DB Link
ALTER SESSION SET CONTAINER = CDB$ROOT;

CREATE DATABASE LINK src_link 
  CONNECT TO system IDENTIFIED BY ****** 
  USING 'HRPDB_SRC';

-- 测试连接
SELECT name FROM v$pdbs@src_link WHERE name='HRPDB';

4.2 检查兼容性

SET SERVEROUTPUT ON
DECLARE
  compatible BOOLEAN := FALSE;
BEGIN
  compatible := DBMS_PDB.CHECK_PLUG_COMPATIBILITY(
    pdb_descr_file => NULL,
    pdb_name => 'hrpdb',
    db_link => 'src_link');
  IF compatible THEN
    DBMS_OUTPUT.PUT_LINE('Compatible');
  ELSE
    DBMS_OUTPUT.PUT_LINE('Incompatible');
  END IF;
END;
/

4.3 执行 Relocate

-- 在目标 CDB 创建 PDB(RELOCATE)
CREATE PLUGGABLE DATABASE hrpdb 
  FROM hrpdb@src_link 
  RELOCATE 
  AVAILABILITY MAX;

-- 过程中源 PDB 仍可正常使用
-- 目标 PDB 处于 MOUNT 状态

4.4 切换

-- 在目标 CDB 打开 PDB(触发切换)
ALTER PLUGGABLE DATABASE hrpdb OPEN;

-- 此时:
-- 1. 源 PDB 自动关闭
-- 2. 业务连接切换到目标 PDB
-- 3. 目标 PDB 接管服务

4.5 完成验证

-- 目标 PDB 状态
SELECT name, open_mode FROM v$pdbs WHERE name='HRPDB';

-- 源 PDB 已关闭
-- 在源 CDB 查看
SELECT name, open_mode FROM v$pdbs WHERE name='HRPDB';
-- OPEN_MODE = MOUNT

5. AVAILABILITY 选项

5.1 AVAILABILITY MAX

CREATE PLUGGABLE DATABASE hrpdb 
  FROM hrpdb@src_link 
  RELOCATE 
  AVAILABILITY MAX;
-- 源 PDB 保持 OPEN 最长时间
-- 切换瞬间停机最短

5.2 AVAILABILITY NORMAL

CREATE PLUGGABLE DATABASE hrpdb 
  FROM hrpdb@src_link 
  RELOCATE 
  AVAILABILITY NORMAL;
-- 源 PDB 在某些阶段关闭
-- 同步时间更短

6. 服务切换

6.1 服务配置

-- 在目标 CDB 创建相同服务
ALTER SESSION SET CONTAINER = hrpdb;
EXEC DBMS_SERVICE.CREATE_SERVICE('hrpdb', 'hrpdb');

-- 启动服务
EXEC DBMS_SERVICE.START_SERVICE('hrpdb');

6.2 客户端配置

# tnsnames.ora - 使用 SCAN 或多地址
HRPDB =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (LOAD_BALANCE = ON)
      (FAILOVER = ON)
      (ADDRESS = (PROTOCOL = TCP)(HOST = new-host)(PORT = 1521))
      (ADDRESS = (PROTOCOL = TCP)(HOST = old-host)(PORT = 1521))
    )
    (CONNECT_DATA = (SERVICE_NAME = hrpdb))
  )

7. 监控 Relocate

7.1 查看进度

-- 在目标 CDB
SELECT 
  opname, 
  target, 
  sofar, 
  totalwork, 
  units, 
  time_remaining
FROM v$session_longops
WHERE opname LIKE '%PDB%';

7.2 PDB 状态

-- 源 CDB
SELECT name, open_mode FROM v$pdbs WHERE name='HRPDB';

-- 目标 CDB
SELECT name, open_mode FROM v$pdbs WHERE name='HRPDB';

7.3 Alert Log

# 监控 alert log
tail -f $ORACLE_BASE/diag/rdbms/$DB_UNIQUE_NAME/$ORACLE_SID/trace/alert_$ORACLE_SID.log

8. 回滚

8.1 切换前回滚

-- 在目标 CDB 终止 Relocate
ALTER PLUGGABLE DATABASE hrpdb CLOSE;
DROP PLUGGABLE DATABASE hrpdb;

-- 源 PDB 保持可用

8.2 切换后回滚

-- 较复杂,需重新 Relocate 回去
-- 1. 在源 CDB 重新打开 PDB
ALTER SESSION SET CONTAINER = CDB$ROOT;
ALTER PLUGGABLE DATABASE hrpdb OPEN;

-- 2. 从目标 Relocate 回源
CREATE DATABASE LINK tgt_link ...
CREATE PLUGGABLE DATABASE hrpdb 
  FROM hrpdb@tgt_link 
  RELOCATE;

9. 与 Data Guard 集成

9.1 主备库 Relocate

-- 1. 主库 Relocate
CREATE PLUGGABLE DATABASE hrpdb FROM hrpdb@src_link RELOCATE;

-- 2. Data Guard 自动同步到备库

9.2 备库 PDB 状态

-- 备库
SELECT name, open_mode FROM v$pdbs;
-- hrpdb: READ ONLY(Active Data Guard)

详细内容见:Oracle Data Guard 架构与配置


10. 常见坑与排错

10.1 ORA-65122: 源 PDB 不存在

现象:Relocate 失败。

修复

-- 1. 检查 DB Link
SELECT name FROM v$pdbs@src_link;

-- 2. 检查 tnsnames.ora
! tnsping HRPDB_SRC

-- 3. 检查源 PDB 名称(区分大小写)

10.2 ORA-65334: 字符集不兼容

修复

-- 检查字符集
-- 源
SELECT value FROM nls_database_parameters@src_link WHERE parameter='NLS_CHARACTERSET';
-- 目标
SELECT value FROM nls_database_parameters WHERE parameter='NLS_CHARACTERSET';

10.3 ORA-65169: 源 PDB 必须打开

修复

-- 源 CDB
ALTER PLUGGABLE DATABASE hrpdb OPEN;

10.4 Relocate 卡住

现象:Relocate 长时间无进展。

修复

-- 1. 检查等待事件
SELECT event, state FROM v$session WHERE sid=(SELECT sid FROM v$mystat WHERE rownum=1);

-- 2. 检查 DB Link
SELECT * FROM dba_db_links;

-- 3. 检查网络
! tnsping HRPDB_SRC

10.5 切换失败

现象:源 PDB 未关闭。

修复

-- 1. 手动关闭源 PDB
-- 源 CDB
ALTER PLUGGABLE DATABASE hrpdb CLOSE;

-- 2. 重新打开目标 PDB
-- 目标 CDB
ALTER PLUGGABLE DATABASE hrpdb OPEN;

11. 最佳实践

  1. 测试兼容性:DBMS_PDB.CHECK_PLUG_COMPATIBILITY
  2. 使用 AVAILABILITY MAX:最小停机
  3. 服务名一致:客户端无感切换
  4. tnsnames 多地址:自动故障切换
  5. 监控 Relocate 进度:v$session_longops
  6. 切换前测试:业务验证
  7. 保留回滚选项:切换前不删源 PDB
  8. 切换后验证:业务功能测试
  9. 删除源 PDB 前备份:防止误删
  10. 使用 19c+:特性更完善

12. 参考资料

[1] Oracle Multitenant Administrator’s Guide 19c, “Relocating a PDB” https://docs.oracle.com/en/database/oracle/oracle-database/19/multi/relocating-a-pdb.html