oracle 11g 數據庫恢復技術 ---01 重做日志


redo log

Oracle數據庫中的三大核心文件分別是數據文件data file)、重做日志redo log)和控制文件control file)。數據文件保證了數據庫的持久性,是保存修改結果的地方;重做日志保證了數據庫的可恢復性,是保存修改操作(包括對數據文件、控制文件等各類文件的修改)的地方;控制文件的作用是確定數據數據文件和重做日志文件的路徑、數據庫字符集、數據庫當前的狀態、檢查點信息、保存其他文件頭部的部分信息及提供備份信息資料庫等。

  重做日志可分為在線重做日志(online redo log)和歸檔重做日志(archive redo log),涉及的5個概念

--RBA(redo byte address)重做字節地址

--SCN(system change number)系統變更號

--DBA(相對數據塊地址)

--數據塊版本號(SCN+SEQ)

--檢查點(checkpoint)

1 Redo record重做記錄

  重做日志是數據庫的日記,記錄着每一個對數據庫的更改。日志中所記載的數據稱為重做記錄redo record,是它提供了數據庫具備了恢復能力。

  只要對數據庫做出任何形式的更改,就會在真正執行更改操作之前產生一條重做記錄,該記錄包含了一個或多個操作,記載了數據庫如何從一個狀態改變到另外一個狀態的具體步驟,

往往包含對多個數據塊的修改,也可能包含對控制文件和其他文件的修改。創建表、創建用戶、插入數據、更新、刪除數據,修改表空間屬性、創建表空間、添加數據文件等任何變更都屬於數據塊狀態的更改。

  數據庫狀態的變更與事務兩個概念不同。

 SCN是內核產生的一個數,兩部分6個字節組成。在正常工作的情況下,oracle不停地按照不同的頻率將SCN寫入不同的文件,在數據庫關閉之后不擔心丟失SCN的進度。判斷數據文件是否需要恢復的指標就是SCN

 v$database視圖的信息大部分來自控制文件,current_scn可以得到一個最新的SCN

select current_scn from v$database

union all

select current_scn from v$database;

 

select current_scn from v$database

union all

select dbms_flashback.get_system_change_number from dual;

每個能夠修改數據庫狀態的操作,都會將從內核申請到的SCN標記在該操作對應的重做記錄,這樣兩條重做記錄之間就可以分清在時間順序上其對應的操作,scn在文件中的表示

scn: 0x0000.0012fc0a

不能排除多個重做記錄的SCN一樣的情況,這說明有一個以上的修改操作分配到同樣的SCN,由某些oracle內部操作導致的,所以oracle又創建了SUBSCN,用以標記同一個SCN下的多次變更,該值范圍1~254,比如

scn: 0x0000.0012fc0a subscn:1 ,scn: 0x0000.0012fc0a subscn:2 分別表示同一個SCN的先后兩個操作。

