查詢Oracle的SCN

kunlunzhiying發表於2017-04-07
        在學習閃回查詢時,其中一種方法就是透過特定的SCN來進行閃回,因此瞭解了一下在Oracle中如何查詢SCN。
1.查詢系統當前SCN兩條命令

SQL> select current_scn from v$database;
CURRENT_SCN
-----------
    1161213
SQL>
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
                 1161245
SQL>

2.資料庫全域性-檢查點 SCN,在控制檔案中。
SQL>
SQL> select dbid,checkpoint_change# from v$database;
      DBID CHECKPOINT_CHANGE#
---------- ------------------
2082231315 1143153
SQL>
3.當前資料檔案SCN。在控制檔案中。即checkpoint scn,表示該資料檔案最近一次執行檢查點操作時的SCN
SQL>
SQL> select name,checkpoint_change# from v$datafile;
NAME CHECKPOINT_CHANGE#
-------------------------------------------------- ------------------
/u01/app/oracle/oradata/HOEGH/system01.dbf 1143153
/u01/app/oracle/oradata/HOEGH/sysaux01.dbf 1143153
/u01/app/oracle/oradata/HOEGH/undotbs01.dbf 1143153
/u01/app/oracle/oradata/HOEGH/users01.dbf 1143153
/u01/app/oracle/oradata/HOEGH/example01.dbf 1143153

5 rows selected.
SQL>

4.查詢資料檔案頭SCN,在資料檔案頭
 
SQL>
SQL> select name,checkpoint_change# from v$datafile_header;
NAME CHECKPOINT_CHANGE#
-------------------------------------------------- ------------------
/u01/app/oracle/oradata/HOEGH/system01.dbf 1143153
/u01/app/oracle/oradata/HOEGH/sysaux01.dbf 1143153
/u01/app/oracle/oradata/HOEGH/undotbs01.dbf 1143153
/u01/app/oracle/oradata/HOEGH/users01.dbf 1143153
/u01/app/oracle/oradata/HOEGH/example01.dbf 1143153

5 rows selected.
SQL>

5.資料檔案結束SCN,在控制檔案中。
LAST_CHANGE#,如果資料庫非正常關閉值為NULL。正常關閉是關閉時的SCN。
例項恢復就是在開啟資料庫時檢查此引數確定是否需要恢復。
資料庫OPEN時LAST_CHANGE#也為NULL,因為不確定SCN多少時關閉。

SQL
>
SQL> select name,last_change# from v$datafile;
NAME LAST_CHANGE#
-------------------------------------------------- ------------
/u01/app/oracle/oradata/HOEGH/system01.dbf
/u01/app/oracle/oradata/HOEGH/sysaux01.dbf
/u01/app/oracle/oradata/HOEGH/undotbs01.dbf
/u01/app/oracle/oradata/HOEGH/users01.dbf
/u01/app/oracle/oradata/HOEGH/example01.dbf

5 rows selected.
SQL>
6.日誌中所含SCN範圍

SQL>
SQL> select GROUP#,sequence#,STATUS,FIRST_CHANGE#,to_char(FIRST_TIME,\'yyyy/mm/dd:hh24:mi:ss\') time from V$log;
    GROUP# SEQUENCE# STATUS FIRST_CHANGE# TIME
---------- ---------- ---------------- ------------- -------------------
         1 17 INACTIVE 1104305 2015/04/05:23:35:22
         2 18 INACTIVE 1110540 2015/04/05:23:35:33
         3 19 INACTIVE 1124594 2015/04/05:23:36:04
         4 20 INACTIVE 1142387 2015/04/08:21:18:16
         5 21 CURRENT 1142429 2015/04/08:21:18:39

SQL>

以上是常用的查詢SCN的方法,下面轉載一篇詳細介紹SCN的文章,介紹的非常詳細。轉載地址:http://czmmiao.iteye.com/blog/1010267

SCN號概述 
SCN是當Oracle資料庫更新後,由DBMS自動維護去累積遞增的一個數字。Oracle資料庫中一共有4種SCN分別為

系統檢查點SCN: 系統檢查點SCN位於控制檔案中,當檢查點程式啟動時(ckpt),Oracle就把系統檢查點的SCN儲存到控制檔案中。該SCN是全域性範圍的,當發生檔案級別的SCN時,例如將表空間置於只讀狀態,則不會更新系統檢查點SCN。  

查詢系統檢查點SCN的命令如下 

SQL> select CHECKPOINT_CHANGE# from v$database;
CHECKPOINT_CHANGE#
------------------
            590694

資料檔案scn:當ckpt程式啟動時,包括全域性範圍的(比如日誌切換)以及檔案級別的檢查點(將表空間置為只讀、begin backup或將某個資料檔案設定為offline等),這時會在控制檔案中記錄的scn。
查詢資料檔案SCN的命令如下 

SQL> alter tablespace users read only;
Tablespace altered.

SQL> select file#,checkpoint_change# from v$datafile;
     FILE# CHECKPOINT_CHANGE#
---------- ------------------
         1             592277
         2             592277
         3             592277
         4             592291
         5             592277


SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
            592277
 
可以看到4號檔案也就是users表空間所屬的檔案scn值和其他檔案不一致,且比系統檢查點的scn要大。
結束scn:每個資料檔案都有一個結束scn,在資料庫的正常執行中,只要資料檔案線上且是可讀寫的,結束scn為null。否則則存在具體的scn值。結束scn也記錄在控制檔案中。

SQL>select TABLESPACE_NAME,STATUS from dba_tablespaces
TABLESPACE_NAME   STATUS
----------------- ---------------------------
SYSTEM            ONLINE
UNDOTBS1          ONLINE
SYSAUX            ONLINE
TEMP              ONLINE
USERS             READ ONLY
EXAMPLE           ONLINE


SQL> select file#,LAST_CHANGE# from  v$datafile;
     FILE# LAST_CHANGE#
---------- ------------
         1
         2
         3
         4       592291
         5
 
可以看到除了users表空間的結束scn不為空,其他資料檔案的結束scn為空。

將資料庫至於mount狀態,由於該狀態下所有的資料檔案都不可寫,故mount狀態下所有的資料檔案都具有結束scn。

SQL> shutdown immediate;
SQL> startup mount;

SQL> select file#,last_change# from v$datafile;
     FILE# LAST_CHANGE#
---------- ------------
         1       592608
         2       592608
         3       592608
         4       592291
         5       592608

資料檔案頭scn:不同於上述的SCN資料檔案開始scn記錄在每個資料檔案中。當發生系統及檔案級別的檢查點後,不僅將這時的SCN號記錄在控制檔案中,同樣也記錄在資料檔案中。

查詢資料檔案頭SCN的命令如下

SQL> select file#,CHECKPOINT_CHANGE# from v$datafile_header;
     FILE# CHECKPOINT_CHANGE#
---------- ------------------
         1             592608
         2             592608
         3             592608
         4             592291
         5             592608
 
SCN的機制

資料庫執行時的SCN

我們先看下oracle事務中的資料變化是如何寫入資料檔案的:

1、 事務開始;

2、 在buffer cache中找到需要的資料塊,如果沒有找到,則從資料檔案中載入buffer cache中;

3、 事務修改buffer cache的資料塊,該資料被標識為“髒資料”,並被寫入log buffer中;

4、 事務提交,LGWR程式將log buffer中的“髒資料”寫入redo log file中;

5、 當發生checkpoint,CKPT程式更新所有資料檔案的檔案頭中的資訊,DBWr程式則負責將Buffer Cache中的髒資料寫入到資料檔案中。

Redo log中的high scn和low scn

Oracle的Redo log會順序紀錄資料庫的各個變化。一組redo log檔案寫滿後,會自動切換到下一組redo log檔案。則上一組redo log的high scn就是下一組redo log的low scn。在current log中high scn為無窮大。 
可透過查詢v$log_history檢視 low scn和 high scn。
SQL> select recid,sequence#,first_change#,next_change# from v$log_history ;              
     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#
---------- ---------- ------------- ------------
         1          1        446075       474154
         2          2        474154       497385
         3          3        497385       516087
         4          4        516087       540659
         5          5        540659       564897
         6          6        564897       564903
         7          7        564903       565320
         8          8        565320       565704
         9          9        565704       565715
        10         10      565715       567343
        11         11      567343       587705
檢視currnet redolog中的high scn
SQL>select vf.member,v.status,v.first_change# from v$logfile vf,v$log v
  2      where vf.group#=v.group#
  3*   and v.status='CURRENT'

MEMBER                                                              STATUS             FIRST_CHANGE#
------------------------------------------------------------    --------------           -------------
/u01/app/oradata/orcl/redo02.log                             CURRENT         587705

SQL>alter system dump logfile ' /u01/app/oradata/orcl/redo02.log';

SQL> show parameter user_dump
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
user_dump_dest                       string      /home/oracle/admin/c001/udump

開啟轉儲出來的檔案,可以看到

DUMP OF REDO FROM FILE '/u01/app/oradata/orcl/redo02.log'
 Opcodes *.*
 RBAs: 0x000000.00000000.0000 thru 0xffffffff.ffffffff.ffff
 SCNs: scn: 0x0000.00000000 thru scn: 0xffff.ffffffff
 Times: creation thru eternity
 FILE HEADER:
        Compatibility Vsn = 169869568=0xa200100
        Db ID=1269936864=0x4bb1b2e0, Db Name='ORCL'
        Activation ID=1269912032=0x4bb151e0
        Control Seq=696=0x2b8, File size=102400=0x19000
        File Number=2, Blksiz=512, File Type=2 LOG
 descrip:"Thread 0001, Seq# 0000000012, SCN 0x00000008f7b9-0xffffffffffff"
 thread: 1 nab: 0x34f6 seq: 0x0000000c hws: 0x9 eot: 1 dis: 0
 resetlogs count: 0x2c3c676f scn: 0x0000.0006ce7b (446075)
 resetlogs terminal rcv count: 0x0 scn: 0x0000.00000000
 prev resetlogs count: 0x2184ef74 scn: 0x0000.00000001 (1)
 prev resetlogs terminal rcv count: 0x0 scn: 0x0000.00000000
 Low  scn: 0x0000.0008f7b9 (587705) 04/20/2011 09:35:56 
 Next scn: 0xffff.ffffffff 01/01/1988 00:00:00 
 Enabled scn: 0x0000.0006ce7b (446075) 02/03/2011 18:29:03
 Thread closed scn: 0x0000.00090ae0 (592608) 04/20/2011 15:29:05
 Disk cksum: 0x30ee Calc cksum: 0x30ee
 Terminal recovery stop scn: 0x0000.00000000
 Terminal recovery  01/01/1988 00:00:00
 Most recent redo scn: 0x0000.00000000
 Largest LWN: 1920 blocks
 End-of-redo stream : No
 Unprotected mode
 Miscellaneous flags: 0x0
 Thread internal enable indicator: thr: 0, seq: 0 scn: 0x0000.00000000

