學習什麼是SCN

bitifi發表於2017-02-10


--只能算半原創吧,理論主要來自ITPUB論壇的“聽海日誌”,自己做的實驗來進行理解和驗證

一、            什麼是SCN
Concepts中是這樣描述SCN的:

A system change number (SCN) is alogical, internal timestamp used by Oracle Database. SCNs order events thatoccur within the database, which is necessary to satisfy the ACID properties ofa transaction. Oracle Database uses SCNs to mark the SCN before which allchanges are known to be on disk so that recovery avoids applying unnecessaryredo. The database also uses SCNs to mark the point at which no redo exists fora set of data so that recovery can stop.

怎麼理解這個“SCN(系統變更號)是供Oracle資料庫使用的一個邏輯的、內部的時間戳”呢?要理解這個先需要理解Oracle中的事務(Transaction)和資料一致性(Data Consistency)的概念。

先說說資料一致性的概念。資料一致性指的是資料的可用性。比如說管理一個財務的系統,需要從A賬戶將100元轉入到B賬戶,正常的操作是從A賬戶減去100元,然後給B賬戶加上100元,如果這兩步操作都正常完成了,那我們可以說完成轉賬操作之後的資料是一致可用的;但是如果在操作的過程中出了問題,A賬戶的100元給減掉了,但是B賬戶卻沒有加上100元,這樣的情況下產生的結果資料就有問題了,因為部分操作的失敗導致了資料的不一致而不可用,在實際中肯定是要避免這種讓資料不一致的情況發生的。在Oracle資料庫中,保證資料一致性的方法就是事務。

事務是一個邏輯的、原子性的作業單元,通常由一個或者是多個SQL組成,一個事務裡面的所有SQL操作要麼全部失敗回滾(Rollback),要麼就是全部成功提交(Commit)。就像上面轉賬的例子,為保證資料的一致性,就需要將轉賬的兩步操作放在一個事務裡面,這樣不管哪個操作失敗了,都需要將所有已進行的操作回滾,以保證資料的可用性。進行事務管理是資料庫區別於別的檔案系統的一個最主要的特徵,在資料庫中事務最主要的作用就是保證了資料的一致性,每次事務的提交都是將資料庫從一種一致性的狀態帶入到另外一種一致性的狀態中,SCN就是用來對資料庫的每個一致狀態進行標記的,每當資料庫進入到一個新的一致的狀態,SCN就會加1,也就是每個提交操作之後,SCN都會增加。也許你會想為什麼不直接記錄事務提交時候的時間戳呢?這裡面主要是涉及了兩個問題,一個是時間戳記錄的精度有限,再一個就是在分散式系統中記錄時間戳會存在系統時鐘同步的問題,詳細的討論可以檢視Ordering Events in Oracle。

SCN在資料庫中是一個單一的不斷的隨著資料庫一致性狀態的改變而自增的序列。正如一個時間戳代表著時間裡面的某一個固定的時刻點一樣,每一個SCN值也代表著資料庫在執行當中的一個一致性的點,大的SCN值所對應的事務總是比小SCN值的事務發生的更晚。因此把SCN說成是Oracle資料庫的邏輯時間戳是很恰當的。

二、            SCN概述 

SCN是當Oracle資料庫更新後,由DBMS去自動維護累積遞增的一個數字。通常看文章的時候能看到各種型別的SCN,但是嚴格來說SCN是沒有分類的,之所以會有不同型別的SCN並不是說這些SCN的概念不一樣,而是說不同分類的SCN代表的意義不一樣,不管什麼時候SCN所指代的都是資料庫的某個一致性的狀態。就像我們給一天中的某個時間點定義上班時間、另外的某個時間點定義成下班時間一樣,資料庫Checkpoint發生點的SCN被稱為Checkpoint SCN,僅此而已。Oracle資料庫中一共有4種SCN分別為:

?系統檢查點SCN (System Checkpoint SCN)

?檔案檢查點SCN (Datafile Checkpoint SCN)

?結束SCN (Stop SCN)

?資料檔案頭SCN (Start SCN)

前面3個SCN存在於控制檔案中,最後一種則存在於資料檔案的檔案頭中。

在Oracle中用來標識資料庫的每一次改動,及其先後順序,SCN的最大值是0xffff.ffffffff。

