SCN、Checkpoint、例項恢復介質恢復理解

lusklusklusk發表於2017-09-12
如果LGWR的下一個日誌是ACTIVE,那麼LWGR會掛起,警告日誌會報告"Checkpoint not complete",oracle會發起alter system checkpoint的操作
狀態為ACTIVE的日誌也可能已經是歸檔日誌了,ARCn程式會自動將非CURRENT的線上日誌歸檔

V$LOG.STATUS反應的是完全檢查點的進度,因為alter system switch logfile後還是會發現原來為ACTIVE的日誌還是ACTIVE狀態,但是alter system checkpoint後就一定會把ACTIVE變成INACTIVE(完全檢查點寫入控制檔案和資料檔案頭部,增量檢查點只寫入控制檔案)

V$LOG.STATUS=ACTIVE

Log is active but is not the current log. It is needed for crash recovery. It may be in use for block recovery. It may or may not be archived.
代表最近一次的完全檢查點SCN小於該日誌中最後一條重做記錄的SCN,說明完全檢查點還沒有越過這個線上日誌
V$LOG.STATUS=INACTIVE
Log is no longer needed for instance recovery. It may be in use for media recovery. It may or may not be archived.
代表最近一次的完全檢查點SCN大於該日誌中最後一條重做記錄的SCN,說明完全檢查點已經越過這個線上日誌

v$log.FIRST_CHANGE#:等於上一個online redo的v$log.NEXT_CHANGE#或上一個archive redo log的$archived_log.NEXT_CHANGE#,等於下一個archive redo log的v$archived_log.FIRST_CHANGE#
v$log.NEXT_CHANGE#:Highest change number (SCN) in the log. When STATUS=CURRENT, NEXT_CHANGE# is set to the highest possible SCN, 281474976710655

V$DATABASE displays information about the database from the control file.
V$DATABASE.CHECKPOINT_CHANGE#:Last SCN checkpointed
V$DATABASE.CONTROLFILE_CHANGE#:Last SCN in backup control file; null if the control file is not a backup
V$DATABASE.CURRENT_SCN:Current SCN; null if the database is not currently open. For a standby database, it is the checkpoint SCN of the mounted physical standby database during media recovery and is always less than the last applied SCN tracked in V$RECOVERY_PROGRESS.

V$DATAFILE displays datafile information from the control file.

V$DATAFILE.CHECKPOINT_CHANGE#:SCN at last checkpoint

V$DATAFILE_HEADER displays datafile information from the datafile headers.
V$DATAFILE_HEADER.CHECKPOINT_CHANGE#:Datafile checkpoint change#

控制檔案中儲存的控制檔案SCN是指v$database.CONTROLFILE_CHANGE#
控制檔案中儲存的資料庫SCN(也稱系統檢查點SCN)是指v$database.CHECKPOINT_CHANGE#
控制檔案中儲存的資料檔案SCN是指v$datafile.CHECKPOINT_CHANGE#
控制檔案中儲存的資料檔案結束SCN是指v$datafile.last_change#,open狀態下是null,mount下和資料庫檢查點scn一致
資料檔案中儲存的資料檔案頭SCN是指v$datafile_header.CHECKPOINT_CHANGE#,叫start SCN,也叫啟動SCN。
redo logfile中儲存的SCN:每一個日誌檔案有一個first scn和一個next scn。歸檔日誌中,下一個日誌檔案的first SCN等於上一個日誌檔案的next SCN,線上日誌中,first SCN等於最後一個歸檔日誌的next SCN,而next SCN不論是在open還是mount狀態下都是無窮大

資料檔案SCN會出現不一致現象,因為資料檔案的狀態會出現online和offline或begin backup


