--热备份细节研究
SQL> alter database begin backup;
Database altered.
SQL> create table scott.before_bkp as select table_name from dba_tables where owner='SCOTT';
Table created.
SQL> commit;
SQL> select file#,checkpoint_change#,checkpoint_time from v$datafile;
FILE# CHECKPOINT_CHANGE# CHECKPOIN
---------- ------------------ ---------
1 1782557 19-SEP-13
2 1782557 19-SEP-13
3 1782557 19-SEP-13
4 1782557 19-SEP-13
datafile的状态
更新检查点
SQL> alter system checkpoint;
System altered.
SQL> select file#,checkpoint_change#,checkpoint_time
from v$datafile;
FILE#
CHECKPOINT_CHANGE# CHECKPOIN
---------- ------------------ ---------
1 1782557 19-SEP-13
2 1782557 19-SEP-13
3 1782557 19-SEP-13
4 1782557 19-SEP-13
SQL> host echo %time:~0%
10:29:38.67
我们发现,检查点是更新不了的,换句话说,更新了也还是一样。
我的理解:Oracle通过这个检查点,标记了begin backup的时刻点LSN,写到了所有数据文件中,标记着数据文件检查点。
看时间,好像这些数据文件都没有被更新。
|
|
|
|
测试,拿掉备份点开始后的日志文件,恢复数据库,看是否有before_bkp表。
切换日志文件
SQL> alter system switch logfile;
SQL> alter database end backup;
Database altered.
数据文件更新时间还是没任何变化…什么情况…
SQL> shutdown abort
ORACLE instance shut down.
SQL> host echo %time%
10:46:30.58
此时发生变化,看来shutdown abort还是不能模拟突然断电,我没有希望此时得到更新。s
不管如何,看看用备份的数据文件,不加begin backup之后的log,看看能恢复成什么样子,是否含有before_bkp表。
更好数据文件,重新启动数据库。
SQL> startup
ORACLE instance started.
Total System Global Area
778387456 bytes
Fixed Size 1374808 bytes
Variable Size
234882472 bytes
Database Buffers
536870912 bytes
Redo Buffers 5259264 bytes
Database
mounted.
ORA-01113: file 1 needs media recovery
ORA-01110: data file 1:
'D:APPHUJIEORADATAAUGUSTSYSTEM01.DBF'
提示需要进行media recovery。 /*media recovery过程是怎么样的?*/
数据文件,重备份的原文件拷贝到相应目录,此时的所以数据文件的检查点都是与这些数据文件备份时刻begin backup的检查点一致。
猜想: 我们的scott.begin_bkp表是发生在begin backup的SCN之后,也就是说,如果oracle在我们热备份的过程中将数据写入磁盘,那么现在的user01.DBF中,就会有scott.begin_bkp表,而且表对于的block的SCN会大于begin backup的SCN。
而这些事务的日志又被我丢掉了,那么这些事务应该能回滚。
清除旧的在线日志
SQL> alter database clear unarchived logfile group 2;
Database altered.
SQL> alter database clear unarchived logfile group 1;
Database altered.
SQL> alter database clear unarchived logfile group 3;
alter database clear unarchived logfile group 3
*
ERROR at line 1:
ORA-01624: log 3 needed for crash recovery of instance
august (thread 1)
ORA-00312: online log 3 thread 1: 'D:APPHUJIEORADATAAUGUSTREDO03.LOG'
日志组3为当前正在使用的日志组,清除不了。
----MEDIA RECOVERY
SQL> recover database until
cancel
ORA-00279: change 1782557 generated at 09/19/2013
09:59:23 needed for thread 1
ORA-00289: suggestion :
D:APPHUJIEFLASH_RECOVERY_AREAAUGUSTARCHIVELOG2013_09_19O1_MF_1_23_93NRNWS
Q_.ARC
ORA-00280: change 1782557 for thread 1 is in sequence #23
Specify log: {<RET>=suggested | filename | AUTO |
CANCEL}
auto
ORA-00308: cannot open archived log
'D:APPHUJIEFLASH_RECOVERY_AREAAUGUSTARCHIVELOG2013_09_19O1_MF_1_23_93NRNW
SQ_.ARC'
ORA-27041: unable to open file
OSD-04002: unable to open file
O/S-Error: (OS 2) The system cannot find the file
specified.
ORA-00308: cannot open archived log
'D:APPHUJIEFLASH_RECOVERY_AREAAUGUSTARCHIVELOG2013_09_19O1_MF_1_23_93NRNW
SQ_.ARC'
ORA-27041: unable to open file
OSD-04002: unable to open file
O/S-Error: (OS 2) The system cannot find the file
specified.
ORA-10879: error signaled in parallel recovery slave
ORA-01547: warning: RECOVER
succeeded but OPEN RESETLOGS would
get error below
ORA-01195: online backup of file 1 needs more recovery to
be consistent
ORA-01110: data file 1:
'D:APPHUJIEORADATAAUGUSTSYSTEM01.DBF'
可见,我们使用这种方法,根本不能够恢复回数据库,因为热备份开始时 SCN 为1782557,此范围刚好包含在我们移走的日志文件中,所以可以看出,如果我们丢失了热备份过程中正在使用的日志文件,recover database until cancel是不行的。
---那么试试 RMAN
RMAN> recover database until scn ,注意until scn只有在rman中可以使用,算是普通恢复功能的加强吧。
首先获取需要恢复到的最近scn。
SQL> select sequence#,first_change#,next_change# from
v$archived_log;
SEQUENCE#
FIRST_CHANGE# NEXT_CHANGE#
---------- ------------- ------------
6 1238892 1280080
.....
SEQUENCE#
FIRST_CHANGE# NEXT_CHANGE#
---------- ------------- ------------
17 1587139 1606123
18 1606123 1633357
19 1633357 1675049
20 1675049 1686966
21 1686966 1704171
22 1704171 1758209
23 1758209 1783919
很显然,我们要选择离丢失的archive log最近的,那就是22号归档日志,此日志的起止SCN为1704171--—1758209.
RMAN> recover database until scn 1783919;
Starting recover at 19-SEP-13
using target database control file instead of recovery
catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=10 device type=DISK
starting media recovery
RMAN-00571:
===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS
===============
RMAN-00571:
===========================================================
RMAN-03002: failure of recover command at 09/19/2013
11:39:14
RMAN-06053: unable to perform media recovery because of
missing log
RMAN-06025: no backup of archived log for thread 1 with sequence 23
and starting SCN of 1758209 found to restore
好像rman并不能识别自动归档的日志??
/*这里list
backup of archivelog all,显示的为通过rman进行备份的archivelog,很显然没有*/
/*可以通过命令RMAN> list
archivelog all来查看归档的日志信息*/
RMAN> list backup of archivelog all;
specification does not match any backup in the repository
可以使用rman对archivelog进行备份。
RMAN> backup archivelog sequence 22;
Starting backup at 19-SEP-13
using channel ORA_DISK_1
channel ORA_DISK_1: starting archived log backup set
channel ORA_DISK_1: specifying archived log(s) in backup
set
input archived log thread=1 sequence=22 RECID=17
STAMP=826449348
channel ORA_DISK_1: starting piece 1 at 19-SEP-13
channel ORA_DISK_1: finished piece 1 at 19-SEP-13
piece
handle=D:APPHUJIEFLASH_RECOVERY_AREAAUGUSTBACKUPSET2013_09_19O1_MF_ANNNN_TAG20130919T115536_93NXFRQK_.BKP
t
ag=TAG20130919T115536 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time:
00:00:03
Finished backup at 19-SEP-13
检查知道,刚刚上面的错误是由于我选错了日志文件,应该恢复到22号日志文件1758209。
RMAN>
recover database until scn 1758209;
Starting recover at 19-SEP-13
using channel ORA_DISK_1
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS
===============
RMAN-00571:
===========================================================
RMAN-03002: failure of recover command at 09/19/2013
11:58:56
RMAN-06556: datafile 1 must be
restored from backup older than SCN 1758209
根据提示知道,对于日志的应用,我们只能前滚,不能后滚,所以我们不能应用比begin backup SCN前的日志文件。
由此可以看出,备份时刻的归档日志非常重要。
那是否无计可施了呢?
暂时没办法。
结论:同db2数据库一样,热备份期间的归档日志一定要有,这个热备份才能恢复回来,不然如果只有热备份期间的数据文件备份,不管是同RMAN还是手动,都是恢复不了的。
ORACLE 热备原理,需要归档日志
关于Oracle的备份知识,下面我是我的一些摘要和自己的理解:
1、Oracle中的数据块大小通常是OS块大小的整数倍,在用系统命令直接复制数据文件到备份介质的过程中,数据库一直可用的状态,oracle数据块可能在不断的被修改,被读写,使用操作系统命令复制数据文件时,是根据操作系统块大小进行copy的,也就是说复制一个操作系统块的时候,首先锁定这个块,复制完成以后,解锁这个块,这样这个块在复制前和复制后是一致的。但是对于一个Oracle数据库来说,一个块要分成几次进行复制,有可能在复制一个操作系统数据块的时候,另外一个操作系统数据块被改变了,导致oracle数据块在复制到备份介质以后,前一半是没有改动过的,后一半是改动过的,数据块的状态就出现了不一致的情况,这时候备份也就是无效的,这叫做分离数据块现象。
2、为了修复分离数据块现象,我们在备份某个表空间或者数据文件的的时候,首先发出begin backup命令,通知数据库我要开始开始备份了,在没有发出end backup命令之前,只要是进程修改了被备份的表空间所包含的数据块,oracle就会把该数据块中所包含的所有的数据行的数据生成重做记录,记录到日志文件中。
通过发出begin backup以后,第一次修改数据块中的数据行之前,在联机重做日志文件中记录数据块的修改前的数据,这样在需要恢复数据的时候,发现某个数据块是分离的,就会利用日志文件里的重做记录的数据对整个数据块进行恢复
3、备份表空间中的所有的被修改过的数据块的所有数据行都被保存在了联机重做日志文件中,而不是只记录被修改的数据行的记录,因此在热备份过程中,会发现生成的联机重做日志文件的量比较大,这取决于业务的繁忙程度,例如DML量比较大,那么产生的日志会非常的多
4、发出begin backup命令以后,oracle会对被备份的表空间所对应的数据文件触发文件级别的检查点进程,将内存中属于该表空间的所有脏数据块写入数据文件,检查点结束以后,数据文件头部(第一个和第一个数据块)的检查点SCN和日志序列号都不在变化,直至发出end backup,数据文件头部的SCN和日志序列号才被更新
5、在热备份的过程中,数据文件头部的SCN和日志序列号被冻结,但是数据文件本身还是最新的,和正常一样的更新和使用,DML更新了某个表,这些更新都会被写入到数据文件中去。冻结数据文件头部的SCN号和日志序列号,是为了将来使用热备份进行恢复的时候,能够知道应该从哪里开始应用重做记录,也就是备份的数据文件头部所记录的SCN和日志序列号,定位到日志文件中,从日志文件中找到开始的SCN,向后应用所有的日志文件
6、发出end backup命令以后,所有的数据文件的头部SCN号和日志序列号更新到最新,因为数据文件本身就是最新的。