redo log中當前系統的SCN記錄當前最新的資料庫scn值可透過如下命令檢視

SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
                  594373
 
如果需要進行例項恢復,則需要恢復的記錄為587705至594373中redo log中的記錄。

日誌切換或者checkpoint

當日志切換或發生checkpoint(上述第五個步驟)時,從Low SCN到Next SCN之間的所有redo記錄的資料就被DBWn程式寫入資料檔案中,而CKPT程式則將所有資料檔案(無論redo log中的資料是否影響到該資料檔案)的檔案頭上記錄的Start SCN(透過檢視v$datafile_header的欄位checkpoint_change#可以查詢)更新為Next SCN,同時將控制檔案中的System Checkpoint SCN(透過檢視v$database的欄位checkpoint_change#可以查詢)、每個資料檔案對應的Datafile Checkpoint(透過檢視v$datafile的欄位checkpoint_change#可以查詢)也更新為Next SCN。但是,如果該資料檔案所在的表空間被設定為read-only時,資料檔案的Start SCN和控制檔案中Datafile Checkpoint SCN都不會被更新。

心跳 
在Oracle中有一個事件叫Heartbeat,這個詞在很多地方被提及,並且有著不同的含義(比如RAC中),我們這裡要討論的是CKPT的Heartbeat機制。
Oracle透過CKPT程式每3秒將Heartbeat寫入控制檔案,以減少故障時的恢復時間

資料庫正常關閉啟動

資料庫正常關閉時,系統會執行一個完全檢查點動作,並用該檢查點時的SCN號更新上述4個SCN號,這時所有資料檔案的終止SCN號會設定為資料檔案頭的那個啟動SCN(除了離線和只讀的資料檔案)

資料庫重新啟動時,Oracle將資料檔案頭中的啟動SCN與資料檔案檢查點SCN比較,如果這 兩個值匹配,Oracle接下來再比較資料檔案頭中的SCN和控制檔案中資料檔案的終止SCN,如果這個值也匹配,就意味著所有資料塊已經提交,因此資料 庫不需要進行恢復,此時資料庫直接開啟。當所有的資料檔案都開啟之後,線上且可讀寫的資料檔案終止SCN再次被設定為NULL,表示資料檔案已經開啟並能 夠正常使用了。有些表空間是隻讀的,這時控制檔案中的系統檢查點SCN號會不斷增長,而資料檔案SCN號和檔案頭中的啟動SCN(會停止更新直到表空間又 設定為可讀寫),顯然這時系統檢查點SCN號會大於資料檔案SCN和檔案頭啟動SCN。

資料庫非正常關閉 
資料庫非正常關閉 ( 或稱為例項崩潰 ) 時,終止 SCN 不會被設定,依然為 NULL ,這可以透過把資料庫啟動至 mount 狀態查詢出來。 這樣重新啟動時,SMON程式 會執行例項恢復工作,即先執行前滾、回滾操作,再把資料庫開啟。

資料檔案介質故障

出現介質故障時,資料檔案檢查點SCN及系統檢查點SCN比檔案頭啟動SCN大。系統發生介質故障時,資料檔案被以前的備份代替,控制檔案中的資料檔案檢查點SCN肯定比檔案頭中的啟動SCN要大,這樣Oracle就知道要對這個檔案進行介質恢復

控制檔案介質故障

系統檢查點SCN及資料檔案SCN比資料檔案頭啟動SCN小:
在資料庫恢復時,控制檔案可能不是最新的,即把一個較早的控制檔案還原為當前的控制檔案,然後再執行恢復操作,這時控制檔案中的系統檢查點SCN和資料文 件SCN可能比檔案頭的啟動SCN小。這時恢復資料庫要用下面命令:recover database using Backup Controlfile或其他的恢復語句。

備份時的例項崩潰

當執行begin backup時例項崩潰:控制檔案中的資料檔案檢查點SCN號和資料檔案頭部檢查點SCN號相同,但是每個可讀寫的線上資料檔案之間檢查點SCN號不同, 那麼要求介質恢復,例如發出begin backup命令後就會出現這種情況,需要透過end backup命令好才可以開啟資料庫。


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

相關文章