Dataguard中pdb的迁移和故障切换
在12c多租户环境中,每一个CDB当中都会有多个pdb在运行,在某些情况下会涉及到CDB之间进行pdb的迁移。当然也就会碰到类似的情况,比如只有其中某一个pdb出现了问题,而其他的pdb都运行正常,这个时候如果对CDB做failover代价太大,这时为了最大程度减少停机时间和缩小影响,我们可以只对这个单独的pdb进行failover或者迁移到同服务器的其他primary cdb。这就需要用到dg broker所带来的新功能,从12.1版本开始,通过dg broker中migrate pluggable database
命令能很方便的对pdb进行迁移操作,方便的同时得需要满足一些条件才可以实现,数据库的版本、补丁、COMPATIBLE参数等
实验环境大致如下
Host | CDBNAME | PDBNAME |
---|---|---|
Pri | ORA12C | PDB12C |
Pri | ORA12C | PDB3 |
Stb | ORA12C | PDB12C |
Stb | ORA12C | PDB3 |
Stb | CDB1 | PDB1 |
注意事项
下面的步骤假设源CDB库(无论是主库还是备库用来做迁移和failover)和目标CDB库能访问到同一个存储,这样就不需要复制文件操作。
- 源CDB库可以是RAC也可以是单实例
- 源CDB的备库不需要是ADG,尽管备库的CDB和PDB都需要被打开为只读模式一段时间
- 目标CDB可以是RAC也可以是单实例
- 源端和目标端的存储方式可以是文件系统也可以是ASM
- 如果是从备库进行迁移,确保之前已经建好了TEMP临时文件
- 如果源PDB正常关闭:
- 对于迁移操作,源pdb必须要打开,而且恢复到当前状态否则迁移的过程中会拔下失败
- 对于failover,源端pdb的正常关闭没什么影响。拔下操作会失败,需要手动清理并完成操作。
- 如果目标CDB的版本较高,则pdb仍能插入但是处于关闭状态,需要手动进行升级。
- 无法迁移或者failover到低版本数据库
- 迁移和failover不支持PDB快照克隆
- 任务执行完毕以后,需要手动清理主库剩余的数据文件
- 目标库插入pdb时是通过STANDBYS=NONE的方式,所以在目标库的其他备库中需要手动启用恢复
迁移过程
迁移是用来将PDB从一个cdb迁移到其他cdb中去,migrate命令会将dgbroker配置中主库的pdb拔下,然后插入到另外一个configuration中的主库当中去。
可以将pdb迁移到更高版本的CDB当中去,往低版本则不行。在迁往更高的版本以后,被迁移的pdb在目标cdb中处于关闭状态,你必须执行一些操作来让pdb进行升级。同样pdb可以迁移到更高COMPATIBLE
参数值的数据库当中去。
迁移过程的大致步骤如下:
- 停止所有连到被迁移pdb的服务
- 如果dg环境中你却没有打补丁Patch 25616359 的话,则必须先要停掉备库上所有的pdb,否则redo apply会失败
- dgmgrl连接到主库
1 | $ dgmgrl |
- 执行migrate命令
1 | DGMGRL> migrate pluggable database <PDBNAME1> to container <dest-cdb-name> using '/<path>/<DEST_SID>/<PDBNAME1.xml>' connect as <USERNAME>@"<dest-cdb-connect-identifer>"; |
manifest文件存放路径必须可以同时被源端主库和目标端主库访问的到
- 当连上目标库以后,migrate命令会做以下事情:
- 对migrate操作做一些必要的验证工作
- 从主库拔下pdb
- 在目标库上使用主库的数据文件通过
STANDBYS=NONE
的方式创建PDB - 如果目标库的版本与源端一样,则在其所有实例中打开PDB
- 在源端主库中删除pdb,同时删除源端备库中的pdb
- 当migrate命令完成以后则执行以下任务:
- 将之前连接到pdb的服务进行重连
- 将目标端CDB中的pdb进行备份方便以后恢复
- 参照Note 1916648.1中开启pdb的备库同步
迁移测试用例
主库pdb的状态
1 | sys@ORA12C> show pdbs; |
生成pdb的xml文件
1 | sys@ORA12C> alter session set container=pdb3; |
在备库机器上连接到源库的dg broker
1 | DGMGRL> connect sys/oracle@ora12c_dg |
然后执行迁移命令,使用之前生成的xml文件,因为这里只能使用本地路径,所以必须要是共享目录或者同一个机器上
1 | DGMGRL> migrate pluggable database immediate pdb3 to container cdb1 using '/u01/app/oracle/oradata/pdb3.xml'; |
failover步骤
下面的图展示了将一个故障的pdb迁移到新的cdb过程中初始和结束的状态。
CDB1有三个pdb(PDB1,PDB2,PDB3),同时有一个物理备库。在物理备库同一个机器上有另外一个CDB2,CDB2是可读写状态,出故障的pdb将会迁移到这个CDB上面来。
迁移前的状态:
目前CDB1上的所有pdb都运行正常,CDB1的备库不是处于active dg。CDB2有自己的pdb4
迁移后的状态:
PDB2出现故障,估算需要很长的时间才能恢复,但是目前PDB1和PDB3均允许正常,而且备库的同步也都正常。为了最低程度减小影响,将使用备库pdb2的数据文件去插入到CDB2当中作为读写状态提供给应用访问,然后删除CDB1上的pdb2。这不是一个本机拔插操作,因为它需要一个可读写的CDB。
过程
failover主要用于主库的某个pdb出现了故障,而其他pdbs都允许正常,这时就需要将这个pdb移到其他CDB上去。它提供了一个方法可以只对主库的其中一个pdb进行故障转移而不用影响其他库。备库必须要与目标CDB共享数据文件存放的目录和通过DBMS_PDB.DESCRIBE
生成的XML文件所在路径,目标CDB都要能够访问到这些文件,无论是通过在同一台机器或者NFS挂载的方式。
Failover不是一个计划性操作,所以目标就是尽可能降低停机时间。所以要确保一些前提条件:
- 源和目标库都必须打上相同的补丁包,这样就不用执行额外的脚本,这些内容会在
DGMGRL CLI MIGRATE
命令时用到,最好的方式是目标CDB与源备库使用同一个oracle home目录 - 目标CDB最好与源库安装的同样的Oracle组件
failover步骤:
- 停掉所有连接到故障pdb主备库的服务
- 连接dgmgrl到备库,使用sysdba角色
1 | $ dgmgrl |
- 在dgmgrl命令行中执行failover操作。Note:这里的操作与之前的迁移命令一模一样
1 | DGMGRL> migrate pluggable database <PDBNAME1> to container <dest-cdb-name> using '/<path>/<PDBNAME1>/<PDBNAME1.xml>' connect as <USERNAME>@"<dest-cdb-connect-identifer>"; |
-
当到目标CDB的连接建立以后,主要做了如下事情:
- 做了很多failover操作必要的校验
- 如果备库的redo apply运行则会停掉
- 将所有备库实例打开到read only状态
- 根据迁移命令指定的路径通过DBMS_PDB.DESCRIBE创建XML文件
- 停止源备库PDB的恢复
- 如果源备库本身不是ADG状态则还原成mount
- 通过备库的数据文件(NOCOPY)在目标CDB创建PDB,使用STANDBYS=NONE选项
- 在目标CDB的所有实例打开PDB
- 拔掉源主库的PDB,如果操作有报错则需要手动解决
- 如果拔下操作顺利,则通过KEEP DATAFILES的方式删掉PDB,这同样会删除所有源备库的pdb。
- 如果都顺利结束,则将之前的服务都连到新PDB上来
- 备份目标CDB的PDB允许恢复
- 开启目标CDB所有备库的恢复操作
因为Failover过程中使用的DGMGRL命令与之前迁移操作的基本一样,这里就不再一一赘述,全文完。