v$datafile.checkpoint_change#是控制檔案裡記錄某個資料檔案比如A的SCN值
v$datafile_header.checkpoint_change#是資料檔案比如A記錄自己的SCN值
預設情況下這兩都應該是一樣的。關於兩個checkpoint_change#值的比較:
如果datafile大於datafile_header,那麼就需要recover datafile,說明控制檔案裡記錄的SCN比資料檔案記錄的要新。產生原因:shutdown abort等。
如果datafile小於datafile_header,任何情況下都不可能發生,控制檔案裡的scn不可能比資料檔案


執行alter system switch logfile時,只有V$DATABASE.CONTROLFILE_CHANGE#變大了,其他V$DATABASE.CHECKPOINT_CHANGE#、V$DATAFILE.CHECKPOINT_CHANGE#、V$DATAFILE_HEADER.CHECKPOINT_CHANGE#都沒有變

執行ALTER DATABASE BEGIN BACKUP時,V$DATABASE.CONTROLFILE_CHANGE#、V$DATAFILE.CHECKPOINT_CHANGE#、V$DATAFILE_HEADER.CHECKPOINT_CHANGE#都變大了,只有V$DATABASE.CHECKPOINT_CHANGE#沒變

執行alter tablespace users begin backup時,V$DATABASE.CONTROLFILE_CHANGE#、對應的表空間檔案V$DATAFILE.CHECKPOINT_CHANGE#、對應的表空間檔案V$DATAFILE_HEADER.CHECKPOINT_CHANGE#變大了,$DATABASE.CHECKPOINT_CHANGE#沒變,其他表空間檔案的V$DATAFILE.CHECKPOINT_CHANGE#、$DATAFILE_HEADER.CHECKPOINT_CHANGE#也沒變

執行alter system checkpoint時,則V$DATABASE.CONTROLFILE_CHANGE#、V$DATABASE.CHECKPOINT_CHANGE#、V$DATAFILE.CHECKPOINT_CHANGE#、V$DATAFILE_HEADER.CHECKPOINT_CHANGE#都變


查詢相應SCN的一些語句
select CHECKPOINT_CHANGE#,CONTROLFILE_CHANGE#,CURRENT_SCN from v$database;
select distinct CHECKPOINT_CHANGE#,last_change# from v$datafile; 
select distinct CHECKPOINT_CHANGE# from v$datafile_header; 
select distinct FIRST_CHANGE#,NEXT_CHANGE#,sequence#,first_time from v$archived_log order by first_time desc;
select SEQUENCE#,STATUS,ARCHIVED,FIRST_CHANGE#,NEXT_CHANGE# from v$log

mount狀態下scn不會改變


查詢當前SCN的SQL
一般使用如下
select to_char(dbms_flashback.get_system_change_number) scn from dual
mount狀態執行上述語句會報錯ORA-00904

下面這條查詢語句,每執行一次scn就會增加一次
select CURRENT_SCN from v$database;
mount狀態下執行上述語句結果是0



COMMIT Statement
The COMMIT statement ends the current transaction, making its changes permanent and visible to other users.
COMMIT不會觸發任何的checkpoint,只是觸發lgwr把日誌緩衝資料寫入線上重做日誌並把事務對應的資料塊的最新scn和是否的提交狀態記錄在控制檔案中,但是不會記錄在任何檢視中,V$DATABASE.CURRENT_SCN雖然也來自來自控制檔案,但是記錄當前最新的SCN

database checkpoint
The thread checkpoint that has the lowest SCN. All changes in all enabled redo threads with SCNs before the database checkpoint SCN are guaranteed to have been written to disk.
具有最低SCN的執行緒檢查點。 在資料庫檢查點SCN之前所有啟用的具有SCN的重做執行緒的所有更改都保證已寫入磁碟。

data file checkpoint
A data structure that defines an SCN in the redo thread of a database for a particular data file. Every data file has a checkpoint SCN, which you can view in V$DATAFILE.CHECKPOINT_CHANGE#. All changes with an SCN lower than this SCN are guaranteed to be in the data file.
資料結構,用於定義特定資料檔案的資料庫重做執行緒中的SCN。 每個資料檔案都有一個檢查點SCN,您可以在V$DATAFILE.CHECKPOINT_CHANGE#中檢視。 SCN低於此SCN的所有更改都將保證在資料檔案中。


