执行begin backup之后,oracle会把将要备份的数据文件都标记为hot-backup-in-progress,锁定所要备份的datafile header的scn,例如此时scn=100,同时redolog中会记住这个scn,其他数据文件正常使用,scn会继续增长。之后在备份所要备份的数据文件过程中,数据文件是允许写入和checkpoint,而且可能不止一次checkpoint,而这个过程中的所有操作和checkpoint也会正常记录到redolog与archivelog中。
oracle系统数据文件最小存储单元是数据块,比如8192bytes,而操作系统的最小存储单元os快为固定的512bytes,这样问题就产生了。
在oracle执行begin backup之后进行copy操作,这个copy操作底层属于操作系统的命令,每次只能copy一个os block,假如oracle数据库的block单位为8192bytes,那么这个oracle block就由16个os block组成,这里为了方便理解,我们把他们标记为1--16个os block。copy命令对于数据块的拷贝时没有顺序的,也就是说第一次可能copy 1号block,而第二次可能就会copy 16号block。而在这个copy过程中,对于oracle热备份机制来说对oracle整个的block是允许读写,这样就会产生如下的问题,例如:执行begin backup,oracle锁定datafile header的scn,假设此时oracle block中存储的数据室10,敲copy进行复制,系统就会将这个oracle block中的16个os block一个一个地拷贝到备份目录,假如拷贝到第五个os block时候,如果有数据写入,例如需要将这个数据块中的数据update为20,oracle就会调用dbwr进程对这个数据块进行数据修改,同样dbwr进程也是不顺序地将数据写入这16个os block,所以他就有可能从已经拷贝完的那五个os块中开始写数据,也有可能从剩下的11个os block中开始写数据。如果从剩下的11个os block中开始写入的话,就会带来一个严重的后果,热备份copy正在进行,而剩下的11个block其中的几个有可能数据已经改变,这样copy出来的备份文件肯定会不一致,copy出来的备份文件对于这个oracle block来说前5个block是原来存储数据10的信息,而后来copy的11个block就有可能存储的是update之后的数据20的信息,这样是绝对不允许的。
因此,oracle做了这样的一个机制,在copy过程中如果需要有数据update,dbwr进程告诉oracle我要update,这时候oracle就会通知备份系统,先把所要写入的那个oracle block完全镜像到redo中,redo记录的是整个数据块的镜像,而不是一条信息。之后dbwr在开始向这个oracle block中的16个os block随机写入数据。这样,在数据恢复的时候,oracle检查是从被锁定的那个scn时刻起开始恢复,如果检查到那个时间点上的某个oracle block出现上述所说的那种“损坏的block”,他就会将redo中的镜像在完全copy到这个oracle block,这样,这个数据块就是begin backup的那个时间点时候的完整的数据块了,之后redo就可以从这个scn进行向后的恢复工作。
这个过程也就解释了为什么在热备过程中有时候redo会急剧增加的现象。
结束热备份end backup之后,oracle解锁备份的datafile header的scn,自动同系统当前的scn同步,例如此时的scn已经变为1000,那么备份文件的scn会与系统自动同步到1000。
因为在备份过程中数据文件及redo是允许写入的,因此备份的数据文件不仅包含scn=100以前的数据,而且还包含scn在100和1000之间的所有操作数据。这就是我上述所说的“损坏的block”。
在数据恢复的时候,将备份的数据文件复制到oracle系统之后,因为备份文件的scn是在执行alter database begin backup时候的时间点,也就是scn=100,oracle会在redolog中查找这个scn,如果这个scn时间点有“损坏的block”,redo先把以前镜像好的block完全复制回去,然后自动执行scn大于100之后的所有操作及数据,写入当前数据文件。而从备份文件恢复到当前的数据文件中scn在100和1000之间的数据将会被redo操作覆盖。
因为在备份过程中数据文件及redo是允许写入的,因此备份的数据文件不仅包含scn=100以前的数据,而且还包含scn在100和1000之间的所有操作数据。这就是我上述所说的“损坏的block”。
在数据恢复的时候,将备份的数据文件复制到oracle系统之后,因为备份文件的scn是在执行alter database begin backup时候的时间点,也就是scn=100,oracle会在redolog中查找这个scn,如果这个scn时间点有“损坏的block”,redo先把以前镜像好的block完全复制回去,然后自动执行scn大于100之后的所有操作及数据,写入当前数据文件。而从备份文件恢复到当前的数据文件中scn在100和1000之间的数据将会被redo操作覆盖。