1.oracle正常運行時,control文件的SCN是個很大的數,與redo log文件、數據文件的SCN不一樣,正常關閉時,作完checkpoint後,三者的SCN值相同;
Biti:日誌文件中scn有起始和結束2個(高低),在current log中高scn一樣爲無窮大。
2.當一個事務commit成功時,redo log文件中的SCN+1,當該事務所作的修改寫入數據文件後,數據文件的SCN+1;
Biti:commit的時候加1,其餘不少時候也會加1,只要數據庫發生了變化都會增長。數據寫入數據文件時scn不是加1而是由ckpt更新,檢查點發生的時候才修改數據文件頭的檢查點計數並更新scn。
3.疑問:
是否是若是一個事務比較大,在事務提交前就發生redo log entries、data buffer的寫入,此時斷電,則數據文件、redo log文件的SCN沒有+1,且相同,但控制文件SCN不一樣,數據庫startup時發生回滾。
Biti:數據文件是由ckpt進程更新文件頭的,scn不是加1,而是更新爲檢查點發生那時的scn,回滾是根據回滾段頭的事務表狀態來進行的。html
4.數據寫入數據文件scn不是加1而是ckpt 更新,檢查點發生的時候才修改數據文件頭的檢查點計數和更新scn
是否是應該這麼說?:
當ckpt 更新時發生數據寫入,同時修改數據文件頭的檢查點計數和更新scn 。當出現其餘狀況下的數據寫入時(如無空閒緩衝等),不發生ckpt ,但SCN會增長。
Biti:這個時候修改的是數據塊但不是數據文件頭,只有檢查點發生的時候才更新數據文件頭,也就是說只有ckpt進程更新數據文件頭(oracle8之前若是沒有ckpt進程就是lgwr更新),dbwr只寫數據塊。數據庫
BTW:看樣DBWR只是些數據塊,只有CKPT進程才能更新數據文件頭;
5.commit的時候加一,其餘不少時候也會加1,只要數據庫發生了變化都會增長。
不少時候,可否舉一些例子
Biti: dml一發生即便沒有提交也會增長scn, job進程同樣產生scn,只要對數據庫中文件發生任何的改變都有可能產生scn,SCN: system change number, not system commit number .也就是系統發生變化時所產生的一個時間點安全
標誌。不是提交的標誌,只是由於提交也是系統的變化之一而已。oracle
6.Biti:檢查點的發生,跟寫日誌文件是沒有必然聯繫的
檢查點通知 DBWR 寫數據文件,寫完後ckpt更新控制文件頭和數據文件頭。
當DBWR寫數據塊的時候若發現數據塊的相關 RDBA (位於日誌文件的位置) 的 log block 尚未被寫入日誌文件,則在dbwr寫塊以前必須通知lgwr把log buffer 中日誌寫入日誌文件。dom
7.data block 裏面的SCN是當 block 被更改的時候的SCN
而數據文件有那麼多 block,天然不一樣的 block有不一樣的SCN
block中存在 block SCN 和 ITL 中的commit SCN
block SCN 又在塊頭和塊尾都有,若不一致意味着block損壞(熱備可能出現這個狀況,須要從redo log中拷貝回來,如果正在修改的過程當中因爲進程死掉則 pmon負責清理。若因爲一些之外發生這樣的不一致的狀況,則查詢的時候出現 1578 錯誤,固然該錯誤號也多是物理磁盤損壞,這裏表示邏輯的損壞!)這個頭和尾的SCN的檢查時機跟這兩個參數有關:
db_block_checking boolean FALSE
db_block_checksum boolean FALSE
該2參數信息請查閱http://tahiti.oracle.com
而ITL 中的 commit SCN 則跟 consistent gets and delay block cleanout 有關
數據文件頭的 SCN 是檢查點發生時更新的
表明着當恢復的時候從這個 SCN 點開始在 log file 中尋找 redo 開始作恢復ide
8.According to Rama Velpuri's book, CKPT updates controlfiles, not their headers. It makes sense because if you look at a controlfile dump, the header doesn't even have an SCN. But the file body has sections for each datafile, and therefore each of them has an SCN to be updated.
It's odd that most books and also documentation don't even say CKPT updates controlfiles.
Follow-up to bellsz's original message. In controlfiles, the stop SCN is not a very big number; it's in fact set to infinity when the database is open. Also, SCNs are incremented for many reasons, mostly due to recursive transactions. Read Steve Adams and Hemant Chitale's answers at
http://groups.google.com/groups?sel...t_nospam.com.sg
9.測試
系統檢查點scn(v$database(checkpoint_change#))
數據文件檢查點(v$datafile(checkpoint_change#))
數據文件終止scn(v$datafile(last_change#))
數據文件中存放的檢查點
啓動scn (v$datafile_header(checkpoint_change#)
1>系統檢查點scn
當一個檢查點動做完成以後,Oracle就把系統檢查點的SCN存儲到控制文件中。
select checkpoint_change# from v$database
2>數據文件檢查點scn
當一個檢查點動做完成以後,Oracle就把每一個數據文件的scn單獨存放在控制文件
中。
select name,checkpoint_change# from v$datafile
3>啓動scn
Oracle把這個檢查點的scn存儲在每一個數據文件的文件頭中,這個值稱爲啓動scn,
由於它用於在數據庫實例啓動時,檢查是否須要執行數據庫恢復。
select name,checkpoint_change# from v$datafile_header
4>終止scn
每一個數據文件的終止scn都存儲在控制文件中。
select name,last_change# from v$datafile
在正常的數據庫操做過程當中,全部正處於聯機讀寫模式下的數據文件的終止scn都爲null.
5>在數據庫運行期間的scn值
在數據庫打開並運行以後,控制文件中的系統檢查點、控制文件中的數據文件檢查點scn
和每一個數據文件頭中的啓動scn都是相同的。控制文件中的每一個數據文件的終止scn都爲null.
在安全關閉數據庫的過程當中,系統會執行一個檢查點動做,這時全部數據文件的終止scn
都會設置成數據文件頭中的那個啓動scn的值。在數據庫從新啓動的時候,
Oracle將文件頭中的那個啓動scn與數據庫文件檢查點scn進行比較,
若是這兩個值相互匹配,oracle接下來還要比較數據文件頭中的啓動scn和控制文件
中數據文件的終止scn。若是這兩個值也一致,就意味着全部數據塊多已經提交,全部
對數據庫的修改都沒有在關閉數據庫的過程當中丟失,所以此次啓動數據庫的過程
也不須要任何恢復操做,此時數據庫就能夠打開了。當全部的數據庫都打開以後,
存儲在控制文件中的數據文件終止scn的值再次被更改成null,
這表示數據文件已經打開並可以正常使用了。this
10.google
找了一些網頁,發現SCN確實不僅在事務提交時增長,如下是網頁上的摘要:
1)
SCN means "System Change Number" not "System Commit Number".
However, because the SCN is always incremented at commits and seldom otherwise, it is OK to use the two terms interchangeably.
2)
The SCN is incremented whenever a transaction commits. However, this is not the only source of increments. In a seemingly idle database, the SCN gets incremented also through AQ, SMON, job queues...
1中說了 oracle seldom操做也會引發SCN的增長,2中更明確說了AQ, SMON, job queues... 會致使SCN的增長,所以應該得出結論,在ORACLE中除了COMMIT會致使SCN增長外還有其它的ORACLE後臺進程會致使SCN增長.
可是,是不是普通的DML致使了SCN的增長,仍是因爲DML操做過程當中後臺進程致使了SCN增長的假象?請你們踊躍討論!
還有ORACLE後臺進程在什麼時候,何種狀況下致使了SCN增長,也請你們踊躍討論!spa
Biti:這句話我應該更準確第表達一下
若是一個dml致使產生事務,則會產生一個scn。這個意思是說
若是一個事務包含多個dml,則只有第一個初始產生事務的dml產生scn,提交的時候又是一個scn
若是一個事務只有一個dml,拿看起來就是dml產生一個scn,提交或者回滾產生一個scn
這是通過實驗測試過的,若是你又興趣,不牢牢是要找資料看,還能夠動手證實。
你能夠理解爲 begin transaction and commit tansaction
至於沒有dml的commit ,那不叫一個 transaction
你不作任何dml 而發出rollback命令將會發現 v$sysstat 中 user rollbacks 將會增長而 transactions 不會增長
因此你能夠把結論定義爲事務的開始和事務的結束都會致使 SCN 的增長,其餘如 AQ/JOB 等也會產生SCN ……
同一個block上在一個事務中連續發生255個DML後scn也會增長
……
11.sys@DBAP01> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;
MAX(KTUXESCNW*POWER(2,32)+KTUX
------------------------------
52211024
已用時間: 00: 00: 00.00
sys@DBAP01> alter system checkpoint;
系統已更改。
已用時間: 00: 00: 00.06
sys@DBAP01> select CHECKPOINT_CHANGE# from v$database;
CHECKPOINT_CHANGE#
------------------
52211055
已用時間: 00: 00: 00.00
sys@DBAP01> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;
MAX(KTUXESCNW*POWER(2,32)+KTUX
------------------------------
52211053
x$ktuxe 計算出來的是已經結束的最新的事務的commit scn ,因此可小於當前系統scn。檢查點scn 天然也小於當前系統scn。可是檢查點scn 和 x$ktuxe 計算出來的大小卻倚賴於系統情況了。
current scn 是系統當前所產生的最大 scn ,多是當前未結束事務所產生的scn。在9i 的dbms_flashback.get_system_change_number能夠獲得這個值,這個值應該是大於等於 x$ktuxe SCN (這個view 記錄的是當前數據庫結束事務的最大scn)