Overview of Checkpoints
A checkpoint is a crucial mechanism in consistent database shutdowns, instance recovery, and Oracle Database operation generally. The term checkpoint has the following related meanings:
A data structure that indicates the checkpoint position, which is the SCN in the redo stream where instance recovery must begin
The checkpoint position is determined by the oldest dirty buffer in the database buffer cache. The checkpoint position acts as a pointer to the redo stream and is stored in the control file and in each data file header.
The writing of modified database buffers in the database buffer cache to disk
檢查點是一致的資料庫關閉,例項恢復和Oracle資料庫操作的關鍵機制。 檢查點一詞具有以下相關含義:
指示檢查點位置的資料結構,該位置是例項恢復必須開始的重做流中的SCN
檢查點位置由資料庫緩衝區快取中最舊的髒緩衝區確定。 檢查點位置用作指向重做流的指標,儲存在控制檔案和每個資料檔案頭中。
將資料庫緩衝區中的修改後的資料庫緩衝區寫入磁碟


When Oracle Database Initiates Checkpoints
The checkpoint process (CKPT) is responsible for writing checkpoints to the data file headers and control file. Checkpoints occur in a variety of situations. For example, Oracle Database uses the following types of checkpoints:
Thread checkpoints
The database writes to disk all buffers modified by redo in a specific thread before a certain target. The set of thread checkpoints on all instances in a database is a database checkpoint. Thread checkpoints occur in the following situations:
Consistent database shutdown
ALTER SYSTEM CHECKPOINT statement
Online redo log switch
ALTER DATABASE BEGIN BACKUP statement
Tablespace and data file checkpoints
The database writes to disk all buffers modified by redo before a specific target. A tablespace checkpoint is a set of data file checkpoints, one for each data file in the tablespace. These checkpoints occur in a variety of situations, including making a tablespace read-only or taking it offline normal, shrinking a data file, or executing ALTER TABLESPACE BEGIN BACKUP.
檢查點程式(CKPT)負責將檢查點寫入資料檔案標頭檔案和控制檔案。 檢查點發生在各種情況。 例如,Oracle資料庫使用以下型別的檢查點:
執行緒檢查點
資料庫透過在某個目標之前的特定執行緒中重做修改的所有緩衝區寫入磁碟。 資料庫中所有例項上的一組執行緒檢查點是一個資料庫檢查點。 執行緒檢查點在以下情況下發生:
一致的資料庫關機
ALTER SYSTEM CHECKPOINT語句
線上重做日誌切換
ALTER DATABASE BEGIN BACKUP語句
表空間和資料檔案檢查點
資料庫將磁碟上的所有緩衝區寫入特定目標之前透過重做修改。 表空間檢查點是一組資料檔案檢查點,一個用於表空間中的每個資料檔案。 這些檢查點發生在各種情況下,包括使表空間為只讀或正常離線,收縮資料檔案或執行ALTER TABLESPACE BEGIN BACKUP。

oracle規定:保證重做記錄先於對應的髒資料塊寫入持久層
所以,令同一個更改產生的重做記錄為R、髒資料塊為D,那麼lgwr沒有把R寫入線上日誌的情況下,oracle是不允許dbwr把D先行寫入資料檔案的。即便是dbwr首先發出請求,也必須等待lgwr先清空日誌緩衝。這樣,資料檔案中的內容永遠沒有線上日誌的內容更新得快,也就是在資料庫開啟的情況下,資料檔案永遠比線上日誌“舊”,為了標識資料檔案“舊”到什麼程度,oracle便引入了檢查點。

Oracle透過檢查點(Checkpoint)來縮減恢復時間。檢查點只是一個資料庫事件,它存在的根本意義在於減少恢復時間。