修改完成,SCNSUBSCN會被保存在修改的數據塊的頭部,占7個字節。SUBSCN改稱為SEQ(序列號)。這就是數據塊版本號(SCN+SEQ,經常scn: 0x0000.0012fc0a seq:n形式出現在轉儲文件中。

如此一來,修改操作的SCN就出現在:重做日志和數據文件中。

RBA(重做字節地址),即重做記錄的物理地址,4部分組成:日志線程號、日志序列號、日志文件塊編號和日志文件塊字節偏移量,長度為10個字節。

low cache rba:(0x6a.2650.0) on disk rba:(0x6a.266c.0)

查看

SYS@ orcl >select rowid,empno,job,ename from SCOTT.EMP where empno=7566;
ROWID            EMPNO JOB    ENAME
------------------ ---------- --------- ----------
AAAVUyAAEAAAACVAAD     7566 MANAGER    JONES

ROWIDbase64的形式體現,前6位代表段號(AAAVUy),隨后3位代表數據文件號(AAE),接下來6位代表數據塊編號(AAAACV),最后的三位代表行號(AAD)

變更矢量

--AFN:絕對文件編號,對應v$datafile.file#字段

SYS@ orcl >select name from v$datafile where file#=3;
NAME
--------------------------------------------------------------------------------
/u01/app/oracle/oradata/orcl/undotbs01.dbf

--DBA:相對數據塊地址,包含相對文件編號與數據塊編號,4個字節。

---dbms_utility.data_block_address_file()

--SCNSEQ:數據塊當前的(被修改之前的)的版本號

第一個矢量負責創建事務表,而第二個矢量負責在事務表中創建具體的撤銷數據。

日志緩沖(log buffer)是重做記錄在內存中的臨時保存點,大小由參數

SYS@ orcl >show parameter log_buffer
NAME                     TYPE     VALUE
------------------------------------ ----------- ------------------------------
log_buffer                 integer     6479872

重做記錄進入日志緩沖之后由后台進程LGWR將其寫入在線重做日志,只要符合下面其中一個條件LGWR就會把log buffer中的所有重做記錄推入在線日志中

--1 每隔3

--2 日志緩沖內有1MB的日志記錄

--3 日志緩沖1/3寫滿

--4 執行提交(commit)命令

--5 DBWn進程中將臟數據塊寫入數據文件之前。

2 Online redo log 在線重做日志

在線重做日志是重做記錄在磁盤上的臨時保存點,是數據庫正常打開不可缺少的文件之一,之所以是臨時的,原因是LGWR會不斷的覆蓋在線日志,它的作用是支持實例恢復和介質恢復

Oracle出於管理性的考慮把重做日志分為:在線日志和歸檔日志

在線日志是數據庫啟動時一定要被打開的文件,而歸檔日志則不必,如果在線日志損壞,db將無法啟動,因為允許被LGWR重寫覆蓋,除非手動修改,其數量和大小都不會變化而歸檔日志不管理,則會越來越多,視圖v$log,v$logfile

SQL>select lg.group#,lg.members,lf.member from v$log lg,v$logfile lf
where lg.group#=lf.group#
order by group#; 
1    1    /u01/app/oracle/oradata/orcl/redo01.log
2    1    /u01/app/oracle/oradata/orcl/redo02.log
3    1    /u01/app/oracle/oradata/orcl/redo03.log

這里有3個日志組,一般建議每組至少2在線日志互為鏡像備份,不要把同組的日志放在易單點損壞的存儲上,添加日志組成員

--alter database add logfile member '/u01/app/oracle/oradata/orcl/redo11.log' to group 1;

SYS@ orcl >select group#,sequence#,status from v$log;
    GROUP#  SEQUENCE# STATUS
---------- ---------- ----------------
     1      256 INACTIVE
     2      257 CURRENT ##正在寫入的日志組
     3      255 INACTIVE
觀察日志組的使用情況,
SYS@ orcl >alter system switch logfile;
System altered.
SYS@ orcl >select group#,sequence#,status from v$log;
    GROUP#  SEQUENCE# STATUS
---------- ---------- ----------------
     1      256 INACTIVE
     2      257 ACTIVE
     3      258 CURRENT

3 Checkpoint 檢查點

數據庫中的任何一個更改操作,ddldml會產生兩種不同類型的數據

--重做記錄,其目的是確保數據庫具有可恢復性

--另一種是被修改的數據庫本身(撤銷數據和修改數據),其目的是確保數據庫的持久性

這兩類數據的臨時存儲地點和永久存儲地點均不相同

重做記錄記載了該更改需要修改哪些數據塊及如何更改,重做記錄在日志緩沖區產生由LGWR寫入在線日志,最后在線日志由ARCn歸檔進程備份為歸檔日志。

被修改的數據塊稱為臟塊,產生了臟塊臨時保存區域database buffer cache,這些數據塊根據重做記錄的RBA按順序在一個檢查點的隊列中,由進程DBWn寫入數據文件,數據塊從檢查點中踢出。數據塊內存中的狀態和數據文件中的狀態一致

DBWn進程的頻率低於LGWR,保證重做記錄先於對應的臟數據塊寫入持久層,所以,令同一個更改產生的重做記錄為R、臟數據塊為D,那么,在LGWR沒有把R寫入在線日志的情況下,

oracle是不允許DBWnD先行寫入數據文件的,即便是DBWn首先發起請求,也必須等待LGWR先清空日志緩沖。--即數據更改必須先寫online redo log再寫datafile

這樣數據文件的內存永遠沒有在線日志的內容更新塊,在數據庫打開的情況下,數據文件永遠比在線日志“舊”

為了標識數據文件舊到什么程度,oracle使用了檢查點,檢查點是一系列操作的集合,其最終目的是將檢查點目標寫入數據文件頭部和控制文件,檢查點目標就是某條重做記錄,以其頭部中的RBASCN表示。

參與檢查點的進程主要包括LGWRDBWnCKPT,分為完全檢查點增量檢查點

發起一次完全檢查點主要步驟

--1 在日志緩沖中確定當前的重做記錄,提取RBASCN作為檢查點的目標

--2 LGWR清空log buffer,將重做記錄寫入online redo log

--3 DBWn將檢查點目標(RBASCN)產生的及檢查點目標之前產生的臟數據塊,按RBA的順序寫入數據文件

--4 最后,CKPT進程將檢查點目標(RBASCN)寫入數據文件頭部和控制文件。

這樣,數據文件頭部的檢查點目標(RBASCN)能提供一下兩個重要信息

--1 讀取其中的scnonline redo log中的scn做比較,就可以知道數據文件是否需要恢復,檢查點目標中的scn簡稱檢查點SCN。

--2 如果該數據文件需要恢復,RBA用來表示從哪個日志中那一項重做記錄開始恢復,檢查點目標中的RBA簡稱檢查點RBA.

完全檢查點發生的時機

--1 執行shutdownshutdown normashutdown immediateshutdown transaction命令關閉數據庫

--2 執行alter system checkpoint命令

--3  LGWR切換online redo log,不論是因為日志寫滿還是手工執行alter system switch logfile命令

--4  執行部分表空間維護命令,比如alter tablespace test offine|online|begin backup|end backup|read only| read write,但此類完全檢查點並不完整,DBWn僅將特定表空間內的所有臟數據塊寫回到數據文件而已。

完全檢查點高優先級:shutdown(除shutdown abort外)與alter system checkpoint命令發起的就是高優先級的檢查點,檢查點沒有完成,命令不會返回。

SYS@ orcl >alter system checkpoint;
System altered.
SYS@ orcl >alter system switch logfile;
System altered.
Tue May 21 14:49:02 2019
Thread 1 advanced to log sequence 259 (LGWR switch)
  Current log# 1 seq# 259 mem# 0: /u01/app/oracle/oradata/orcl/redo01.log
  Current log# 1 seq# 259 mem# 1: /u01/app/oracle/oradata/orcl/redo11.log
Tue May 21 14:49:02 2019
Archived Log entry 172 added for thread 1 sequence 258 ID 0x5b6f4ecf dest 1:
查看v$datafile_header字段,可以得到最近一次已經完成的完全檢查點SCN
SYS@ orcl >select file#,checkpoint_change# from v$datafile_header;
     FILE# CHECKPOINT_CHANGE#
---------- ------------------
     1          9249678
     2          9249678
     3          9249678
     4          9249678
     5          9249678
SYS@ orcl >select file#,checkpoint_change# from v$datafile;
     FILE# CHECKPOINT_CHANGE#
---------- ------------------
     1          9249678
     2          9249678
     3          9249678
     4          9249678
     5          9249678

增量檢查點,發起時機由oracle自動控制,也可以修改FAST_START_MTTR_TARGET初始化參數影響它的頻率,一次增量檢查點主要步驟:

--1 首先確定一條重做記錄(不是當前的),提取RBASCN號作為檢查點的目

--2 LGWR情況log buffer,將重做記錄寫入online redo log

--3 DBWn將檢查點目標(RBASCN)產生的及檢查點目標之前的臟數據按RBA順序寫入數據文件

--4 CKPT將檢查點目標(RBASCN)寫入控制文件--注意這里與完全檢查點,這里只寫了控制文件

增量檢查點會在告警日志中寫

Incremental checkpoint up to RBA [ ],current log tail at RBA [ ]

將初始化參數log_checkpoint_to_alerttrue再觀察

增量檢查點的意義

--1 減少發生完全檢查點時DBWn進程的工作負擔

--2 提高實例恢復的速度。

4 實例恢復

實例是一系列oracle內存結構和進程的總稱,這些結構是訪問數據庫各種文件的方法,沒有它們,數據庫將不能被訪問,所謂啟動數據庫就是指啟動實例

當通過shutdown abort除外)關閉數據庫,oracle會先發起一個完全檢查點,此時數據庫不允許任何變更,log buffer被清除,LGWR進程停止,online redo log更新停止,數據庫緩存中的臟數據完全寫入數據文件。

