Oracle 系统改变号SCN详解
這篇文章是參考甲骨論老相老師的教學(xué)視頻:
http://v.youku.com/v_show/id_XNDAyNDIyMDgw.html
所做的學(xué)習(xí)筆記.
1. SCN的定義
?????? scn的英文全稱就是 system change number, 中文直譯過(guò)來(lái)就是系統(tǒng)改變號(hào)了.
?????? 有名字可以知道, scn其實(shí)是一串?dāng)?shù)字. 那么它到底是用來(lái)做什么的.
??????? 其實(shí)scn是oracle 根據(jù)1個(gè)時(shí)間點(diǎn), 然后經(jīng)過(guò)1個(gè)函數(shù)的運(yùn)算后得出的1個(gè)數(shù)字. (x和y一一對(duì)應(yīng)), 反之, 也可以通過(guò)scn號(hào)碼經(jīng)過(guò)反函數(shù)的運(yùn)算得出時(shí)間.
???????? 也就是說(shuō), scn其實(shí)就是時(shí)間的另1種表示.??
2. 系統(tǒng)為什么要把時(shí)間轉(zhuǎn)化為SCN
??????? 原因很簡(jiǎn)單, 因?yàn)橄到y(tǒng)要用不同的SCN號(hào)碼來(lái)比較,? 例如A對(duì)象的SCN號(hào)碼和B對(duì)象的SCN號(hào)碼. 系統(tǒng)就會(huì)知道哪個(gè)SCN的號(hào)碼更新, 就知道SCN對(duì)應(yīng)的時(shí)間更遲了.
????
???????? 也就是說(shuō), oracle 會(huì)利用scn 來(lái)比較 時(shí)間上的先后或者新舊.
??????????那為什么不用直接用時(shí)間來(lái)比較呢?? 因?yàn)橹苯颖容^時(shí)間的話比較復(fù)雜啊.
???????? 回想起, sharepool 解析sql的概念,? oracle會(huì)判斷sql語(yǔ)句 在sharepool 里有沒(méi)有被執(zhí)行(解析)過(guò),? 如何判斷呢?? 很簡(jiǎn)單, 就是根據(jù)要執(zhí)行的sql語(yǔ)句 跟sharepool 緩存的sql語(yǔ)句(其實(shí)是sql]語(yǔ)句的哈希碼)比較啊.
???????? 問(wèn)題是就是怎樣比較了,? 就是把sql語(yǔ)句的ASCII碼根據(jù)函數(shù)轉(zhuǎn)化為1個(gè)哈希碼(數(shù)字)啊.? 而不是直接地比較兩條sql語(yǔ)句啊.
???????? 根本原因就是計(jì)算內(nèi)部比較數(shù)字是很簡(jiǎn)單的, 而比較復(fù)雜一點(diǎn)的數(shù)據(jù)類型, 例如字符串,或者時(shí)間, 就相對(duì)復(fù)雜了.
???????? 所以系統(tǒng)會(huì)把時(shí)間轉(zhuǎn)化為SCN, 就是為了方便不同時(shí)間之間的比較啊.
????????? 可以利用下面語(yǔ)句來(lái)獲得當(dāng)前的時(shí)間及當(dāng)前時(shí)間所對(duì)應(yīng)的scn:
SQL> select dbms_flashback.get_system_change_number,SCN_TO_TIMESTAMP(dbms_flashback.get_system_change_number) from dual;GET_SYSTEM_CHANGE_NUMBER SCN_TO_TIMESTAMP(DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER) ------------------------ ---------------------------------------------------------------------------1760283 29-APR-13 11.25.40.000000000 PM?????????? 那個(gè)1760283 就是SCN啦.
3. SCN的意義
SCN的意義很簡(jiǎn)單, 就是為了保證oracle數(shù)據(jù)和文件的一致性, 下面會(huì)詳細(xì)分析常見(jiàn)的SCN, 來(lái)體會(huì)這個(gè)意義.
4. 常見(jiàn)的SCN
4.1 關(guān)于checkpoint queue的SCN
???? 我們先回顧下檢查點(diǎn)隊(duì)列的經(jīng)典SQL 查詢語(yǔ)句, 如下:
?????
SQL> select CPDRT,CPLRBA_SEQ||'.'||CPLRBA_BNO||'.'||CPLRBA_BOF "Low RBA",CPODR_SEQ||'.'||CPODR_BNO||'.'||CPODR_BOF "On disk RBA",CPODS,CPODT,CPHBT from x$kcccp;CPDRT Low RBA On disk RBA CPODS CPODT CPHBT ---------- -------------------- -------------------- ---------------- -------------------- ----------159 51.52589.0 51.53508.0 1762856 04/29/2013 23:36:38 8105124390 0.0.0 0.0.0 0 00 0.0.0 0.0.0 0 00 0.0.0 0.0.0 0 00 0.0.0 0.0.0 0 00 0.0.0 0.0.0 0 00 0.0.0 0.0.0 0 00 0.0.0 0.0.0 0 08 rows selected.????? 上次講過(guò)了, 上面CPDRT就是當(dāng)前臟buffer的個(gè)數(shù),? Low_RBA就是checkpoint queue中最高記錄的日志地址, 也是整個(gè)系統(tǒng)最早臟buffer日志地址,? 而on disk RBA就是current logfile(當(dāng)前使用的日志文件)最后一條日志的地址, 也就是硬盤上最后1條日志地址.? oracle每3秒發(fā)生1此檢查點(diǎn)時(shí)間, 會(huì)把當(dāng)前的Low RBA保存到控制文件中.?? 假如oracle在某個(gè)時(shí)間點(diǎn)不幸崩潰了,? 那么重啟恢復(fù)時(shí), 就會(huì)在控制文件中找出最新保存的Low RBA作為起點(diǎn),? on disk RBA作為終點(diǎn), 把這段日志對(duì)應(yīng)的臟buffer恢復(fù)出來(lái).
???? 好了, 接著 CPODS 這1列就是1個(gè)SCN了,? 但是它不是Low RBA被寫入時(shí)的SCN,? 而是ondisk RBA被寫入的時(shí)間對(duì)應(yīng)的SCN啊.? 這個(gè)SCN對(duì)于oracle來(lái)講其實(shí)是很有用的.
4.3 控制文件的SCN介紹
????? 控制文件包括3種重要的SCN, 包括系統(tǒng)檢查點(diǎn)SCN,?? 保存的數(shù)據(jù)文件的檢查點(diǎn)SCN和數(shù)據(jù)文件的結(jié)束SCN.
????? 沒(méi)錯(cuò), 后面的關(guān)于數(shù)據(jù)文件的SCN其實(shí)是數(shù)據(jù)文件的, 但是會(huì)被保存在控制文件內(nèi). 作用就是為了校驗(yàn)數(shù)據(jù)文件的一致性和系統(tǒng)的狀態(tài). 具體的本文后面還會(huì)講到.
????? 至于控制文件本身的檢查點(diǎn)的SCN又叫系統(tǒng)檢查點(diǎn)SCN. 該SCN是全局范圍的,? 當(dāng)檢查點(diǎn)進(jìn)程ckpt啟動(dòng)時(shí), oracle 就把系統(tǒng)檢查點(diǎn)SCN保存到控制文件中.??? 當(dāng)發(fā)生文件級(jí)別的SCN時(shí),? 例如將某個(gè)表空間置于只讀狀態(tài), 不會(huì)更新檢查點(diǎn)SCN.
????? 可以用下面的語(yǔ)句來(lái)查看系統(tǒng)檢查點(diǎn)SCN
4.3 數(shù)據(jù)文件的SCN介紹
????? Oracle會(huì)為數(shù)據(jù)文件保存2個(gè)SCN, 分別是數(shù)據(jù)文件的檢查點(diǎn)SCN,? 和結(jié)束SCN.
????? 4.3.1 數(shù)據(jù)文件的檢查點(diǎn)SCN
????? 當(dāng)ckpt進(jìn)程啟動(dòng)時(shí), 包括全局范圍的改動(dòng)(例如日志切換) 和文件級(jí)別的檢查點(diǎn)(將標(biāo)空間置為只讀), 就會(huì)更新數(shù)據(jù)文件的SCN, 并將這SCN寫于到控制文件中.
????? 可以用如下語(yǔ)句來(lái)查看數(shù)據(jù)庫(kù)各個(gè)數(shù)據(jù)文件的SCN.
?????
SQL> select file#, name, checkpoint_change# from v$datafile;FILE# NAME CHECKPOINT_CHANGE# ---------- ------------------------------------------------------------ ------------------1 /u01/app/oracle/project/oradata/orcl/system01.dbf 17949182 /u01/app/oracle/project/oradata/orcl/sysaux01.dbf 17949183 /u01/app/oracle/project/oradata/orcl/undotbs01.dbf 17949184 /u01/app/oracle/project/oradata/orcl/users01.dbf 17949185 /u01/app/oracle/project/oradata/orcl/ts_example.dbf 1794918? ? ? ? 見(jiàn)到各個(gè)數(shù)據(jù)文件的SCN與 當(dāng)前上面的系統(tǒng)檢查點(diǎn)SCN是一致的.
??????? 假如我將1個(gè)表空間設(shè)為只讀, 則個(gè)這個(gè)表空間的數(shù)據(jù)文件的檢查點(diǎn)SCN會(huì)被更新:
SQL> alter tablespace ts_example read only;Tablespace altered.SQL> select file#, name, checkpoint_change# from v$datafile;FILE# NAME CHECKPOINT_CHANGE# ---------- ------------------------------------------------------------ ------------------1 /u01/app/oracle/project/oradata/orcl/system01.dbf 17949182 /u01/app/oracle/project/oradata/orcl/sysaux01.dbf 17949183 /u01/app/oracle/project/oradata/orcl/undotbs01.dbf 17949184 /u01/app/oracle/project/oradata/orcl/users01.dbf 17949185 /u01/app/oracle/project/oradata/orcl/ts_example.dbf 1801087
????????? 如上面的例子,? tx_exmple.dbf 這個(gè)數(shù)據(jù)文件的檢查點(diǎn)scn被更新了.
?
????????? 這時(shí)我們?cè)俨榭聪到y(tǒng)檢查點(diǎn)scn:
SQL> select file#, name, checkpoint_change# from v$datafile;FILE# NAME CHECKPOINT_CHANGE# ---------- ------------------------------------------------------------ ------------------1 /u01/app/oracle/project/oradata/orcl/system01.dbf 17949182 /u01/app/oracle/project/oradata/orcl/sysaux01.dbf 17949183 /u01/app/oracle/project/oradata/orcl/undotbs01.dbf 17949184 /u01/app/oracle/project/oradata/orcl/users01.dbf 17949185 /u01/app/oracle/project/oradata/orcl/ts_example.dbf 1801087SQL> select checkpoint_change# from v$database;CHECKPOINT_CHANGE# ------------------1794918???????????? 見(jiàn)到系統(tǒng)檢查點(diǎn)SCN并沒(méi)有發(fā)生變化,? 這時(shí)ts_example表空間的數(shù)據(jù)文件的檢查點(diǎn)scn就比系統(tǒng)的檢查點(diǎn)scn要新了.???????????
???????????? 過(guò)了大概兩小時(shí), 再查一下..
SQL> select file#, name, checkpoint_change# from v$datafile;FILE# NAME CHECKPOINT_CHANGE# ---------- ------------------------------------------------------------ ------------------1 /u01/app/oracle/project/oradata/orcl/system01.dbf 18154782 /u01/app/oracle/project/oradata/orcl/sysaux01.dbf 18154783 /u01/app/oracle/project/oradata/orcl/undotbs01.dbf 18154784 /u01/app/oracle/project/oradata/orcl/users01.dbf 18154785 /u01/app/oracle/project/oradata/orcl/ts_example.dbf 1801087發(fā)現(xiàn)1 ~ 4號(hào)的數(shù)據(jù)文件的檢查點(diǎn)scn和系統(tǒng)檢查點(diǎn)scn都更新了了, 但是5號(hào)文件卻沒(méi)更新, 于是變得比系統(tǒng)檢查點(diǎn)scn舊了.
至于系統(tǒng)檢查點(diǎn)scn何時(shí)為何被更新, 下面會(huì)講.
?????? 4.3.2 數(shù)據(jù)文件的結(jié)束SCN
????? 每個(gè)數(shù)據(jù)文件都有1個(gè)結(jié)束scn, 在數(shù)據(jù)的正常運(yùn)行中, 只要數(shù)據(jù)文件在線且 可以讀寫的, 則這個(gè)數(shù)據(jù)文件的結(jié)束scn為空(NULL), 否則就是1個(gè)具體的scn值, 代表這個(gè)數(shù)據(jù)文件什么時(shí)候被結(jié)束讀寫狀態(tài).
????? 用如下命令來(lái)查看表空間的狀態(tài), 就得出數(shù)據(jù)文件的狀態(tài), 還有數(shù)據(jù)文件的檢查點(diǎn)scn和結(jié)束scn.
??????
SQL> select a.file#, a.name, t.status as TS_STATUS, a.checkpoint_change#, last_change#2 from v$datafile a, dba_data_files b, dba_tablespaces t3 where a.file# = b.file_id and b.tablespace_name = t.tablespace_name;FILE# NAME TS_STATUS CHECKPOINT_CHANGE# LAST_CHANGE# ---------- ------------------------------------------------------------ --------- ------------------ ------------1 /u01/app/oracle/project/oradata/orcl/system01.dbf ONLINE 18154782 /u01/app/oracle/project/oradata/orcl/sysaux01.dbf ONLINE 18154783 /u01/app/oracle/project/oradata/orcl/undotbs01.dbf ONLINE 18154784 /u01/app/oracle/project/oradata/orcl/users01.dbf ONLINE 18154785 /u01/app/oracle/project/oradata/orcl/ts_example.dbf READ ONLY 1801087 1801087?????? 可以見(jiàn)到, 1 ~ 4號(hào)文件的結(jié)束scn( last_change#) 是NULL,? 而第5個(gè)文件是表空間ts_example的數(shù)據(jù)文件, 剛才被設(shè)為readonly 了, 所以這個(gè)文件相當(dāng)于被關(guān)閉不能讀寫, 所以具有結(jié)束scn, 而且它的檢查點(diǎn)scn不再與系統(tǒng)檢查點(diǎn)同步.
????????
???????? 這時(shí)我們將表空間ts_example 恢復(fù)為讀寫狀態(tài), 就會(huì)令它的數(shù)據(jù)文件再次更新其檢查點(diǎn)scn,? 結(jié)束scn就變回null了.
SQL> alter tablespace ts_example read write;Tablespace altered.SQL> select name, checkpoint_change#,last_change# from v$datafile;NAME CHECKPOINT_CHANGE# LAST_CHANGE# ------------------------------------------------------------ ------------------ ------------ /u01/app/oracle/project/oradata/orcl/system01.dbf 1815478 /u01/app/oracle/project/oradata/orcl/sysaux01.dbf 1815478 /u01/app/oracle/project/oradata/orcl/undotbs01.dbf 1815478 /u01/app/oracle/project/oradata/orcl/users01.dbf 1815478 /u01/app/oracle/project/oradata/orcl/ts_example.dbf 1822907SQL>4.3 日志文件的SCN介紹
???????? 在redo log里每1條數(shù)據(jù)項(xiàng)都對(duì)應(yīng)1個(gè)地址, 上次介紹checkpoint queue時(shí)講過(guò)了. 而且每1條 日志數(shù)據(jù)項(xiàng)都配1個(gè)scn, 因?yàn)閞edo log file是嚴(yán)格按照日志的產(chǎn)生時(shí)間來(lái)記錄日志的啊, 所以scn就是配備的時(shí)間信息了.?????????
???????? 而且每1個(gè)redo log文件在文件頭都記錄著兩個(gè)scn,? 它們是first scn 和 next scn,? first scn就是日志文件第一條數(shù)據(jù)項(xiàng)的scn, 相對(duì)地next scn就是文件最后1條數(shù)據(jù)項(xiàng)的scn.?? 注意命名規(guī)則, first scn容易理解,? 至于后面那個(gè)為什么不叫l(wèi)ast scn而叫next scn? 因?yàn)樗瑫r(shí)也是下一個(gè)日志組文件的first scn啊, 這樣的話用于表示日志文件的銜接啊.
???????? 同樣可以理解出, 日志組文件的first scn 和 next scn就代表了日志組的范圍, 說(shuō)明了這個(gè)日志組記錄的是哪1個(gè)時(shí)間段的日志啊!
???????? 用下面語(yǔ)句可以查詢這個(gè)兩個(gè)scn:
SQL> select * from v$log;GROUP# THREAD# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM NEXT_CHANGE# NEXT_TIME ---------- ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- --------- ------------ ---------1 1 55 52428800 512 1 NO CURRENT 1837304 01-MAY-13 2.8147E+142 1 53 52428800 512 1 NO INACTIVE 1794918 30-APR-13 1815478 30-APR-133 1 54 52428800 512 1 NO INACTIVE 1815478 30-APR-13 1837304 01-MAY-13??????? 可以見(jiàn)到3號(hào)文件的next scn 就是1號(hào)文件的first scn, 2號(hào)文件的next scn 就是3號(hào)文件的first scn了,? 只有第1個(gè)日志組文件的next scn是不可用的, 而且沒(méi)有next time, 因?yàn)榈?個(gè)日志組狀態(tài)是 current啊.?
????????? 注意觀察, 上面的日志組的first scn都在上面的語(yǔ)句的系統(tǒng)檢查點(diǎn)scn出現(xiàn)過(guò)啊, 沒(méi)錯(cuò), 系統(tǒng)檢查點(diǎn)的scn的變化跟日志組的first scn有密切關(guān)系, 下面會(huì)詳細(xì)講到.
4.4 日志文件的SCN的意義
?????????? 這里順便解析下日志組文件的3種狀態(tài):?????????? Current:
???????????????????? 就是指當(dāng)前正在使用的日志文件組,? 新產(chǎn)生的日志將會(huì)被寫入這個(gè)日志組的文件.
??????????? Active:
???????????????????? 非當(dāng)前寫入的文件, 但是對(duì)應(yīng)這個(gè)文件內(nèi)的日志的臟buffer還沒(méi)完全寫入dbf文件中, 也就說(shuō)這個(gè)日志文件不能被覆蓋重寫, 因?yàn)橐坏┍桓采w重寫,? 萬(wàn)一對(duì)應(yīng)的臟buffer丟失, 就沒(méi)有日志把那些臟buffer重造出來(lái)了.
??????????? Inactive:
????????????????????? 非當(dāng)前寫入的文件, 而且里面日志對(duì)應(yīng)的臟buffer已經(jīng)全部被dbwr寫入到dbf文件中了(變成干凈buffer), 所以這種日志文件能被覆蓋重寫.? 所謂覆蓋重寫就是日志切換的意思啦. 當(dāng)current的寫滿, 就會(huì)寫下1個(gè)日志組, 當(dāng)然前提是下1個(gè)日志組狀態(tài)不能是Active啦.
??????????? 這時(shí)我們做1個(gè)操作, 就是手動(dòng)切換日志文件2次:
SQL> alter system switch logfile;System altered.SQL> alter system switch logfile;System altered.SQL> select * from v$log;GROUP# THREAD# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM NEXT_CHANGE# NEXT_TIME ---------- ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- --------- ------------ ---------1 1 58 52428800 512 1 NO ACTIVE 1842626 01-MAY-13 1844283 01-MAY-132 1 59 52428800 512 1 NO ACTIVE 1844283 01-MAY-13 1844286 01-MAY-133 1 60 52428800 512 1 NO CURRENT 1844286 01-MAY-13 2.8147E+14
??????????? 可以見(jiàn)到, 手動(dòng)切換2次后, current 狀態(tài)的日志組輪換到了第3組,? 也就是第3組的原來(lái)日志被重寫了.? 而第1組和第組的狀態(tài)是ACTIVE的,? 證明還有對(duì)應(yīng)的臟buffer 未被寫入到dbf文件, 所以不能被覆蓋和重寫的.
??????????? 而且2號(hào)和3號(hào)日志的First SCN都被更新了, 這很合理啊, 因?yàn)?號(hào)文件和3號(hào)文件都被重寫過(guò)了嘛, 畢竟剛才手動(dòng)切換日志2次!
???????????? 這時(shí)我們查詢一下系統(tǒng)檢查點(diǎn)SCN 和 數(shù)據(jù)文件的SCN:
?
SQL> select checkpoint_change# from v$database;CHECKPOINT_CHANGE# ------------------1842626SQL> select file#, name, checkpoint_change# from v$datafile;FILE# NAME CHECKPOINT_CHANGE# ---------- ------------------------------------------------------------ ------------------1 /u01/app/oracle/project/oradata/orcl/system01.dbf 18426262 /u01/app/oracle/project/oradata/orcl/sysaux01.dbf 18426263 /u01/app/oracle/project/oradata/orcl/undotbs01.dbf 18426264 /u01/app/oracle/project/oradata/orcl/users01.dbf 18426265 /u01/app/oracle/project/oradata/orcl/ts_example.dbf 1842626SQL>??????????? 可以見(jiàn)到系統(tǒng)檢查點(diǎn)SCN 這個(gè)SCN值與上面第1組logfile 的SCN值是一樣的.
???????????? 我們來(lái)分析下:
???????????? 假如這時(shí)數(shù)據(jù)庫(kù)崩了, 那么重啟時(shí)就會(huì)做實(shí)例恢復(fù). 那么做實(shí)例恢復(fù)需要那些日志呢? 由上面的分析得知, Active狀態(tài)的日志都是存在有臟buffer未寫入dbf文件中的. 所以需要從最早的Active狀態(tài)日志組起, 也就是上面的第一組日志, 然后一直到current狀態(tài)的日志都要用于實(shí)例恢復(fù)啊.
???
??????????? 這時(shí)我們?cè)偈謩?dòng)把所有臟buffer寫入dbf中.
SQL> alter system flush buffer_cache;System altered.SQL> select * from v$log;GROUP# THREAD# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM NEXT_CHANGE# NEXT_TIME ---------- ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- --------- ------------ ---------1 1 58 52428800 512 1 NO INACTIVE 1842626 01-MAY-13 1844283 01-MAY-132 1 59 52428800 512 1 NO INACTIVE 1844283 01-MAY-13 1844286 01-MAY-133 1 60 52428800 512 1 NO CURRENT 1844286 01-MAY-13 2.8147E+14SQL> select checkpoint_change# from v$database;CHECKPOINT_CHANGE# ------------------1844286SQL> select file#, name, checkpoint_change# from v$datafile;FILE# NAME CHECKPOINT_CHANGE# ---------- ------------------------------------------------------------ ------------------1 /u01/app/oracle/project/oradata/orcl/system01.dbf 18442862 /u01/app/oracle/project/oradata/orcl/sysaux01.dbf 18442863 /u01/app/oracle/project/oradata/orcl/undotbs01.dbf 18442864 /u01/app/oracle/project/oradata/orcl/users01.dbf 18442865 /u01/app/oracle/project/oradata/orcl/ts_example.dbf 1844286????? 見(jiàn)到寫入所有臟buffer后,? 第1和第2個(gè)日志組文件.狀態(tài)就變成INACTIVE了, 也就是可以被重寫啦!
????? 如果這時(shí)數(shù)據(jù)庫(kù)崩潰, 所需的日志文件就只是當(dāng)前current 日志了, 因?yàn)镮NACTIVE的日志所對(duì)應(yīng)的臟buffer已經(jīng)全部寫入dbf文件!
????? 而且數(shù)據(jù)文件的檢查點(diǎn)SCN和系統(tǒng)檢查點(diǎn)SCN都被更新了,? 因?yàn)閯偛诺膭?dòng)作相當(dāng)執(zhí)行了1次完全檢查點(diǎn)事件, 所有數(shù)據(jù)文件都會(huì)被更新, 所以數(shù)據(jù)文件的檢查點(diǎn)SCN也會(huì)更新. 當(dāng)然,系統(tǒng)檢查點(diǎn)SCN也更新了.? 而且更新的后的值與Current狀態(tài)的日志文件的First SCN 是一致的.
???????? 所以日志文件的SCN也是用來(lái)標(biāo)識(shí)日志的新舊程度的, 而且會(huì)把最早不能被重寫的日志組first SCN作為系統(tǒng)檢查點(diǎn)SCN寫入控制文件中.
??????? 總結(jié):? 可以見(jiàn)到, 系統(tǒng)檢查點(diǎn)的SCN實(shí)際上就是最早1個(gè)Active狀態(tài)的日志組的first SCN, 或者是current狀態(tài)的日志組SCN(當(dāng)沒(méi)有ACTIVE狀態(tài)的日志組時(shí)),? 當(dāng)數(shù)據(jù)庫(kù)崩潰時(shí), oracle重啟后會(huì)做實(shí)例恢復(fù), 就會(huì)從控制文件得出最新的系統(tǒng)檢查點(diǎn)SCN, 然后根據(jù)這個(gè)SCN獲得第1個(gè)需要被回復(fù)的日志啊, 當(dāng)然,具體從那個(gè)日志的哪個(gè)數(shù)據(jù)項(xiàng)開(kāi)始還要看被保存于控制文件的檢查點(diǎn)隊(duì)列的LRBA.
??????
4.5 控制文件的和數(shù)據(jù)文件SCN的意義
????? 我們上面提到了,控制文件的系統(tǒng)檢查點(diǎn)SCN是如何生成的了, 但是再上面還提到了其實(shí)控制文件還保存著數(shù)據(jù)文件的檢查點(diǎn)SCN和結(jié)束SCN,? 這里會(huì)詳細(xì)分析它們的關(guān)系及意義.
?????? 首先, 上面說(shuō)過(guò), 結(jié)束SCN是當(dāng)文件結(jié)束在線狀態(tài)或結(jié)束讀寫狀態(tài)時(shí), 就會(huì)生成結(jié)束SCN, 那么正常情況下, 除了手動(dòng)更改數(shù)據(jù)文件的狀態(tài), 只有關(guān)機(jī)這1個(gè)動(dòng)作, 會(huì)生成數(shù)據(jù)文件的結(jié)束SCN(last_change#)
?????? 而且關(guān)機(jī)時(shí), oracle還會(huì)做1個(gè)動(dòng)作, 就是把每個(gè)dbf文件生成的結(jié)束SCN保存入控制文件中, 那么下次啟動(dòng)oracle數(shù)據(jù)庫(kù)時(shí),oracle會(huì)檢查控制文件, 當(dāng)然發(fā)現(xiàn)正常的dbf結(jié)束SCN,就認(rèn)為自己上次關(guān)閉是正常關(guān)閉.
?????? 假如, 數(shù)據(jù)庫(kù)在運(yùn)行中崩了, 那么oracle就不會(huì)生成dbf文件結(jié)束scn和把它們寫入控制文件, 下次oracle啟動(dòng)自檢時(shí)發(fā)現(xiàn)控制文件不存在數(shù)據(jù)文件的結(jié)束scn, 那么oracle就會(huì)認(rèn)為上次關(guān)閉是非正常關(guān)閉,? 接下來(lái)就啟動(dòng)實(shí)例恢復(fù)了. 所以保存在控制文件的數(shù)據(jù)文件結(jié)束SCN是oracle啟動(dòng)自檢時(shí)判斷上次關(guān)閉是否正常關(guān)閉的標(biāo)記.
???????
?????? 還有, 正常關(guān)閉下所有數(shù)據(jù)文件的檢查點(diǎn)SCN與系統(tǒng)檢查點(diǎn)SCN是保持一致的, 假如這時(shí)我們做1個(gè)動(dòng)作, 就是在數(shù)據(jù)庫(kù)關(guān)閉狀態(tài)時(shí), 用較舊版本的1個(gè)數(shù)據(jù)文件去覆蓋正常的數(shù)據(jù)文件,? 那么啟動(dòng)時(shí)oracle發(fā)現(xiàn)這個(gè)數(shù)據(jù)庫(kù)文件的scn比 控制文件中保存的scn舊, 就會(huì)認(rèn)為介質(zhì)故障, 就會(huì)要求啟動(dòng)介質(zhì)恢復(fù)(需要?dú)w檔日志), 這時(shí)通過(guò)日志會(huì)舊的dbf文件跑成新的. 所以行業(yè)內(nèi)有一句話:?? 提升數(shù)據(jù)庫(kù)文件的SCN!
????? 當(dāng)oracle自檢時(shí)發(fā)現(xiàn)控制文件保存的系統(tǒng)檢查點(diǎn)SCN比數(shù)據(jù)庫(kù)文件的檢查scn還舊, 就會(huì)認(rèn)為控制文件發(fā)生故障..這時(shí)恢復(fù)數(shù)據(jù)庫(kù)要用下面命令:recover database using Backup Controlfile或其他的恢復(fù)語(yǔ)句。
4.5 1個(gè)關(guān)鍵的參數(shù) fast_start_mttr_target
????? 看這個(gè)參數(shù)的名字, 大概估算出這個(gè)參數(shù)跟啟動(dòng)速度有關(guān).
????? 沒(méi)錯(cuò), 這個(gè)參數(shù)參數(shù)就是用來(lái)設(shè)定數(shù)據(jù)庫(kù)崩潰后,? 實(shí)例恢復(fù)的期望速度. 這個(gè)參數(shù)的單位是秒,? 假如我們把這個(gè)參數(shù)設(shè)為20秒,? 那么oracle就會(huì)調(diào)整一些參數(shù), 讓實(shí)例回復(fù)的速度控制在20秒以內(nèi).
????? 關(guān)鍵是調(diào)整什么啊,? 我們知道實(shí)例恢復(fù)的本質(zhì)是構(gòu)造出丟失的臟buffer, 所以崩潰時(shí)臟buffer的數(shù)量直接影響著實(shí)例恢復(fù)的速度.? 所以oracle就會(huì)調(diào)整臟buffer的數(shù)量, 怎樣調(diào)整?? 就是調(diào)整dbwr的寫入頻率啊.
????? 所以這個(gè)參數(shù)的本質(zhì)是跟dbwr的頻率有關(guān).? 當(dāng)我們將這個(gè)這個(gè)參數(shù)設(shè)成很短時(shí), dbwr的頻率就很頻繁, 這對(duì)數(shù)據(jù)庫(kù)的運(yùn)行效率是相當(dāng)不利的, 而且大部分情況下, 實(shí)例恢復(fù)的速度慢點(diǎn)也沒(méi)所謂, 就算10分鐘以上也可以接受的.
?
????? 所以我們不建議隨便更改這個(gè)參數(shù), 把設(shè)為默認(rèn)的0. 讓系統(tǒng)自動(dòng)管理就ok了.
總結(jié)
以上是生活随笔為你收集整理的Oracle 系统改变号SCN详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 数据结构 递归讲解
- 下一篇: 外观模式(Facade) - 为系统分层