完全檢查點步驟
1.在日誌緩衝中確定當前的(也是最新的)重做記錄,提取其RBA和SCN作為檢查點的目標
2.lgwr清空日誌緩衝,將重做記錄寫入線上日誌
3.dbwr程式將檢查點目標(RBA與SCN)產生的及檢查點目標之前產生的髒資料塊,按RBA的順序寫入資料檔案
4.ckpt程式將檢查點目標(RBA與SCN)寫入資料檔案的頭部和控制檔案

這樣資料檔案頭部的檢查點目標(RBA與SCN)便能提供如下資訊
1.讀取資料檔案頭的檢查點scn與線上日誌重做記錄的scn比較,就可以知道該資料檔案是否需要恢復
2.如果該資料檔案需要恢復,資料檔案SCN用來表示從這個SCN開始恢復

完全檢查點發生時機
1.shutdown、shutdown normal、shutdown transactional、shutdown immediate命令
2.alter system checkpoint
3.ALTER DATABASE BEGIN BACKUP
4.執行部分表空間維護命令如alter tablespace tablespacename offline|online|begein backup|end backup|read only|read write

--Online redo log switch時只有V$DATABASE.CONTROLFILE_CHANGE#變大
--ALTER DATABASE BEGIN BACKUP時$DATABASE.CHECKPOINT_CHANGE#沒變,雖然V$DATABASE.CONTROLFILE_CHANGE#、V$DATAFILE.CHECKPOINT_CHANGE#、V$DATAFILE_HEADER.CHECKPOINT_CHANGE#都變大
--alter tablespace users begin backup時,V$DATABASE.CONTROLFILE_CHANGE#、對應的表空間檔案V$DATAFILE.CHECKPOINT_CHANGE#、對應的表空間檔案V$DATAFILE_HEADER.CHECKPOINT_CHANGE#變大,$DATABASE.CHECKPOINT_CHANGE#和?其他表空間對應資料檔案CHECKPOINT_CHANGE#沒變

完全檢查點:個人更願意理解只有V$DATABASE.CHECKPOINT_CHANGE#增加了才算發生了一次完全檢查點。雖然完全檢查點的定義是隻要同時寫入資料檔案頭部和控制檔案就認為是完全檢查點。不過按個人理解其實上面BEGIN BACKUP這樣的操作就不算完全檢查點了。





Incremental checkpoints
An incremental checkpoint is a type of thread checkpoint partly intended to avoid writing large numbers of blocks at online redo log switches. DBWn checks at least every three seconds to determine whether it has work to do. When DBWn writes dirty buffers, it advances the checkpoint position, causing CKPT to write the checkpoint position to the control file, but not to the data file headers.
Other types of checkpoints include instance and media recovery checkpoints and checkpoints when schema objects are dropped or truncated.
增量檢查點是一種型別的執行緒檢查點,部分是為了避免線上重做日誌切換中寫入大量塊。 DBWn至少每三秒檢查一次,以確定是否有工作要做。 當DBWn寫入髒緩衝區時,它會提前檢查點位置,導致CKPT將檢查點位置寫入控制檔案,而不是資料檔案頭
其他型別的檢查點在模式物件被刪除或截斷時包括例項和介質恢復檢查點和檢查點。

增量檢查點
增量檢查點會推動dbwr將部分髒資料塊寫回資料檔案,但是檢查點SCN只是記錄到控制檔案即V$DATABASE.CONTROLFILE_CHANGE#,而沒有寫入資料檔案頭部。例項恢復操作並不會因此而少索取日誌記錄。比如:增量檢查點SCN到200了,意味著資料檔案內資料塊的最高的SCN也已經是200了,但是資料檔案頭部可能還寫著檢查點SCN是100,如果此時例項崩潰,例項恢復的前滾會從scn為100的重做記錄開始,實際上從scn號100~200的重做記錄根本不需要前滾。oracle當然瞭解這一點,所以每次寫完髒資料塊之後,dbwr會新增一條被稱為BWR(block written record,資料塊已寫)的重做記錄,該記錄的變更向量不代表任何變更,只是用來標記哪些資料塊已經被寫回資料檔案了。
因為有BWR這樣的記錄,oracle在進行自動前滾時實際上採用“兩次讀取法”讀取線上日誌,仍然假設資料檔案檢查點scn為100,增量檢查點已經到200了,第一次讀取日誌中scn號100後的所有重做記錄,目的是確定所有的真正的需要恢復的資料塊有哪些,BWR記錄就像一個過濾器,可以大量減少這樣的資料塊。第二次讀取線上日誌時oracle只對真正需要恢復的資料塊,即沒有被BWR記錄點到名的資料塊的重做記錄感興趣。結果是oracle會跳過scn從100到200之間的重做記錄,也就會使前滾相應變快