在控制檔案中,System Checkpoint SCN是針對整個資料庫全域性的,因而只存在一個Datafile Checkpoint SCN和Stop SCN是針對每個資料檔案的,因而一個資料檔案就對應在控制檔案中存在一份Datafile Checkpoint SCN和Stop SCN。在資料庫正常執行期間,Stop SCN(透過檢視v$datafile的欄位last_change#可以查詢)是一個無窮大的數字或者NULL。

 

1.        系統檢查點SCN(System Checkpoint SCN)- 存於控制檔案

系統檢查點SCN位於控制檔案中,當檢查點程式啟動時(ckpt),Oracle就把系統檢查點的SCN儲存到控制檔案中。該SCN是全域性範圍的(比如日誌切換),當發生檔案級別的SCN時,例如將表空間置為只讀、begin backup或將某個資料檔案設定為offline等,則不會更新系統檢查點SCN。

select checkpoint_change# from v$database;

SYS@PROD>select trim(checkpoint_change#) cc# from v$database;

 

CC#

------

714857

 

2.        檔案檢查點SCN(Datafile Checkpoint SCN)- 存於控制檔案

 

SYS@PROD>alter tablespace tbs_tommie offline;

 

Tablespace altered.

 

SYS@PROD>select trim(file#) f#,name,trim(checkpoint_change#) cc#, trim(last_change#) lc# from v$datafile;

 

F NAME                                                CC#    LC#

- --------------------------------------------------- ------ ------

1 /u01/app/oracle/oradata/PROD/disk1/system001.dbf    714857

2 /u01/app/oracle/oradata/PROD/disk1/undotbs01.dbf    714857

3 /u01/app/oracle/oradata/PROD/disk1/sysaux01.dbf     714857

4 /u01/app/oracle/oradata/PROD/disk1/example1.dbf     714857

5 /u01/app/oracle/oradata/PROD/disk1/indx1.dbf        714857

6 /u01/app/oracle/oradata/PROD/disk1/tools1.dbf       714857

7 /u01/app/oracle/oradata/PROD/disk1/users1.dbf       714857

8 /u01/app/oracle/oradata/PROD/disk1/oltp1.dbf        714857

9 /u01/app/oracle/oradata/PROD/disk3/tbs_tommie01.dbf 715270 715270

 

9 rows selected.

 

SYS@PROD>alter tablespace tbs_tommie online;

 

Tablespace altered.

 

SYS@PROD>select trim(file#) f#,name,trim(checkpoint_change#) cc#, trim(last_change#) lc# from v$datafile;

 

F NAME                                                CC#    LC#

- --------------------------------------------------- ------ ------

1 /u01/app/oracle/oradata/PROD/disk1/system001.dbf    714857

2 /u01/app/oracle/oradata/PROD/disk1/undotbs01.dbf    714857

3 /u01/app/oracle/oradata/PROD/disk1/sysaux01.dbf     714857

4 /u01/app/oracle/oradata/PROD/disk1/example1.dbf     714857

5 /u01/app/oracle/oradata/PROD/disk1/indx1.dbf        714857

6 /u01/app/oracle/oradata/PROD/disk1/tools1.dbf       714857

7 /u01/app/oracle/oradata/PROD/disk1/users1.dbf       714857

8 /u01/app/oracle/oradata/PROD/disk1/oltp1.dbf        714857

9 /u01/app/oracle/oradata/PROD/disk3/tbs_tommie01.dbf 715288

 

9 rows selected.

 

可以看到9號檔案也就是tbs_tommie表空間所屬的檔案SCN值和其他檔案不一致,且比系統檢查點的SCN要大(因為這個資料檔案最後被操作,其他資料檔案沒有變動)。

 

3.        結束SCN(Stop SCN)- 存於控制檔案

見二中的表空間tbs_tommie的資料檔案的last_change#,offline時有值,online後又為NULL。

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

SYS@PROD>shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.

SYS@PROD>startup mount

ORACLE instance started.

 

Total System Global Area  314572800 bytes

Fixed Size                  1219184 bytes

Variable Size              75498896 bytes

Database Buffers          234881024 bytes

Redo Buffers                2973696 bytes

Database mounted.

SYS@PROD>select trim(file#) f#,name,trim(checkpoint_change#) cc#, trim(last_change#) lc# from v$datafile;

 

F NAME                                                CC#    LC#

- --------------------------------------------------- ------ ------

1 /u01/app/oracle/oradata/PROD/disk1/system001.dbf    715634 715634

2 /u01/app/oracle/oradata/PROD/disk1/undotbs01.dbf    715634 715634

3 /u01/app/oracle/oradata/PROD/disk1/sysaux01.dbf     715634 715634

4 /u01/app/oracle/oradata/PROD/disk1/example1.dbf     715634 715634

5 /u01/app/oracle/oradata/PROD/disk1/indx1.dbf        715634 715634

6 /u01/app/oracle/oradata/PROD/disk1/tools1.dbf       715634 715634

7 /u01/app/oracle/oradata/PROD/disk1/users1.dbf       715634 715634

8 /u01/app/oracle/oradata/PROD/disk1/oltp1.dbf        715634 715634

9 /u01/app/oracle/oradata/PROD/disk3/tbs_tommie01.dbf 715634 715634

 

9 rows selected.

 

SYS@PROD>select trim(checkpoint_change#) from v$database;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

715634

 

因資料庫先做了shutdown immediate,屬正常關閉,因此checkpoint_change#=last_change#,即System Checkpoint SCN=Datafile Checkpoint SCN=Stop SCN

 

繼續開啟資料庫再看

SYS@PROD>alter database open;

 

Database altered.

 

SYS@PROD>select trim(checkpoint_change#) cc# from v$database;

 

CC#

------

715635

 

SYS@PROD>select trim(file#) f#,name,trim(checkpoint_change#) cc#, trim(last_change#) lc# from v$datafile;

 

F NAME                                                CC#    LC#

- --------------------------------------------------- ------ ------

1 /u01/app/oracle/oradata/PROD/disk1/system001.dbf    715635

2 /u01/app/oracle/oradata/PROD/disk1/undotbs01.dbf    715635

3 /u01/app/oracle/oradata/PROD/disk1/sysaux01.dbf     715635

4 /u01/app/oracle/oradata/PROD/disk1/example1.dbf     715635

5 /u01/app/oracle/oradata/PROD/disk1/indx1.dbf        715635

6 /u01/app/oracle/oradata/PROD/disk1/tools1.dbf       715635

7 /u01/app/oracle/oradata/PROD/disk1/users1.dbf       715635

8 /u01/app/oracle/oradata/PROD/disk1/oltp1.dbf        715635

9 /u01/app/oracle/oradata/PROD/disk3/tbs_tommie01.dbf 715635

 

9 rows selected.

 

同樣資料庫保持了一致性,即System Checkpoint SCN=Datafile Checkpoint SCN,Stop SCN=NULL。

 

4.        資料檔案頭SCN(Start SCN)- 存於資料檔案的檔案頭

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

sys@ORCL>select file#,CHECKPOINT_CHANGE# from v$datafile_header;

 

SYS@PROD>select trim(file#) f#, trim(checkpoint_change#) cc# from v$datafile_header;

 

F CC#

- ------

1 715635

2 715635

3 715635

4 715635

5 715635

6 715635

7 715635

8 715635

9 715635

 

9 rows selected.

 

此時Start SCN=System Checkpoint SCN=Datafile Checkpoint SCN

 

三、            SCN相關概念

1.        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:

 

SYS@PROD>select recid,sequence#,first_change#,next_change# from v$log_history;

 

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

---------- ---------- ------------- ------------

         1         36        597766       598183

         2          1        598449       638186

         3          2        638186       638842

         4          3        638842       638854

         5          4        638854       638937

         6          5        638937       638948

         7          6        638948       639692

         8          7        639692       639694

         9          8        639694       639697

        10          9        639697       639699

        11         10        639699       639702

 

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

---------- ---------- ------------- ------------

        12         11        639702       639970

        13         12        639970       639972

        14         13        639972       639975

        15         14        639975       639977

        16         15        639977       639979

        17         16        639979       641997

        18         17        641997       644653

        19         18        644653       644655

        20         19        644655       644658

        21          1        644659       648896

        22          2        648896       648898

 

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

---------- ---------- ------------- ------------

        23          3        648898       648902

        24          4        648902       648904

        25          1        648905       669544

        26          2        669544       670151

        27          3        670151       670186

        28          4        670186       673454

        29          5        673454       673459

        30          6        673459       711108

        31          7        711108       714855

        32          8        714855       714857

 

32 rows selected.

 

2.        檢視currnet redolog中的high SCN

SYS@PROD>select vf.member, v.status, v.first_change# from v$logfile vf, v$log v where vf.group#=v.group# and v.status='CURRENT';

 

MEMBER

--------------------------------------------------------------------------------

STATUS                           FIRST_CHANGE#

-------------------------------- -------------

/u01/app/oracle/oradata/PROD/disk1/redo301.log

CURRENT                                 714857

 

/u01/app/oracle/oradata/PROD/disk2/redo302.log

CURRENT                                 714857

 

/u01/app/oracle/oradata/PROD/disk3/redo303.log

CURRENT                                 714857

 

 

MEMBER

--------------------------------------------------------------------------------

STATUS                           FIRST_CHANGE#

-------------------------------- -------------

/u01/app/oracle/oradata/PROD/disk4/redo304.log

CURRENT                                 714857

 

此時可以和一中的記錄進行對比,一里的最後一條記錄recid=32,其last_change#=當前日誌組的first_change#。

再看如下:

SYS@PROD>alter system dump logfile '/u01/app/oracle/oradata/PROD/disk1/redo301.log';

 

System altered.

 

SYS@PROD>show parameter user_dump;

 

NAME                                 TYPE

------------------------------------ ----------------------

VALUE

------------------------------

user_dump_dest                       string

/u01/app/oracle/admin/PROD/udump

 

開啟轉儲的trace檔案:

-rw-r-----  1 oracle oinstall 3835232  1月 28 11:36 prod_ora_12847.trc

[oracle@odd-oelr4u8 udump]$ date

二  1月 28 11:38:00 CST 2014

[oracle@odd-oelr4u8 udump]$ pwd

/u01/app/oracle/admin/PROD/udump

[oracle@odd-oelr4u8 udump]$ vi prod_ora_12847.trc

Dump file /u01/app/oracle/admin/PROD/udump/prod_ora_12847.trc

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production

With the Partitioning, Oracle Label Security, OLAP and Data Mining options

ORACLE_HOME = /u01/app/oracle/product/10.2.0/db_1

System name:    Linux

Node name:      odd-oelr4u8

Release:        2.6.9-89.0.0.0.1.ELsmp

Version:        #1 SMP Tue May 19 04:23:49 EDT 2009

Machine:        i686

Instance name: PROD

Redo thread mounted by this instance: 1

Oracle process number: 26

Unix process pid: 12847, image: oracle@odd-oelr4u8 (TNS V1-V3)

 

*** 2014-01-28 11:25:37.360

*** SERVICE NAME:(SYS$USERS) 2014-01-28 11:25:37.360

*** SESSION ID:(289.3) 2014-01-28 11:25:37.360

tkcrrsarc: (WARN) Failed to find ARCH for message (message:0x1)

tkcrrpa: (WARN) Failed initial attempt to send ARCH message (message:0x1)

*** 2014-01-28 11:36:55.032

 

DUMP OF REDO FROM FILE '/u01/app/oracle/oradata/PROD/disk1/redo301.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=248672105=0xed26f69, Db Name='PROD'

        Activation ID=249629221=0xee10a25

        Control Seq=2332=0x91c, File size=204800=0x32000

        File Number=3, Blksiz=512, File Type=2 LOG

 descrip:"Thread 0001, Seq# 0000000009, SCN 0x0000000ae869-0xffffffffffff"

 thread: 1 nab: 0xffffffff seq: 0x00000009 hws: 0x4 eot: 1 dis: 0

 resetlogs count: 0x31ef36d5 scn: 0x0000.0009e6c9 (648905)

 resetlogs terminal rcv count: 0x0 scn: 0x0000.00000000

 prev resetlogs count: 0x31ef23a6 scn: 0x0000.0009d633 (644659)

 prev resetlogs terminal rcv count: 0x0 scn: 0x0000.00000000

 Low  scn: 0x0000.000ae869 (714857) 01/28/2014 11:05:48 -- 這裡對應current log的first_change#

 Next scn: 0xffff.ffffffff 01/01/1988 00:00:00

 Enabled scn: 0x0000.0009e6c9 (648905) 01/25/2014 07:18:45

 Thread closed scn: 0x0000.000aeb72 (715634) 01/28/2014 11:22:29

 Disk cksum: 0xe808 Calc cksum: 0xe808

 Terminal recovery stop scn: 0x0000.00000000

 Terminal recovery  01/01/1988 00:00:00

 Most recent redo scn: 0x0000.00000000

 Largest LWN: 0 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值可透過如下命令檢視:

SYS@PROD>select dbms_flashback.get_system_change_number from dual;

 

GET_SYSTEM_CHANGE_NUMBER

------------------------

                  716088

 

 

如果需要進行例項恢復,則需恢復的記錄為714857至716088中redo log中的記錄。

 

且get_system_change_number一直在變化:

SYS@PROD>select dbms_flashback.get_system_change_number from dual;

 

GET_SYSTEM_CHANGE_NUMBER

------------------------

                  716264

 

SYS@PROD>select dbms_flashback.get_system_change_number from dual;

 

GET_SYSTEM_CHANGE_NUMBER

------------------------

                  716265

 

原因在於:there are things in the background going on -- AQ, SMON, Job queues -- maybe

even other users.  The "idle" database is actually very active.

 

SYS@PROD>select trim(checkpoint_change#) from v$database;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

715635

基本不變

那麼這兩種方法取出的值有什麼區別呢?GET_SYSTEM_CHANGE_NUMBER又與哪些值有聯絡呢?和Datafile Checkpoint SCN還有Stop SCN有什麼聯絡呢?

3.        日誌切換或發生Checkpoint

當日志切換或發生checkpoint時,從Low SCN(first_change#)到High SCN(next_change#)之間的所有redo記錄的資料就被DBWn程式寫入資料檔案中,如下查詢:SYS@PROD>select recid,sequence#,first_change#,next_change# from v$log_history;

 

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

---------- ---------- ------------- ------------

         1         36        597766       598183

         2          1        598449       638186

         3          2        638186       638842

         4          3        638842       638854

         5          4        638854       638937

         6          5        638937       638948

         7          6        638948       639692

         8          7        639692       639694

         9          8        639694       639697

        10          9        639697       639699

        11         10        639699       639702

 

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

---------- ---------- ------------- ------------

        12         11        639702       639970

        13         12        639970       639972

        14         13        639972       639975

        15         14        639975       639977

        16         15        639977       639979

        17         16        639979       641997

        18         17        641997       644653

        19         18        644653       644655

        20         19        644655       644658

        21          1        644659       648896

        22          2        648896       648898

 

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

---------- ---------- ------------- ------------

        23          3        648898       648902

        24          4        648902       648904

        25          1        648905       669544

        26          2        669544       670151

        27          3        670151       670186

        28          4        670186       673454

        29          5        673454       673459

        30          6        673459       711108

        31          7        711108       714855

        32          8        714855       714857

 

32 rows selected.而CKPT程式則將所有資料檔案(無論redo log中的資料是否影響到該資料檔案)的檔案頭上記錄的Start SCN(透過檢視v$datafile_header的欄位checkpoint_change#可以查詢SYS@PROD>select trim(checkpoint_change#) from v$datafile_header;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

715635

715635

715635

715635

715635

715635

715635

715635

715635

 

9 rows selected.)更新為High SCN,同時將控制檔案中的System Checkpoint SCN(透過檢視v$database的欄位checkpoint_change#可以查詢SYS@PROD>select trim(checkpoint_change#) from v$database;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

715635)、每個資料檔案對應的DatafileCheckpoint(透過檢視v$datafile的欄位checkpoint_change#可以查詢SYS@PROD>select trim(checkpoint_change#) from v$datafile;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

715635

715635

715635

715635

715635

715635

715635

715635

715635

 

9 rows selected.)也更新為High SCN。但是,如果該資料檔案所在的表空間被設定為read-only時,資料檔案的Start SCN和控制檔案中DatafileCheckpoint SCN都不會被更新。

例子:

SYS@PROD>alter tablespace tbs_tommie read only;

 

Tablespace altered.

 

SYS@PROD>select trim(checkpoint_change#) from v$database;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

715635

 

SYS@PROD>select trim(checkpoint_change#) from v$datafile;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

715635

715635

715635

715635

715635

715635

715635

715635

717444

 

9 rows selected.

然後我們做一個日誌切換,再查詢看一下變化:

日誌切換前:

SYS@PROD>select recid,sequence#,first_change#,next_change# from v$log_history;

 

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

---------- ---------- ------------- ------------

         1         36        597766       598183

         2          1        598449       638186

         3          2        638186       638842

         4          3        638842       638854

         5          4        638854       638937

         6          5        638937       638948

         7          6        638948       639692

         8          7        639692       639694

         9          8        639694       639697

        10          9        639697       639699

        11         10        639699       639702

 

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

---------- ---------- ------------- ------------

        12         11        639702       639970

        13         12        639970       639972

        14         13        639972       639975

        15         14        639975       639977

        16         15        639977       639979

        17         16        639979       641997

        18         17        641997       644653

        19         18        644653       644655

        20         19        644655       644658

        21          1        644659       648896

        22          2        648896       648898

 

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

---------- ---------- ------------- ------------

        23          3        648898       648902

        24          4        648902       648904

        25          1        648905       669544

        26          2        669544       670151

        27          3        670151       670186

        28          4        670186       673454

        29          5        673454       673459

        30          6        673459       711108

        31          7        711108       714855

        32          8        714855       714857

 

32 rows selected.

--日誌切換

SYS@PROD>alter system switch logfile;

 

System altered.

--日誌切換

SYS@PROD>alter system switch logfile;

 

System altered.

--再查詢聯機日誌記錄歷史發現增加了兩條記錄

SYS@PROD>select recid,sequence#,first_change#,next_change# from v$log_history;

 

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

---------- ---------- ------------- ------------

         1         36        597766       598183

         2          1        598449       638186

         3          2        638186       638842

         4          3        638842       638854

         5          4        638854       638937

         6          5        638937       638948

         7          6        638948       639692

         8          7        639692       639694

         9          8        639694       639697

        10          9        639697       639699

        11         10        639699       639702

 

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

---------- ---------- ------------- ------------

        12         11        639702       639970

        13         12        639970       639972

        14         13        639972       639975

        15         14        639975       639977

        16         15        639977       639979

        17         16        639979       641997

        18         17        641997       644653

        19         18        644653       644655

        20         19        644655       644658

        21          1        644659       648896

        22          2        648896       648898

 

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

---------- ---------- ------------- ------------

        23          3        648898       648902

        24          4        648902       648904

        25          1        648905       669544

        26          2        669544       670151

        27          3        670151       670186

        28          4        670186       673454

        29          5        673454       673459

        30          6        673459       711108

        31          7        711108       714855

        32          8        714855       714857

        33          9        714857       717474

        34         10        717474       717476

34 rows selected.

但是System Checkpoint SCN和Start SCN沒有變化,為什麼?

SYS@PROD>select trim(checkpoint_change#) from v$database;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

715635

 

SYS@PROD>select trim(checkpoint_change#) from v$datafile;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

715635

715635

715635

715635

715635

715635

715635

715635

717444—本來就不應該變化

 

9 rows selected.

但是再看下面:

SYS@PROD>alter tablespace tbs_tommie read write;

 

Tablespace altered.

 

SYS@PROD>select trim(checkpoint_change#) from v$database;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

717476

 

SYS@PROD>select trim(checkpoint_change#) from v$datafile;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

717476

717476

717476

717476

717476

717476

717476

717476

717569

 

9 rows selected.

 

繼續看變化:

n  將表空間變為只讀

SYS@PROD>alter tablespace tbs_tommie read only;

 

Tablespace altered.

n  查詢System Checkpoint SCN無變化

SYS@PROD>select trim(checkpoint_change#) from v$database;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

717476

n  查詢Datafile Checkpoint SCN無變化

 

SYS@PROD>select trim(checkpoint_change#) from v$datafile;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

717476

717476

717476

717476

717476

717476

717476

717476

717604

 

9 rows selected.

n  再把表空間變為可讀寫再查詢一輪

 

SYS@PROD>alter tablespace tbs_tommie read write;

 

Tablespace altered.

n  查詢Datafile Checkpoint SCN仍舊無變化

 

SYS@PROD>select trim(checkpoint_change#) from v$datafile;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

717476

717476

717476

717476

717476

717476

717476

717476

717624

 

9 rows selected.

n  手工發起checkpoint

 

SYS@PROD>alter system checkpoint;

 

System altered.

n  Loghistory無變化

 

SYS@PROD>select recid,sequence#,first_change#,next_change# from v$log_history;

 

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

---------- ---------- ------------- ------------

         1         36        597766       598183

         2          1        598449       638186

         3          2        638186       638842

         4          3        638842       638854

         5          4        638854       638937

         6          5        638937       638948

         7          6        638948       639692

         8          7        639692       639694

         9          8        639694       639697

        10          9        639697       639699

        11         10        639699       639702

 

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

---------- ---------- ------------- ------------

        12         11        639702       639970

        13         12        639970       639972

        14         13        639972       639975

        15         14        639975       639977

        16         15        639977       639979

        17         16        639979       641997

        18         17        641997       644653

        19         18        644653       644655

        20         19        644655       644658

        21          1        644659       648896

        22          2        648896       648898

 

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

---------- ---------- ------------- ------------

        23          3        648898       648902

        24          4        648902       648904

        25          1        648905       669544

        26          2        669544       670151

        27          3        670151       670186

        28          4        670186       673454

        29          5        673454       673459

        30          6        673459       711108

        31          7        711108       714855

        32          8        714855       714857

        33          9        714857       717474

 

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

---------- ---------- ------------- ------------

        34         10        717474       717476

 

34 rows selected.

n  查詢System Checkpoint SCN發生了變化,變成了前面Datafile Checkpoint SCN裡變化的表空間的SCN

 

SYS@PROD>select trim(checkpoint_change#) from v$database;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

717642

n  查詢Datafile Checkpoint SCN發生了變化,變成了前面Datafile Checkpoint SCN裡變化的表空間的SCN

SYS@PROD>select trim(checkpoint_change#) from v$datafile;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

717642

717642

717642

717642

717642

717642

717642

717642

717642

 

9 rows selected.

 

n  查詢Start SCN也發生了變化,變成了前面Datafile Checkpoint SCN裡變化的表空間的SCN

 

SYS@PROD>select trim(checkpoint_change#) from v$datafile_header;

 

TRIM(CHECKPOINT_CHANGE#)

--------------------------------------------------------------------------------

717642

717642

717642

717642

717642

717642

717642

717642

717642

 

9 rows selected.

 

實驗證明,發起Checkpoint是可以讓System Checkpoint SCN、Datafile Checkpoint SCN、Start SCN變為redolog的High SCN的。但是切換日誌是不能實現這個效果的。

 

4.        心跳

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

-- 暫時沒有理解

5.        資料庫正常關閉啟動

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

 

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

--可以理解

6.        資料庫非正常關閉

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

--可以理解

 

7.        資料檔案介質故障

結果是:出現介質故障時,Datafile SCN及System Checkpoint SCN比檔案頭Start SCN大。

判斷依據是:系統發生介質故障時,資料檔案被以前的備份代替,控制檔案中的Datafile Checkpoint SCN及System Checkpoint SCN肯定比被備份檔案替換的資料檔案的檔案頭中的Start SCN要大,這樣Oracle就知道要對這個檔案進行介質恢復。

--可以理解

 

8.        控制檔案介質故障

結果是:System Checkpoint SCN及Datafile Checkpoint SCN比資料檔案頭Start SCN小。

 

判斷依據是:在資料庫恢復時,控制檔案可能不是最新的,即把一個較早的控制檔案還原為當前的控制檔案,然後再執行恢復操作,這時控制檔案中的System Checkpoint SCN和Datafile Checkpoint SCN可能比檔案頭的Start SCN小。這時恢復資料庫要用下面命令:recover database using Backup Controlfile或其他的恢復語句。

--可以理解

 

9.        備份時的例項崩潰

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

--可以理解

 

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

相關文章