如果實例崩潰(斷點)或者shutdown abort強制關閉數據庫,沒來及完成一次完全檢查點。在下一次啟動數據庫時候,只要控制文件、redo log和數據文件沒有損壞(只是不同步而已),

為了使數據庫能打開,oracle會自動發起稱為實例恢復的操作同步數據文件,會在alert中寫入

Begining crash recover of

...

Completed crash recover at

實例恢復(instance recovery)的定義是在啟動數據庫時發現文件不同步后,自動利用redo log中的重做記錄自動對舊的數據文件進行修復的過程,分前滾回滾

實例恢復的第一步前滾,將數據文件頭部中的檢查點SCN和當前redo log中最新的重做記錄的SCN做對比,得知該數據文件是否為舊的,如果判斷為舊,即不同步,前滾發起

前滾--讀取數據文件頭部檢查點RBA,將RBAredo log文件中找到並作為前滾起點,一直利用完redo log中的最后一條記錄為止。已經提交的變更及沒有提交的變更都寫入數據文件

回滾--需要撤銷數據塊,即便數據庫強制停止時,撤銷數據塊沒有及時寫回數據文件(屬於撤銷表空間),自動前滾也會將他們回復出來

--1 startup命令--手動

--2 參數文件打開,實例啟動

--3 控制文件被打開

