本周在x9m上adg环境主库上做pdb迁移的时候,出现了一个问题,备库在想要启动pdb的时候出现了无法打开的问题,在与sr深入交流之后发现了问题的原因。
1 standbys子句
创建pdb的standbys子句,指定创建pdb时是否在备库创建同一pdb的数据文件,使用方式如下:
create pluggable database xxx ... standbys= ('cdb_name1','cdb_name2',...)|none|all|all except;
standbys子句包含:
- cdb_name: 在指定的备库中创建pdb数据文件。
- none: 不在任何备库中创建pdb数据文件。
- all: 在所有备库中创建pdb数据文件,默认值。(大坑)
- all except: 排除部分备库,在其余备库中创建pdb文件。
在使用none和all except子句中,不在对应备库创建pdb文件不会影响dg整体同步状况,这种配置是控制部分pdb(比如测试pdb)无需灾备同步,备库中pdb不同步数据,仅有元数据展示,因此备库中pdb时无法被open read only的,在switchover后,这个pdb将无法新的主库(原备库)中使用,failover后有丢失对应数据的风险。
2 remote clone
就官方文档来看,一般情况下dg环境中创建pdb是无需关注该子句,因为默认为all。但是,在本周割接后发现备库对应pdb无法打开,出现了以下问题:
sql> alter pluggable database open read only;
alter pluggable database open read only
*
error at line 1:
ora-01147: system tablespace file xxxx is offline
sql> select file#,status,name from v$datafile where file#=1716;
file# status name
---------- ------- --------------------------------------------------------------
xxxx sysoff /u01/app/oracle/product/19.0.0.0/dbhome_1/dbs/unnamed01716
sql> alter database datafile xxxx online;
alter database datafile xxxx online
*
error at line 1:
ora-01156: recovery or flashback in progress may need access to files
检查备库数据库日志,发现了以下问题:
recovery created pluggable database pdb_xxxx <<<<<<<<
pdb_xxxx(16):tablespace-system during pdb create skipped since source is in r/w mode or this is a refresh clone
pdb_xxxx(16):file \#1716 added to control file as 'unnamed01716'. originally created as:
pdb_xxxx(16):' datac1/xxdbaas/0485588f0ab77e31e06302096f0a5738/datafile/system.1938.1146701297'
pdb_xxxx(16):because the pluggable database was created with nostandby
pdb_xxxx(16):or the tablespace belonging to the pluggable database is
pdb_xxxx(16):offline.
该pdb所有数据文件均仅有元数据过来了,日志中“the pluggable database was created with nostandby”也表示主库创建pdb似乎是使用的standbys=none方式创建的。
3 问题处理
其实这个问题处理也并不是太复杂,只不过备库需要重启可能会影响到读写分离:
- 复制数据文件至备库
rman> run{
set newname for pluggable database pdb_xxxx to new;
restore pluggable database pdb_xxxx from service wgdbaas;
}
......
rman> switch pluggable database pdb_xxxx to copy;
- 关闭数据数据同步
dgmgrl> edit database xxdbdg set state='apply-off'
- 关闭备库
srvctl stop database -db xxdbdg
- 启动数据库至mount状态(rac中单个实例即可)
startup mount
- pdb进行recovery
alter pluggable database enable recovery;
- pdb中所有数据文件online
alter database datafile 1716 online;
alter database datafile 1717 online;
......
- 正常启动备库
srvctl start database -db xxdbdg
#这里需要等待一段时间,做恢复
- 开启同步
dgmgrl> edit database xxdbdg set state='apply-on'
- 启动备库相关service
略
至此这个出现问题的pdb恢复完成,根据于sr沟通得知,在本次远程克隆pdb的过程中,standbys被自动指定成了none,但是这个参数默认值是all,为什么会出现这个问题呢?
4 dg环境对多租户环境的影响
data guard impact on oracle multitenant environments (doc id 2049127.1)
从 18c 开始,在主库创建 pdb,默认使用standbys=none的方式创建。数据库的告警日志会出现第二节中相同的输出。
具体也会有以下一些情况:
- 从seed创建新的pdb
备库会自动从灾备端的pdb$seed中复制数据文件,备库对应pdb可直接open read only(需要standbys=all)。 - 从同cdb中克隆pdb
- 在adg环境中,备库对应pdb会从灾备端本地源pdb复制数据文件,备库对应pdb可直接open read only(需要standbys=all)。
注意:在克隆创建过程中,主数据库上的源 pdb 必须处于只读模式。如果源 pdb 处于读写状态,则在尝试创建克隆的 pdb 时,在备用数据库重做应用将失败。 - 在非adg环境中,因为无法保证文件一致性,redo apply无法直接复制数据文件。
- 在adg环境中,备库对应pdb会从灾备端本地源pdb复制数据文件,备库对应pdb可直接open read only(需要standbys=all)。
- 通过dblink从其他cdb克隆pdb
通过dblink远程克隆pdb,因无法预先确定新 pdb 的 guid,因此备库无法将数据文件预先复制到“已知位置”。
如果源 pdb 在副本期间处于只读模式,并且dg处于adg模式下,oracle 建议通过配置standby_pdb_source_file_dblink(即备库配置由主库创建的指定到源端的dblink)来实现备库pdb文件创建(详见doc 2274735.1)。这允许redo apply使用dblink的将源 pdb 复制到备用数据库。这里还是需要指定standbys=all(如果是跨版本pdb克隆升级,还是建议用我本次割接的处理方式)。
如果克隆是在源 pdb open read write情况下完成的,或者dg未处于adg模式下, oracle 建议使用 create pluggable database 语句中的 standbys=none 子句推迟 pdb 的恢复。将 pdb 的数据文件从主数据库复制到备用数据库后,可以在将来的某个时间启用 pdb 的恢复, 恢复方式同上一节。 - 关于plugin和其他方式在主库创建pdb这里就不做讲解了。
5 通过dblink克隆pdb无需附加恢复的操作演示
primary daabase: prodcdb
standby database: proddg
source pluggable database: testpdb1 in devcdb
active data guard is enable.
prodcdb:
create database link devcdb connect to system identified by oracle using 'devcdb';
proddg:
alter system set standby_pdb_source_file_dblink='devcdb';
devcdb:
alter pluggable database testpdb1 close;
alter pluggable database testpdb1 open read only;
prodcdb:
create pluggable database testpdb1 from testpdb1@devcdb standbys=all;
alter pluggable database testpdb1 open;
proddg:
alter pluggable database testpdb1 open;
总结
从本期的讲解中也能知道,在dg环境中创建pdb是有一些坑的,一些操作规则和官方文档中的描述也是有一些出入的。
老规矩,知道写了些啥。