Oracle的备份与恢复一直是很吸引我的一个地方。一直搞不明白到底是怎么个标准来恢复,怎么来备份。今天就来稍微就这其中的一点名词和过程来写写:
都知道,在创建Oracle的时候,初始默认都会建立三个redo log的文件组。可能大家对这三个log文件组的作用可能不太理解,我自己的理解是这三个log文件组就类似于一个循环,一个组写满了,Oracle就切换到另外的一个组里面去,然后就这么来来去去。大家可能又会问到,那么如果这三个组都满了,怎么办?这个我也不太清楚,据我跟一个DBA的探讨,应该Oracle就不会忘Redo log文件里记录了。但是Oracle也可以通过设置备份策略来避免这种情况的发生。
通常Oracle在提交一个事务,或者是做一个操作的时候,首先将数据读到内存中来,然后做修改。修改完成后,一般的步骤会是先想Redo log文件里写入修改的记录,然后等待一段时间,由Oracle统一将一批修改写入磁盘。
那么怎么来查看当前是哪个一个redo log文件组被使用呢:
- SQL> select * from v$logfile;
- GROUP# STATUS TYPE MEMBER IS_
- ---------- ------- ------- -------------------- ---
- 3 STALE ONLINE D:\ORACLE\DATA\GJSID NO
- \REDO03.LOG
- 2 ONLINE D:\ORACLE\DATA\GJSID NO
- \REDO02.LOG
- 1 ONLINE D:\ORACLE\DATA\GJSID NO
- \REDO01.LOG
- SQL> select * from v$log;
- GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS
- ---------- ---------- ---------- ---------- ---------- --- ----------------
- FIRST_CHANGE# FIRST_TIME
- ------------- --------------
- 1 1 11 52428800 1 NO CURRENT
- 814175 06-3月 -11
- 2 1 9 52428800 1 YES INACTIVE
- 791711 05-3月 -11
- 3 1 10 52428800 1 NO INACTIVE
- 791923 05-3月 -11
可以看到现在系统中总共是有三组redo log文件组,而且当前被激活是是第一个redo log文件组。
接下来可能会涉及到一个概念,SCN - system change number。这个数字是Oracle在内部用来记录变化的唯一的一个标示,事务的提交,各种修改的发生,都会修改到这个SCN。也就是可以这样讲到SCN是Oracle的内部逻辑时钟。那么怎么样子才可以查看到当前的SCN呢:
- SQL> select dbms_flashback.get_system_change_number from dual;
- GET_SYSTEM_CHANGE_NUMBER
- ------------------------
- 815255
通过这样的一条语句就可以看到current SCN是多少,你也可以反复的查看,你就会发现SCN经常在变。
通过上述的语句检查出来的SCN是系统最新的SCN,上面也讲到了,Oracle会统一地将一批数据写入磁盘,可能就会有这样的情况,数据修改在Redo log文件中,还没有及时地反映到磁盘中去,数据库就发生了Crush,这样就意味数据的完整性没有保证,那么Oracle是怎么做到恢复的呢。
这个时候,一个检查点的概念就出来了,checkpoint scn。检查点就相当于Oracle每隔多长时间做了一次写入磁盘的批处理动作一样。
看到了吧,如果在T1时刻Oracle做了一次check,然后在T2时刻数据库崩溃,那么Oracle就只需要做T1 - T2时刻的redo log的恢复就Ok。
那么我是如何知道Oracle是在哪个时刻做了一个check呢:
- SQL> select file#,checkpoint_change#,to_char(checkpoint_time,'yyyy-mm-dd hh24:mm:ss') from v$datafile;
- FILE# CHECKPOINT_CHANGE# TO_CHAR(CHECKPOINT_
- ---------- ------------------ -------------------
- 1 814915 2011-03-06 16:03:55
- 2 814915 2011-03-06 16:03:55
- 3 814915 2011-03-06 16:03:55
- 4 814915 2011-03-06 16:03:55
看到了吧,这个时候,在SCN是814915的时候,Oracle做了一次check。
- SQL> select dbms_flashback.get_system_change_number from dual;
- GET_SYSTEM_CHANGE_NUMBER
- ------------------------
- 816436
而当前最新的Oracle SCN是816436,所以说如果当前Oracle崩溃了,系统需要从814915恢复到816436.
其实我还是有一点不太明白,Oracle难道是只有发生check的时候,才将数据写向磁盘么,还是一直都在写。如果是前者的话,那么这么长间隔的数据修改,只能从redo log里查询么?如果是后者的话,如果数据已经写到了磁盘,Oracle在恢复的时候,会不会造成数据的重复写的情况呢?