--4 校驗數據文件和redo log是否同步(控制文件也參與校驗),結果為否

--5 自動前滾

--6 打開數據庫

--7 自動回滾

牢記實例恢復的一個規定:只能使用在線日志(redo log,並且不要忘記LGWR”喜新厭舊”的品性,以循環覆蓋的方式寫redo log

在線日志redo log三種狀態:current代表lgwr正在寫的日志組,active最近一次完全檢查點 RBA(SCN)小於該日志中最后一個重做記錄的RBA(SCN),inactive指最近一次完全檢查點的RBA(SCN)大於該日志中最后一個重組記錄的RBA(SCN).

只有inactiveredo log是實例恢復需要的,activecurrent都是實例恢復所必需

 如果LGWR的下一個日志狀態時active,那么LGWR進程會掛起,alert日志報checkpoint not complete.oracle會立刻發起一個新的高優先級檢查點,進一步推進BRA(SCN).除非發生介質問題、文件損壞。

如果只是斷點或實例崩潰,在線日志一定和數據文件是連續的。Oracle總能依靠實例恢復能自動回到完整一致的狀態。

 通過v$log.status直接了解到假如現在斷點,實例恢復需要哪些日志

select lg.group#,lg.members,lg.status from v$log lg,v$logfile lf
where lg.group#=lf.group#
order by group#; 

根據結果,應該是日志組1,日志組23實例恢復不需要。

5 歸檔重做日志

介質恢復的角度,在線日志就有可能不行,因為介質恢復應對的是數據文件損壞的情況,一旦數據文件損壞,往往第一步操作是從備份中將損壞的文件還原,

文件頭的檢查點scn也就回到備份的時候,如果超過了redo log中的重做記錄范圍,就無法修復,通過視圖觀察到lgwrredo log的速度。

SYS@ orcl >select group#,sequence#,status,to_char(first_time,'yyyy-mm-dd hh24:mi:ss') first_time from v$log; GROUP#  SEQUENCE# STATUS           FIRST_TIME
---------- ---------- ---------------- -------------------
     1      259 CURRENT           2019-05-21 14:49:02
     2      257 INACTIVE           2019-05-21 10:00:58
     3      258 INACTIVE           2019-05-21 11:16:08

簡單的說,歸檔日志就是redo log的備份,由后台進程ARCnLGWR覆蓋之前將redo log復制而來。在數據庫打開時不會打開,不允許覆蓋,在沒有維護的情況下數量不斷增加,是重做記錄的永久保存點。主要作用是支持介質恢復和rman在線備份

開啟歸檔模式,如何開啟歸檔模式這里不做介紹

SYS@ orcl >select log_mode from v$database;
LOG_MODE
------------
ARCHIVELOG
SYS@ orcl >select group#,sequence#,status,archived from v$log;
    GROUP#  SEQUENCE# STATUS           ARC
---------- ---------- ---------------- ---
     1      259 CURRENT           NO
     2      257 INACTIVE           YES ##已經歸檔
     3      258 INACTIVE           YES ##已經歸檔
--shutdown immediate
--startup mount
--alter database archivelog
--alter database open

歸檔日志保存的路徑由參數log_archive_desc_N和db_recovery_file_dest指定,N最大為31,1~10為本地歸檔,其他為遠程歸檔

SYS@ orcl >show parameter log_archive_dest
NAME                     TYPE     VALUE
------------------------------------ ----------- ------------------------------
log_archive_dest             string
log_archive_dest_1             string     location=/u01/app/oracle/arch
--SQL> alter system set log_archive_dest_1=’location=/u01/app/oracle/arch’;
歸檔文件的格式,該參數一定要包含%t,%s和%r
SYS@ orcl >show parameter log_archive_format
NAME                     TYPE     VALUE
------------------------------------ ----------- ------------------------------
log_archive_format             string     %t_%s_%r.db
select sequence#,first_change#,next_change#,name from v$archived_log;

6 介質恢復

在文件有物理損壞的情況下,將其還原、恢復,最后使數據庫得以正常打開的操作稱為介質恢復。

實例恢復的前提是數據文件、控制文件和在線日志均沒有損壞的情況

比如,system01.dbf文件損壞

 

SQL> startup
ORACLE instance started.
Total System Global Area  784998400 bytes
Fixed Size            2257352 bytes
Variable Size          511708728 bytes
Database Buffers      264241152 bytes
Redo Buffers            6791168 bytes
Database mounted.
ORA-01122: database file 1 failed verification check
ORA-01110: data file 1: '/u01/app/oracle/oradata/orcl/system01.dbf'
ORA-01210: data file header is media corrupt

 

#只能啟動到mount階段,提示需要介質恢復

首先查看所有數據文件的檢查點SCN

SYS@ orcl >select file#,name,checkpoint_change# from v$datafile;

凍結1號文件的頭部,oracle會對1號文件發起完全檢查點,屬於1號文件的臟數據塊將全部寫入磁盤

 

SYS@ orcl >alter tablespace system begin backup;
Tablespace altered.
SYS@ orcl >col name format a50
SYS@ orcl >select file#,name,checkpoint_change# from v$datafile;

     FILE# NAME                           CHECKPOINT_CHANGE#
---------- -------------------------------------------------- ------------------
     1 /u01/app/oracle/oradata/orcl/system01.dbf             9252840
     2 /u01/app/oracle/oradata/orcl/sysaux01.dbf             9249773
     3 /u01/app/oracle/oradata/orcl/undotbs01.dbf             9249773
     4 /u01/app/oracle/oradata/orcl/users01.dbf             9249773
     5 /u01/app/oracle/oradata/orcl/test01.dbf             9249773
然后用os命令備份
[oracle@DSI ~]$ cp /u01/app/oracle/oradata/orcl/system01.dbf /home/oracle/systm01.dbf
SYS@ orcl >alter tablespace system end backup; ##解凍
Tablespace altered.
然后在把剛備份的system01復制原處,此時alter database open就會報錯,因為scn不一致。
SYS@ orcl >shutdown immediate;
[oracle@DSI ~]$ cp /home/oracle/systm01.dbf /u01/app/oracle/oradata/orcl/system01.dbf
SYS@ orcl >startup;
ORACLE instance started.
Total System Global Area  784998400 bytes
Fixed Size            2257352 bytes
Variable Size          511708728 bytes
Database Buffers      264241152 bytes
Redo Buffers            6791168 bytes
Database mounted.
ORA-01113: file 1 needs media recovery
ORA-01110: data file 1: '/u01/app/oracle/oradata/orcl/system01.dbf'
 查看還原1號文件的scn
SYS@ orcl >select file#,change# from v$recover_file;
     FILE#    CHANGE#
---------- ----------
     1    9252840
查看非INACTIVE狀態的redo log的低位SCN
SYS@ orcl >select min(first_change#) from v$log where status !='INACTIVE';
MIN(FIRST_CHANGE#)
------------------
       9249773
還原的scn大於非inactive的redo log的低位scn
查看歸檔最小的scn號
SYS@ orcl >select min(first_change#) from v$archived_log;

MIN(FIRST_CHANGE#)
------------------
       1121577
這里1121577明顯小於9252840,可以恢復
SYS@ orcl >recover automatic datafile 1;
Media recovery complete.
SYS@ orcl >alter database open;
Database altered.
SYS@ orcl >select file#,name,checkpoint_change# from v$datafile;

     FILE# NAME                           CHECKPOINT_CHANGE#
---------- -------------------------------------------------- ------------------
     1 /u01/app/oracle/oradata/orcl/system01.dbf             9253054
     2 /u01/app/oracle/oradata/orcl/sysaux01.dbf             9253054
     3 /u01/app/oracle/oradata/orcl/undotbs01.dbf             9253054
     4 /u01/app/oracle/oradata/orcl/users01.dbf             9253054
     5 /u01/app/oracle/oradata/orcl/test01.dbf             9253054

 

介質恢復的步驟

--1 手動還原,數據文件遭到破壞,導致實例恢復這個流程無法進行,所以第一步是將之前備份的數據文件復制到原位置,完整性沒有問題,但是其頭部的檢查點scnredo log的不連續,實例恢復還是無法進行,此時不能使用alter database open打開

--2 手動恢復,sqlplusrecover命令能夠分析數據文件頭部中的檢查點scnRBA,了解數據文件是否需要恢復、從哪里開始恢復,並且能夠讀取到歸檔日志和redo log中的重做記錄,將變更重做,把數據文件中丟失的變更重新找回。

--3 自動回滾,在執行alter database open打開數據庫后自動執行

介質恢復需要人為干預的只有兩部分:還原操作(restore恢復操作(recover

 

SYS@ orcl >alter system dump logfile '/u01/app/oracle/oradata/orcl/redo01.log' dba min 5 319 dba max 5 400;
System altered.
SYS@ orcl >select value from v$diag_info where name='Default Trace File';
VALUE
-----------------------------------------------------------------
/u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_10017.trc


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM