1 容器数据库的一致性
数据库整体上(CDB)会统一维护一套SCN机制,不论是ROOT还是PDB中,但是并不要求ROOT和所有的PDB都拥有相同的一致性。我们在查看数据文件SCN的时候,
ROOT和每个PDB中的几个数据文件,它们必须要一致,但是ROOT和PDB之间不必一致。这就给PDB带来了很的灵活性。
例如,我们在12:00:00时进行了全库备份,在15:00:00进行了归档备份,备份数据中包括了CDB和所有的PDB。在16:00:00时我们对数据进行恢复,将ROOT恢复到最新的状态,即15:00:00,也就是应用全部归档。但是恢复PDB的时候,我们需要恢复到14:30:00,应用部分归档。结果就是ROOT和PDB没有恢复到同一个时间点上,这是系统可以支持的,也是容器灵活性必需要提供的。
2 RMAN连接
首先,我们需要在TNSNAME中解析PDB连接,例如,
[oracle ~]$ cat $ORACLE_HOME/network/admin/tnsname.ora
SERVICE_NAME可以在通过查看监听获取,例如,
[oracle ~]$ lsnrctl status
RMAN登陆PDB数据库,
[oracle ~]$ rman target sys/password@orclpdb
3 数据库备份
有两种方式:
1) 整库备份
包括参数文件、控制文件、归档日志、ROOT库和全部PDB库;
2) PDB备份
ROOT、PDB分别进行备份;
3.1 整库备份
这与前面章节介绍的内容完全相同,这里不再重复介绍。
3.2 PDB备份
首先,PDB的用户权限是有限的,它不能备份归档和参数文件。因此,在备份CDB的时候需要统一对参数文件和归档进行备份,同时也对控制文件进行备份。在对PDB进行备份时,只需要备份数据文件即可。
- 备份ROOT库
[oracle ~]$ rman target /
RMAN> backup database root plus archivelog; --备份root库和归档
RMAN> backup pluggable database 'pdb$seed'; --备份PDB模板库
如果没有开启自动备份控制文件,需要进行手动备份,
RMAN> backup current controlfile;
RMAN> backup spfile;
- 备份PDB
可以选择在ROOT库中操作,也可以在PDB库中操作,出于安全隔离目的,建议在PDB中操作。
在ROOT库中操作备份PDB,
[oracle ~]$ rman target /
RMAN> backup pluggable database orclpdb;
或在PDB中操作备份,
[oracle ~]$ rman target sys/password@orclpdb
RMAN> backup database;
4 数据库恢复
4.1 基本恢复操作
PDB用户虽然没有权限对参数文件和归档日志进行备份,但是恢复的时候就是可以读取这些备份数据的。因此,不论使是在CDB中还是在PDB中进行的备份,在PDB中都可以看到备份数据。有两种恢复方式:
1) 在ROOT库中操作
恢复ROOT库,
[oracle ~]$ rman target /
RMAN> restore pluggable database root;
RMAN> recover pluggable database root;
RMAN> alter database open;
恢复PDB,
[oracle ~]$ rman target /
RMAN> restore pluggable database orclpdb;
RMAN> recover pluggable database orclpdb;
RMAN> alter pluggable database orclpdb open;
2) 在PDB中操作当前库的恢复
恢复ROOT库,
[oracle ~]$ rman target /
RMAN> restore pluggable database root;
RMAN> recover pluggable database root;
RMAN> alter database open;
恢复PDB,rman直接连接PDB
[oracle ~]$ rman target sys/password@orclpdb
RMAN> restore database;
RMAN> recover database;
RMAN> alter database open;
4.2 按照时间点恢复(PITR)
有一个关于时间点恢复的问题。我们可以将ROOT和所有的PDB统一恢复到一个时间点,也可以恢复到不同的时间点。例如,我们可以整个数据库,包括ROOT和所有的PDB统一恢复到SCN 10010。也可以将ROOT和PDB恢复到不同的时间点,例如ROOT恢复到SCN 10010,PDB恢复到SCN 10005。这是系统允许的操作,因此PDB之间数据具备隔离特性。同样,ROOT恢复的SCN号也可以小于PDB恢复的SCN号。我们来看一组操作示例:
运行中的数据库,查看数据文件SCN,
关闭PDB,删除数据文件,再使用备份数据对PDB进行恢复,
SQL> alter pluggable database db23pdb01 close;
RMAN> restore pluggable database db23pdb01;
查看恢复后的数据文件SCN,
可以看到db23pdb01这个PDB的数据文件,都恢复到了备份时的状态。使用时间点恢复,并打开数据库,
RMAN> recover pluggable database db23pdb01 until scn 2385970;
RMAN> alter pluggable database db23pdb01 open resetlogs;
再次查看数据文件SCN,
为什么我们恢复目标SCN是2385970,但是数据库打开后SCN变成了2387568?原因PDB在打开时,系统自动对数据库文件进行了checkpoint,将SCN变成了系统当前的SCN。ROOT库的数据文件SCN没有变,因为没有进行checkpoint。如果我有强迫症,也可以手动进行一次全库的checkpoint,
这下看着舒服多了。
前面提到过INCARNATION的概念,这里再简单说明一下PDB的INCARNATION。它其实是整个数据库INCARNATION的子集,通过视图查看。
首先查看全库的视图,当前INCARNATION序号为4,
再查看PDB数据库的INCARNATION,
前三行,保持与CDB全库的INCARNATION一致。第四行,因为PDB单独执行过时间点恢复,并且进行RESETLOGS,所以产生了新的INCARNATION,它是从第二条继承来的。有没有发现一个问题,为什么前三行的INCARNATION_SCN和BEGIN_RESETLOGS_SCN这两个值相同,但是第四行确不同?我们先了解一下每个字段的含义:
- DB_INCARNATION,CDB的INCARNATION编号; PDB_
- INCARNATION,PDB的INCARNATION编号,如果PDB没有做过单独的时间点恢复,它应该是0;
- STATUS,如果没有做过PDB的时间点恢复,它与CDB保持一致; INCARNATION_SCN,按时间点恢复时的目标SCN;
- BEGIN_RESETLOGS_SCN,执行RESETLOGS时的SCN;
- END_RESETLOGS_SCN,数据库打开的时间点的SCN;
- CON_ID,1为ROOT库,2是PDB&SEED库,3开始以后是PDB库。
现在来解释一下第四行INCARNATION_SCN和BEGIN_RESETLOGS_SCN这两个值不同的原因。前三行的RESETLOG,都是在数据库MOUNT状态下进行的,因此SCN没有变化。第四行,执行的PDB的单独恢复,此时整个CDB是在OPEN状态,SCN是持续变化的,因此RESETLOGS的动作是按照数据库当前的SCN进行的。
优快云视频课程:
https://edu.youkuaiyun.com/lecturer/8135?spm=1002.2001.3001.4144