增量檢查點作用:
1.減少發生完全檢查點是dbwr程式的工作負擔
2.提高例項恢復的速度

增量檢查點發生時機
1.oracle自動控制(當三個引數都不設定或三個引數都設定不當時FAST_START_MTTR_TARGET、LOG_CHECKPOINT_TIMEOUT、LOG_CHECKPOINT_INTERVAL)
2.三個引數取最嚴厲的那個(FAST_START_MTTR_TARGET、LOG_CHECKPOINT_TIMEOUT、LOG_CHECKPOINT_INTERVAL)
3.lgwr切換線上日誌
--alter system flush buffer_cache不會引發增加檢查點

因為lgwr切換線上日誌產生增量檢查點,說明完全檢查點(資料檔案頭部scn)還沒有越過active的線上日誌,但是增量檢查點(控制檔案scn)已經越過了active的線上日誌可能已經在current的線上日誌了,因為recover時使用兩次讀取法,先讀完全檢查點再去增量檢查點,所有recover的時候還是需要active的線上日誌和current的線上日誌,也就是說,current線上日誌丟失時,如果還有active的線上日誌,不能只恢復到active的線上日誌,還需要current的日誌,因為增量檢查點可能已經在current的日誌。


增量檢查點的三個引數
FAST_START_MTTR_TARGET預設為0,LOG_CHECKPOINT_INTERVAL預設為0,LOG_CHECKPOINT_TIMEOUT預設為1800

FAST_START_MTTR_TARGET enables you to specify the number of seconds the database takes to perform crash recovery of a single instance. When specified,FAST_START_MTTR_TARGET is overridden by LOG_CHECKPOINT_INTERVAL.
當設定了LOG_CHECKPOINT_INTERVAL時,LOG_CHECKPOINT_INTERVAL的設定會覆蓋FAST_START_MTTR_TARGET的設定,而不是說11G已經取消了FAST_START_MTTR_TARGET這個引數的功能。

LOG_CHECKPOINT_INTERVAL specifies the frequency of checkpoints in terms of the number of redo log file blocks that can exist between an incremental checkpoint and the last block written to the redo log. This number refers to physical operating system blocks, not database blocks 
這裡指的blocks是OS的block,而不是DATABASE的block
Regardless of this value, a checkpoint always occurs when switching from one online redo log file to another. Therefore, if the value exceeds the actual redo log file size,checkpoints occur only when switching logs. Checkpoint frequency is one of the factors that influence the time required for the database to recover from an unexpected failure
當LOG_CHECKPOINT_INTERVAL值大於redo log file size時,增量檢查點發生情況就是線上日誌切換取代LOG_CHECKPOINT_INTERVAL
Specifying a value of 0 (zero) for LOG_CHECKPOINT_INTERVAL has the same effect as setting the parameter to infinity and causes the parameter to be ignored. Only nonzero values of this parameter are considered meaningful.
LOG_CHECKPOINT_INTERVAL為0時,LOG_CHECKPOINT_INTERVAL這個引數就不起作用了
Recovery I/O can also be limited by setting the LOG_CHECKPOINT_TIMEOUT parameter or by the size specified for the smallest redo log.
LOG_CHECKPOINT_TIMEOUT和LOG_CHECKPOINT_INTERVAL都生效,但是取兩者更嚴厲的那個


LOG_CHECKPOINT_TIMEOUT specifies (in seconds) the amount of time that has passed since the incremental checkpoint at the position where the last write to the redo log(sometimes called the tail of the log) occurred. This parameter also signifies that no buffer will remain dirty (in the cache) for more than integer seconds.
Specifying a value of 0 for the timeout disables time-based checkpoints. Hence, setting the value to 0 is not recommended unless FAST_START_MTTR_TARGET is set
不建議設定LOG_CHECKPOINT_TIMEOUT為0,除非你設定了FAST_START_MTTR_TARGET
FAST_START_MTTR_TARGET、LOG_CHECKPOINT_INTERVAL為0時,LOG_CHECKPOINT_TIMEOUT也生效的



例項恢復的2中情況:
1、增量檢查點SCN和線上日誌中的SCN進行對比,如果大於線上日誌的first_change#,說明和線上日誌接上了,可以例項恢復
因為logfile switch就會發生一次增量檢查點,所以歸檔日誌總是落後例項的增量檢查點,狀態為ACTIVE的日誌也可能已經是歸檔日誌了,所以例項恢復永遠是使用current的線上日誌
2、在mount情況下,$datafile.last_change#為空則必須要例項恢復,mount下$datafile.last_change#為空的情況有兩種
2.1、shutdown abort
2.2、控制是恢復過來的
資料庫OPEN狀態下v$datafile.last_change#的SCN號始終為NULL,而當資料庫正常關閉時,會進行完全檢查點,並將檢查點SCN號更新到該欄位,
所以可以在mount狀態透過v
$datafile.last_change#的SCN號是否為null來判斷是不是需要例項恢復。而崩潰時,Oracle還來不及更新該欄位,則該欄位仍然為NULL。當SMON程式發現該欄位為空時,就知道例項在上次沒有正常關閉,於是由SMON程式就開始進行例項恢復了。SMON程式進行例項恢復時,會從控制檔案中獲得檢查點位置。於是,SMON程式到聯機日誌檔案中,找到該檢查點位置,然後從該檢查點位置開始往下,應用所有的重做條目,從而在buffer cache裡又恢復了例項崩潰那個時間點的狀態。這個過程叫做前滾,前滾完成後,buffer cache裡既有崩潰時已經提交還沒有寫入資料檔案的髒資料塊,也還有事務被突然終止,而導致的既沒有提交又沒有回滾的事務所弄髒的資料塊,這類髒資料塊分兩種,一種是還在buffer cache中,一種是已經被dbwr寫入了磁碟檔案。前滾一旦完畢,SMON程式立即開啟資料庫。但是,這時的資料庫中還含有那些既沒有提交又沒有回滾的髒塊,這種髒塊是不能存在於資料庫中的,因為它們並沒有被提交,必須被回滾。開啟資料庫以後,SMON程式會在後臺進行回滾。



介質恢復的情況:
各個資料檔案頭部檢查點scn不一致,增加檢查點的SCN遠遠小於線上日誌的first_change#,說明和線上日誌接不上,需要介質恢復,需要用到歸檔日誌進行recover(更嚴重的情況是還可能需要restore資料檔案並使用歸檔日誌recover)



RAMN經常遇到的1號檔案system太新的問題
如下三者都是說file 1太新了,file 1需要更多的恢復
ORA-01194: file 1 needs more recovery to be consistent 
ORA-01113: file 1 needs media recovery 
RMAN-06556: datafile 1 must be restored from backup older than scn 919248820
datafile 1的scn大於919248820,也就是datafile 1太新了,不夠舊不夠老
比如正常關機後,startup mount狀態,
sql直接recover database會報錯ORA-00264: no recovery required
rman直接recover database until sequence到前面幾個archivelog就會報RMAN-06556

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30126024/viewspace-2144880/,如需轉載,請註明出處,否則將追究法律責任。

相關文章