【體系結構】有關Oracle SCN知識點的整理
各位技術愛好者,看完本文後,你可以掌握如下的技能,也可以學到一些其它你所不知道的知識,~O(∩_∩)O~:
① Oracle中的SCN是什麼?(重點)
② 如何查詢SCN?(重點)
③ SCN有哪些分類?(重點)
④ SCN和系統恢復的關系?(重點)
④ 實例恢復和介質恢復的區別是什麼?RAC中的實例恢復是什麼樣的?(重點)
⑥ SCN和時間的轉換
⑦ SMON_SCN_TIME系統表的認識
⑧ 不完全恢復的一些分類及其寫法
Tips:
① 本文在itpub(http://blog.itpub.net/26736162)、博客園(http://www.cnblogs.com/lhrbest)和微信公眾號(xiaomaimiaolhr)上有同步更新。
② 文章中用到的所有代碼、相關軟件、相關資料及本文的pdf版本都請前往小麥苗的360雲盤下載,我的360雲盤地址見:http://blog.itpub.net/26736162/viewspace-1624453/。
③ 若網頁文章代碼格式有錯亂,請嘗試以下辦法:①使用360浏覽器,②去博客園地址閱讀③下載pdf格式的文檔來閱讀。
④ 在本篇BLOG中,代碼輸出部分一般放在一行一列的表格中。其中,需要特別關注的地方我都用灰色背景和粉紅色字體來表示,比如在下邊的例子中,thread 1的最大歸檔日志號為33,thread 2的最大歸檔日志號為43是需要特別關注的地方;而命令一般使用黃色背景和紅色字體標注;對代碼或代碼輸出部分的注釋一般采用藍色字體表示。
List of Archived Logs in backup set 11
Thrd Seq Low SCN Low Time Next SCN Next Time
---- ------- ---------- ------------------- ---------- ---------
1 32 1621589 2015-05-29 11:09:52 1625242 2015-05-29 11:15:48
1 33 1625242 2015-05-29 11:15:48 1625293 2015-05-29 11:15:58
2 42 1613951 2015-05-29 10:41:18 1625245 2015-05-29 11:15:49
2 43 1625245 2015-05-29 11:15:49 1625253 2015-05-29 11:15:53
[ZHLHRDB1:root]:/>lsvg -o
T_XLHRD_APP1_vg
rootvg
[ZHLHRDB1:root]:/>
00:27:22 SQL> alter tablespace idxtbs read write;
====》2097152*512/1024/1024/1024=1G
本文如有錯誤或不完善的地方請大家多多指正,ITPUB留言或QQ皆可,您的批評指正是我寫作的最大動力。
由於寫書遇到了SCN的概念,所以就找了點資料,整理了一下有關SCN的一些知識。順便復習了一下SCN和數據庫恢復的關系。
SCN(System Change Number,系統改變號)是一個由系統內部維護的序列號。當系統需要更新的時候自動增加,它是系統中維持數據的一致性和順序恢復的重要標志,是數據庫非常重要的一種數據結構。SCN的最大值是0xffff.ffffffff。在數據庫中SCN作為一種時鐘機制來標記數據庫動作,比如當事務的發生,數據庫會用一個SCN來標記它。同時這個SCN在數據庫全局也是唯一的,它隨時間的增長而增長除非重建數據庫。
在數據庫中,SCN可以說是無處不在,數據文件頭,控制文件,數據塊頭,日志文件等等都標記著SCN。也正是這樣,數據庫的一致性維護和SCN密切相關。不管是數據的備份,恢復都是離不開SCN的。
A system change number (SCN) is a logical, internal time stamp used by Oracle Database. SCNs order events that occur within the database, which is necessary to satisfy the ACID properties of a transaction. Oracle Database uses SCNs to mark the SCN before which all changes are known to be on disk so that recovery avoids applying unnecessary redo. The database also uses SCNs to mark the point at which no redo exists for a set of data so that recovery can stop.
SCNs occur in a monotonically increasing sequence. Oracle Database can use an SCN like a clock because an observed SCN indicates a logical point in time and repeated observations return equal or greater values. If one event has a lower SCN than another event, then it occurred at an earlier time with respect to the database. Several events may share the same SCN, which means that they occurred at the same time with respect to the database.
Every transaction has an SCN. For example, if a transaction updates a row, then the database records the SCN at which this update occurred. Other modifications in this transaction have the same SCN. When a transaction commits, the database records an SCN for this commit.
Oracle Database increments SCNs in the system global area (SGA). When a transaction modifies data, the database writes a new SCN to the undo data segment assigned to the transaction. The log writer process then writes the commit record of the transaction immediately to the online redo log. The commit record has the unique SCN of the transaction. Oracle Database also uses SCNs as part of its instance recovery and media recovery mechanisms.
怎麼理解這個“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並不是說這些SCN的概念不一樣,而是說不同分類的SCN代表的意義不一樣,不管什麼時候SCN所指代的都是數據庫的某個一致性的狀態。就像我們給一天中的某個時間點定義上班時間、另外的某個時間點定義成下班時間一樣,數據庫Checkpoint發生點的SCN被稱為Checkpoint SCN,僅此而已。
SCN可以分為4類,系統檢查點SCN(System Checkpoint SCN)、文件檢查點SCN(Datafile Checkpoint SCN)、開始SCN(Start SCN)和結束SCN(Stop SCN),參考如下表格:
col status for a10
select GROUP# ,SEQUENCE#,STATUS,FIRST_CHANGE#,FIRST_TIME from v$log;
SELECT A.FILE#,
A.NAME,
(SELECT CHECKPOINT_CHANGE# FROM V$DATABASE) SYSTEM_CKPT_SCN,
A.CHECKPOINT_CHANGE# DF_CKPT_SCN,
A.LAST_CHANGE# END_SCN,
B.CHECKPOINT_CHANGE# START_SCN,
B.RECOVER,
A.STATUS
FROM V$DATAFILE A, V$DATAFILE_HEADER B
WHERE A.FILE# = B.FILE#;
SELECT FILE#,ONLINE_STATUS,CHANGE#,ERROR FROM V$RECOVER_FILE;
SYS@lhrdb> select file#,checkpoint_change# from v$datafile;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 9026292
2 9026292
3 9026292
4 9026292
5 9026292
6 9026292
7 9026292
7 rows selected.
SYS@lhrdb> alter tablespace users read only;
Tablespace altered.
SYS@lhrdb> select file#,checkpoint_change# from v$datafile;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 9026292
2 9026292
3 9026292
4 9028165
5 9026292
6 9026292
7 9026292
7 rows selected.
SYS@lhrdb> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
9026292
可以看到4號文件也就是users表空間所屬的文件scn值和其他文件不一致,且比系統檢查點的scn要大。
Stop scn記錄在數據文件頭上。當數據庫處在打開狀態時,stop scn被設成最大值0xffff.ffffffff。在數據庫正常關閉過程中,stop scn被設置成當前系統的最大scn值。在數據庫打開過程中,Oracle會比較各文件的stop scn和checkpoint scn,如果值不一致,表明數據庫先前沒有正常關閉,需要做恢復。
SYS@lhrdb> SELECT TABLESPACE_NAME,STATUS FROM DBA_TABLESPACES;
TABLESPACE_NAME STATUS
------------------------------ ---------
SYSTEM ONLINE
SYSAUX ONLINE
UNDOTBS1 ONLINE
TEMP ONLINE
USERS READ ONLY
EXAMPLE ONLINE
TS_MIG_CHAIN_LHR ONLINE
TS_TESTBLOCKLHR ONLINE
8 rows selected.
SYS@lhrdb> SELECT FILE#,LAST_CHANGE# FROM V$DATAFILE;
FILE# LAST_CHANGE#
---------- ------------
1
2
3
4 9028165
5
6
7
7 rows selected.
可以看到除了USERS表空間的結束SCN不為空,其他數據文件的結束SCN為空。
將數據庫至於MOUNT狀態,由於該狀態下所有的數據文件都不可寫,故MOUNT狀態下所有的數據文件都具有結束SCN。
SYS@lhrdb> startup mount
ORACLE instance started.
Total System Global Area 1720328192 bytes
Fixed Size 2247072 bytes
Variable Size 452986464 bytes
Database Buffers 1258291200 bytes
Redo Buffers 6803456 bytes
Database mounted.
SYS@lhrdb> SELECT FILE#,LAST_CHANGE# FROM V$DATAFILE;
FILE# LAST_CHANGE#
---------- ------------
1 9048847
2 9048847
3 9048847
4 9028165
5 9048847
6 9048847
7 9048847
7 rows selected.
SYS@lhrdb> alter tablespace users read write;
Tablespace altered.
SYS@lhrdb> SELECT FILE#,LAST_CHANGE# FROM V$DATAFILE;
FILE# LAST_CHANGE#
---------- ------------
1
2
3
4
5
6
7
7 rows selected.
SYS@lhrdb> startup force mount
ORACLE instance started.
Total System Global Area 1720328192 bytes
Fixed Size 2247072 bytes
Variable Size 452986464 bytes
Database Buffers 1258291200 bytes
Redo Buffers 6803456 bytes
Database mounted.
SYS@lhrdb> SELECT FILE#,LAST_CHANGE# FROM V$DATAFILE;
FILE# LAST_CHANGE#
---------- ------------
1
2
3
4
5
6
7
7 rows selected.
ORACLE的REDO LOG會順序紀錄數據庫的各個變化。一組REDO LOG文件寫滿後,會自動切換到下一組REDO LOG文件。則上一組REDO LOG的HIGH SCN就是下一組REDO LOG的LOW SCN。在CURRENT LOG中HIGH SCN為無窮大。
在視圖V$LOG_HISTORY中,SEQUENCE#代表REDO LOG的序列號,FIRST_CHANGE#表示當前REDO LOG的LOW SCN,列NEXT_CHANGE#表示當前REDO LOG的HIGH SCN。
可通過查詢V$LOG_HISTORY查看 LOW SCN和 HIGH SCN。
SYS@lhrdb> set pagesize 9999
SYS@lhrdb> SELECT RECID,SEQUENCE#,FIRST_CHANGE#,NEXT_CHANGE# FROM V$LOG_HISTORY WHERE ROWNUM<=6;
RECID SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#
---------- ---------- ------------- ------------
272 272 7486197 7510243
273 273 7510243 7527538
274 274 7527538 7539409
275 275 7539409 7556740
276 276 7556740 7572195
277 277 7572195 7581847
6 rows selected.
查看CURRNET REDO LOG中的HIGH SCN
SYS@lhrdb> COL MEMBER FORMAT A50
SYS@lhrdb> 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#
-------------------------------------------------- ---------------- -------------
+DATA/lhrdb/onlinelog/group_4.798.923841413 CURRENT 9069089
+DATA/lhrdb/onlinelog/group_4.797.923841415 CURRENT 9069089
SYS@lhrdb> ALTER SYSTEM DUMP LOGFILE '+DATA/lhrdb/onlinelog/group_4.797.923841415';
System altered.
SYS@lhrdb> oradebug setmypid
Statement processed.
SYS@lhrdb> oradebug tracefile_name
/oracle/app/oracle/diag/rdbms/lhrdb/lhrdb/trace/lhrdb_ora_8388948.trc
查看轉儲文件的內容:
DUMP OF REDO FROM FILE '+DATA/lhrdb/onlinelog/group_4.797.923841415'
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 = 186647552=0xb200400
Db ID=959319562=0x392e0e0a, Db Name='LHRDB'
Activation ID=959339270=0x392e5b06
Control Seq=96545=0x17921, File size=204800=0x32000
File Number=4, Blksiz=512, File Type=2 LOG
descrip:"Thread 0001, Seq# 0000001090, SCN 0x0000008a6221-0xffffffffffff"
thread: 1 nab: 0xffffffff seq: 0x00000442 hws: 0x2 eot: 1 dis: 0
resetlogs count: 0x36a23c8c scn: 0x0000.000e20dc (925916)
prev resetlogs count: 0x3155bebd scn: 0x0000.00000001 (1)
Low scn: 0x0000.008a6221 (9069089) 10/11/2016 16:46:41
Next scn: 0xffff.ffffffff 01/01/1988 00:00:00
Enabled scn: 0x0000.000e20dc (925916) 07/07/2016 19:39:56
Thread closed scn: 0x0000.008a6221 (9069089) 10/11/2016 16:46:41
Disk cksum: 0xc14c Calc cksum: 0xc14c
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: 0x800000
Thread internal enable indicator: thr: 0, seq: 0 scn: 0x0000.00000000
Zero blocks: 0
Format ID is 1
redo log key is 47e6cd1abd3a43fd864d2b94ae9a8128
redo log key flag is 5
Enabled redo threads: 1
當前最新的數據庫scn值可通過如下命令查看:
SYS@lhrdb> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
9069555
如果需要進行實例恢復,則需要恢復的記錄為9069089至9069555中redo log中的記錄。
Scn號與Oracle數據庫恢復過程有著密切的關系,只有很好地理解了這層關系,才能深刻地理解恢復的原理。CKPT進程在checkpoint發生時,將當時的SCN號寫入數據文件頭和控制文件,同時通知DBWR進程將數據塊寫到數據文件。
CKPT進程也會在控制文件中記錄RBA(redo block address),以標志Recovery需要從日志中哪個地方開始。
1.在數據庫的啟動過程中,當System Checkpoint SCN=Datafile Checkpoint SCN=Start SCN的時候,Oracle數據庫是可以正常啟動的,而不需要做任何的MEDIA RECOVERY。而如果三者當中有一個不同的話,則需要做MEDIA RECOVERY。Oracle在啟動過程中首先檢查是否需要MEDIA RECOVERY,然後再檢查是否需要INSTANCE RECOVERY。
2.那什麼時候需要做INSTANCE RECOVERY呢?其實在正常OPEN數據庫的時候,Oracle會將記錄在控制文件中的每一個數據文件頭的End SCN都設置為#FFFFFF(NULL),那麼如果數據庫進行了正常關閉比如(shutdown or shutdown immediate)這個時候,系統會執行一個檢查點,這個檢查點會將控制文件中記錄的各個數據文件頭的End SCN更新為當前online數據文件的各個數據文件頭的Start SCN,也就是End SCN=Start SCN,如果再次啟動數據庫的時候發現二者相等,則直接打開數據庫,並再次將End SCN設置為#FFFFFF(NULL),那麼如果數據庫是異常關閉,那麼CHECKPOINT就不會執行,因此再次打開數據庫的時候End SCN<>Start SCN這個時候就需要做實例恢復。如果數據庫異常關閉的話,則END SCN號將為NULL.則需要做instance recovery。
為什麼ORACLE會在控制文件中記錄System checkpoint SCN號的同時,還需要為每個數據文件記錄Datafile Checkpoint SCN號?
原因有二:
1.對只讀表空間,其數據文件的Datafile Checkpoint SCN、Start SCN和END SCN號均相同。這三個SCN在表空間處於只讀期間都將被凍結。
2.如果控制文件不是當前的控制文件,則System checkpoint會小於Start SCN或END SCN號。記錄這些SCN號,可以區分控制文件是否是當前的控制文件。
SYS@lhrdb> alter tablespace users read only;
Tablespace altered.
SYS@lhrdb> SELECT A.FILE#,
2 A.NAME,
3 (SELECT CHECKPOINT_CHANGE# FROM V$DATABASE) SYSTEM_CKPT_SCN,
4 A.CHECKPOINT_CHANGE# DF_CKPT_SCN,
5 A.LAST_CHANGE# END_SCN,
6 B.CHECKPOINT_CHANGE# START_SCN,
7 B.RECOVER,
8 A.STATUS
9 FROM V$DATAFILE A, V$DATAFILE_HEADER B
10 WHERE A.FILE# = B.FILE#;
FILE# NAME SYSTEM_CKPT_SCN DF_CKPT_SCN END_SCN START_SCN REC STATUS
---------- ------------------------------------------------------------ --------------- ----------- ---------- ---------- --- ----------
1 +DATA/lhrdb/datafile/system.347.916601927 9225394 9225394 9225394 NO SYSTEM
2 +DATA/lhrdb/datafile/sysaux.340.916601927 9225394 9225394 9225394 NO ONLINE
3 +DATA/lhrdb/datafile/undotbs1.353.916601927 9225394 9225394 9225394 NO ONLINE
4 +DATA/lhrdb/datafile/users.445.916601927 9225394 9229175 9229175 9229175 NO ONLINE
5 +DATA/lhrdb/datafile/example.416.916602001 9225394 9225394 9225394 NO ONLINE
6 +DATA/lhrdb/datafile/ts_mig_chain_lhr.471.919677645 9225394 9225394 9225394 NO ONLINE
7 /oracle/app/oracle/oradata/lhrdb/testblocklhr01.dbf 9225394 9225394 9225394 NO ONLINE
7 rows selected.
當有一個Start SCN號超過了System Checkpoint SCN號時,則說明控制文件不是當前的控制文件,因此在做recover時需要采用using backup controlfile。這是為什麼需要記錄SystemCheckpoint SCN的原因之一。
這裡需要一提的是,當重建控制文件的時候,System Checkpoint SCN為0,Datafile Checkpoint SCN的數據來自於Start SCN。根據上述的描述,此時需要采用using backup controlfile做recovery.
Oracle數據庫提供了兩種直接查看系統當前SCN的方法,一個是V$DATABASE中的CURRENT_SCN列,另外一個就是通過DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER得到。
SYS@ORACNSL1> COL SCN1 FOR 9999999999999
SYS@ORACNSL1> COL SCN2 FOR 9999999999999
SYS@ORACNSL1> COL SCN3 FOR 9999999999999
SYS@ORACNSL1> SELECT CURRENT_SCN SCN1,DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER SCN2,TIMESTAMP_TO_SCN(SYSDATE) SCN3 FROM V$DATABASE;
SCN1 SCN2 SCN3
-------------- -------------- ----------
1495460388 1495460388 1495460387
一般情況下,SCN1和SCN2的結果一致,但在系統比較繁忙的時候可能SCN2比SCN1稍微大一點,比如大1。
在oracle 9i中要麻煩些,V$DATABASE視圖中沒有CURRENT_SCN這列,只有通過查詢X$KTUXE視圖來得到。
SYS@lhrdb> SELECT MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB) SCN FROM X$KTUXE;
SCN
----------
8764198
Oracle 10g提供了兩個新函數對於SCN和時間戳進行相互轉換,這兩個函數是SCN_TO_TIMESTAMP、TIMESTAMP_TO_SCN,通過對SCN和時間戳進行轉換,Oracle極大地方便了很多備份和恢復過程。
一個SCN值總是發生在某一個特定的時刻的,只不過由於粒度的不一樣,通常會存在多個SCN對應同一個時間戳。Oracle中提供了兩個函數以供我們進行SCN和時間的互換:
l SCN_TO_TIMESTAMP(scn_number) 將SCN轉換成時間戳。
l TIMESTAMP_TO_SCN(timestamp) 將時間戳轉換成SCN。
通過這兩個函數,最終Oracle將SCN和時間的關系建立起來,在Oracle 10g之前,是沒有辦法通過函數轉換得到SCN和時間的對應關系的,一般可以通過logmnr分析日志獲得。但是這種轉換要依賴於數據庫內部的數據記錄(SMON_SCN_TIME),對於久遠的SCN則不能轉換,請看以下舉例:
SYS@lhrdb> SELECT MIN(FIRST_CHANGE#) SCN,DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER FROM V$ARCHIVED_LOG;
SCN GET_SYSTEM_CHANGE_NUMBER
---------- ------------------------
7527538 8763206
SYS@lhrdb> SELECT SCN_TO_TIMESTAMP(7527538) SCN FROM DUAL;
select scn_to_timestamp(7527538) scn from dual
*
ERROR at line 1:
ORA-08181: specified number is not a valid system change number
ORA-06512: at "SYS.SCN_TO_TIMESTAMP", line 1
SYS@lhrdb> select min(scn) from smon_scn_time;
MIN(SCN)
----------
8622517
SYS@lhrdb> select scn_to_timestamp(8622517) timestamp from dual;
TIMESTAMP
---------------------------------------------------------------------------
08-OCT-16 04.30.26.000000000 AM
SYS@lhrdb> select scn_to_timestamp(8622516) timestamp from dual;
select scn_to_timestamp(8622516) timestamp from dual
*
ERROR at line 1:
ORA-08181: specified number is not a valid system change number
ORA-06512: at "SYS.SCN_TO_TIMESTAMP", line 1
從上面的例子可以看出Oracle能夠轉換的最小SCN也就是SMON_SCN_TIME.scn的最小值。
SYS@lhrdb> SELECT SCN_TO_TIMESTAMP(8763206) SCN FROM DUAL;
SCN
---------------------------------------------------------------------------
10-OCT-16 05.22.40.000000000 PM
SYS@lhrdb> SELECT TIMESTAMP_TO_SCN(TO_TIMESTAMP('10-OCT-16 05.22.40.000000000 PM','DD-Mon-RR HH:MI:SS.FF AM')) SCN FROM DUAL;
SCN
----------
8763206
SYS@lhrdb> SELECT TIMESTAMP_TO_SCN(TO_TIMESTAMP('2016-10-10 17:22:40','YYYY-MM-DD HH24:MI:SS')) SCN FROM DUAL;
SCN
----------
8763206
SYS@lhrdb> SELECT TO_CHAR(SCN_TO_TIMESTAMP(8763206), 'YYYY-MM-DD HH24:MI:SS') CHR_DATE,TIMESTAMP_TO_SCN(SCN_TO_TIMESTAMP(8763206)) DT FROM DUAL;
CHR_DATE DT
------------------- ----------
2016-10-10 17:22:40 8763206
對於時間到SCN的轉換,Oracle只能定位到3秒以內,3秒內的時間都被轉換成同一個SCN:
SYS@lhrdb> SELECT TIMESTAMP_TO_SCN(TO_TIMESTAMP('2016-10-10 17:22:40','YYYY-MM-DD HH24:MI:SS')) SCN FROM DUAL;
SCN
----------
8763206
SYS@lhrdb> SELECT TIMESTAMP_TO_SCN(TO_TIMESTAMP('2016-10-10 17:22:41','YYYY-MM-DD HH24:MI:SS')) SCN FROM DUAL;
SCN
----------
8763206
SYS@lhrdb> SELECT TIMESTAMP_TO_SCN(TO_TIMESTAMP('2016-10-10 17:22:42','YYYY-MM-DD HH24:MI:SS')) SCN FROM DUAL;
SCN
----------
8763206
SYS@lhrdb> SELECT TIMESTAMP_TO_SCN(TO_TIMESTAMP('2016-10-10 17:22:43','YYYY-MM-DD HH24:MI:SS')) SCN FROM DUAL;
SCN
----------
8763213
SYS@lhrdb> SELECT TIMESTAMP_TO_SCN(TO_TIMESTAMP('2016-10-10 17:22:39','YYYY-MM-DD HH24:MI:SS')) SCN FROM DUAL;
SCN
----------
8763205
SELECT * FROM DBA_TABLES D WHERE D.TABLE_NAME = 'SMON_SCN_TIME';
Oracle 在內部都是使用scn,即使你指定的是as of timestamp,oracle 也會將其轉換成scn,系統時間標記與scn 之間存在一張表,即SYS下的SMON_SCN_TIME。
SYS@lhrdb> set linesize 80
SYS@lhrdb> desc sys.smon_scn_time
Name Null? Type
----------------------------------------- -------- ----------------------------
THREAD NUMBER
TIME_MP NUMBER
TIME_DP DATE
SCN_WRP NUMBER
SCN_BAS NUMBER
NUM_MAPPINGS NUMBER
TIM_SCN_MAP RAW(1200)
SCN NUMBER
ORIG_THREAD NUMBER
每隔5分鐘,系統產生一次系統時間標記與scn的匹配並存入sys.smon_scn_time 表,該表中記錄了最近1440個系統時間標記與scn的匹配記錄,由於該表只維護了最近的1440條記錄,因此如果使用as of timestamp的方式則只能flashback最近5天內的數據(假設系統是在持續不斷運行並無中斷或關機重啟之類操作的話)。
查看SCN 和 timestamp 之間的對應關系:
SELECT SCN, TO_CHAR(TIME_DP, 'YYYY-MM-DD HH24:MI:SS') TIME_DP
FROM SYS.SMON_SCN_TIME T
ORDER BY T.SCN DESC;
有關表SMON_SCN_TIME的更多內容可以參考我的BLOG:http://blog.itpub.net/26736162/viewspace-2126291/,David大神寫的,非常全面,我就不畫蛇添足了。
REDO LOG是Oracle為確保已經提交的事務不會丟失而建立的一個機制。實際上REDO LOG的存在是為兩種場景准備的,一種我們稱之為實例恢復(INSTANCE RECOVERY),一種我們稱之為介質恢復(MEDIA RECOVERY)。
REDO LOG的數據是按照THREAD來組織的,對於單實例系統來說,只有一個THREAD,對於RAC系統來說,可能存在多個THREAD,每個數據庫實例擁有一組獨立的REDO LOG文件,擁有獨立的LOG BUFFER,某個實例的變化會被獨立的記錄到一個THREAD的REDO LOG文件中。
對於單實例的系統,實例恢復一般是在數據庫實例異常故障後數據庫重啟時進行,當數據庫執行了SHUTDOWN ABORT或者由於操作系統、主機等原因宕機重啟後,在執行ALTER DATABASE OPEN的時候,就會自動做實例恢復。而在RAC環境中,如果某個實例宕機了,那麼剩下的實例將會代替宕掉的實例做實例恢復。除非是所有的實例都宕機了,這樣的話,第一個執行ALTER DATABASE OPEN的實例將會做實例恢復。這也是在RAC環境中,REDO LOG是實例私有的組件,但是REDO LOG的文件必須存放在共享存儲上的原因。
一個單實例數據庫或者RAC數據庫所有實例失敗之後,第一個打開數據庫的實例會自動執行實例恢復。這種形式的實例恢復稱為Crash恢復。一個RAC數據庫的一部分但不是所有實例失敗後,在RAC中幸存的實例自動執行失敗實例的恢復稱為實例恢復。一般而言,在崩潰或關機退出之後第一個打開數據庫的實例將自動執行崩潰恢復。
根據Crash恢復和實例恢復的不同,由幸存實例或者第一個重啟的實例讀取失敗實例生成的聯機Redo日志和UNDO表空間數據,使用這些信息確保只有已提交的事務被寫到數據庫中,回滾在失敗時候活動的事務,並釋放事務使用的資源。
[ZFZHLHRDB1:oracle]:/oracle>crsctl stat res -t
--------------------------------------------------------------------------------
NAME TARGET STATE SERVER STATE_DETAILS
--------------------------------------------------------------------------------
Local Resources
--------------------------------------------------------------------------------
ora.DATA.dg
ONLINE ONLINE zfzhlhrdb1
ONLINE ONLINE zfzhlhrdb2
ora.LISTENER.lsnr
ONLINE ONLINE zfzhlhrdb1
ONLINE ONLINE zfzhlhrdb2
ora.LISTENER_LHRDG.lsnr
ONLINE ONLINE zfzhlhrdb1
ONLINE ONLINE zfzhlhrdb2
ora.asm
ONLINE ONLINE zfzhlhrdb1 Started
ONLINE ONLINE zfzhlhrdb2 Started
ora.gsd
OFFLINE OFFLINE zfzhlhrdb1
OFFLINE OFFLINE zfzhlhrdb2
ora.net1.network
ONLINE ONLINE zfzhlhrdb1
ONLINE ONLINE zfzhlhrdb2
ora.ons
ONLINE ONLINE zfzhlhrdb1
ONLINE ONLINE zfzhlhrdb2
ora.registry.acfs
ONLINE ONLINE zfzhlhrdb1
ONLINE ONLINE zfzhlhrdb2
--------------------------------------------------------------------------------
Cluster Resources
--------------------------------------------------------------------------------
ora.LISTENER_SCAN1.lsnr
1 ONLINE ONLINE zfzhlhrdb1
ora.cvu
1 ONLINE ONLINE zfzhlhrdb1
ora.lhrdb.db
1 ONLINE ONLINE zfzhlhrdb1 Open
ora.oc4j
1 ONLINE ONLINE zfzhlhrdb1
ora.raclhr.db
1 ONLINE ONLINE zfzhlhrdb2 Open
2 ONLINE ONLINE zfzhlhrdb1 Open
ora.scan1.vip
1 ONLINE ONLINE zfzhlhrdb1
ora.zfzhlhrdb1.vip
1 ONLINE ONLINE zfzhlhrdb1
ora.zfzhlhrdb2.vip
1 ONLINE ONLINE zfzhlhrdb2
[ZFZHLHRDB1:oracle]:/oracle>srvctl stop instance -d raclhr -i raclhr1 -o abort
[ZFZHLHRDB1:oracle]:/oracle>srvctl status db -d raclhr
Instance raclhr1 is not running on node zfzhlhrdb1
Instance raclhr2 is running on node zfzhlhrdb2
abort掉實例1後:
實例一的告警日志:
Thu Oct 13 15:51:30 2016
Shutting down instance (abort)
License high water mark = 60
USER (ospid: 4194780): terminating the instance
Instance terminated by USER, pid = 4194780
Thu Oct 13 15:51:32 2016
Instance shutdown complete
實例二的告警日志:
Thu Oct 13 15:51:31 2016
Reconfiguration started (old inc 4, new inc 6)
List of instances:
2 (myinst: 2)
Global Resource Directory frozen
* dead instance detected - domain 0 invalid = TRUE
Communication channels reestablished
Master broadcasted resource hash value bitmaps
Non-local Process blocks cleaned out
Thu Oct 13 15:51:31 2016
LMS 0: 0 GCS shadows cancelled, 0 closed, 0 Xw survived
Thu Oct 13 15:51:31 2016
LMS 1: 0 GCS shadows cancelled, 0 closed, 0 Xw survived
Set master node info
Submitted all remote-enqueue requests
Dwn-cvts replayed, VALBLKs dubious
All grantable enqueues granted
Post SMON to start 1st pass IR
Thu Oct 13 15:51:31 2016
Instance recovery: looking for dead threads
Submitted all GCS remote-cache requests
Post SMON to start 1st pass IR
Fix write in gcs resources
Reconfiguration complete
Beginning instance recovery of 1 threads
parallel recovery started with 7 processes
Started redo scan
Completed redo scan
read 18 KB redo, 14 data blocks need recovery
Started redo application at
Thread 1: logseq 235, block 68352
Recovery of Online Redo Log: Thread 1 Group 1 Seq 235 Reading mem 0
Mem# 0: +DATA/raclhr/onlinelog/group_1.362.916601361
Mem# 1: +DATA/raclhr/onlinelog/group_1.361.916601361
Completed redo application of 0.01MB
Completed instance recovery at
Thread 1: logseq 235, block 68389, scn 9725527
14 data blocks read, 14 data blocks written, 18 redo k-bytes read
Thu Oct 13 15:51:33 2016
minact-scn: Inst 2 is now the master inc#:6 mmon proc-id:25100420 status:0x7
minact-scn status: grec-scn:0x0000.00000000 gmin-scn:0x0000.009417d9 gcalc-scn:0x0000.009417e3
minact-scn: master found reconf/inst-rec before recscn scan old-inc#:6 new-inc#:6
Thread 1 advanced to log sequence 236 (thread recovery)
Redo thread 1 internally disabled at seq 236 (SMON)
Thu Oct 13 15:51:34 2016
Thread 2 advanced to log sequence 265 (LGWR switch)
Current log# 4 seq# 265 mem# 0: +DATA/raclhr/onlinelog/group_4.349.916601715
Current log# 4 seq# 265 mem# 1: +DATA/raclhr/onlinelog/group_4.348.916601715
Thu Oct 13 15:51:35 2016
Archived Log entry 493 added for thread 1 sequence 235 ID 0x441b1480 dest 1:
Thu Oct 13 15:51:35 2016
ARC0: Archiving disabled thread 1 sequence 236
Archived Log entry 494 added for thread 1 sequence 236 ID 0x441b1480 dest 1:
Thu Oct 13 15:51:35 2016
Archived Log entry 495 added for thread 2 sequence 264 ID 0x441b1480 dest 1:
minact-scn: master continuing after IR
介質恢復是基於物理備份恢復數據,它是Oracle數據庫出現介質故障時恢復的重要保障。介質恢復包括塊恢復、數據文件恢復、表空間恢復和整個數據庫的恢復。介質恢復主要是針對錯誤類型中的介質失敗,如果是少量的塊失敗,那麼可以使用介質恢復中的塊恢復來快速修復;但如果是其它情況的丟失,那麼需要根據具體情況,可使用數據文件恢復、表空間恢復甚至全庫恢復,可以參考如下的表格:
錯誤分類
恢復解決方案
介質失敗
如果是少量的塊損壞,使用塊介質恢復;如果是大量的塊、數據文件、表空間的損壞,可能需要對損壞的數據文件或者表空間執行完全恢復;如果是歸檔REDO日志文件或者聯機REDO日志文件的丟失,那麼只需要不完全恢復方式。
邏輯損壞
如果是程序員錯誤導致出現的問題,可通過補丁應用修復問題。對於無法修復的問題,也可采用介質恢復手段來恢復數據。
用戶錯誤
根據不同用戶錯誤,選擇不同的FLASHBACK技術恢復,使用FLASHBACK技術恢復用戶錯誤是首選方案。如果FLASHBACK不能很好的恢復數據再考慮使用介質恢復或者表空間時間點恢復。
Oracle數據庫的介質恢復實際上包含了兩個過程:數據庫還原(RESTORE)與數據庫恢復(RECOVER)。
數據庫還原(RESTORE)是指利用備份的數據庫文件來替換已經損壞的數據庫文件或者將其恢復到一個新的位置。RMAN在進行還原操作時,會利用恢復目錄(有建立恢復目錄的話就使用目標數據庫的控制文件)來獲取備份信息,並從中選擇最合適的備份進行修復操作。選擇備份時有兩個原則:1、選擇距離恢復目錄時刻最近;2、優先選擇鏡像復制,其次才是備份集。
數據庫恢復(RECOVER)是指數據文件的介質恢復,即為修復後的數據文件應用聯機或歸檔日志,從而將修復的數據庫文件更新到當前時刻或指定時刻下的狀態。在執行恢復數據庫時,需要使用RECOVER命令。
還原是將某個時間點數據文件的拷貝再拷貝回去,還原後的數據庫處於不一致性的狀態,或不是最新的狀態,還需要執行恢復操作。恢復就是使用歸檔REDO日志文件和聯機REDO日志文件將不一致的數據庫應用到一致性狀態。
需要注意的是,還原只是建立在數據庫備份的基礎版本上,例如,如果數據庫備份包括0級備份和很多1級備份,還原只是應用0級備份,恢復過程會根據情況自動應用1級備份或REDO日志將數據庫恢復到一致性的狀態。
數據庫的恢復過程根據恢復數據的程度又分為完全恢復(Complete Recovery)和不完全恢復(Incomplete Recovery)。
完全恢復是一種沒有數據丟失的恢復方式,能夠恢復到最新的聯機REDO日志中已提交的數據。在傳統恢復方式中,因介質失敗破壞了數據文件之後,可以在數據庫、表空間和數據文件上執行完全介質恢復。
不完全恢復是一種與完全恢復相反的恢復方式,是一種丟失數據的恢復方式,也稱為數據庫基於時間點恢復(Point-in-Time Recovery),是將整個數據庫恢復到之前的某個時間點、日志序列號或者SCN號。通常情況下,若FLASHBACK DATABASE沒有啟用或者變得無效,可以執行不完全恢復撤銷一個用戶錯誤。不完全恢復不一定在原有的數據庫環境執行,可以在測試環境下執行不完全恢復,將找回的數據再重新導入生產庫中。不完全恢復根據備份情況恢復到與指定時間、日志序列號和SCN具有一致性的數據,之後的數據都將丟失。執行不完全恢復一方面是因為歸檔REDO日志、聯機REDO日志的丟失不得不執行不完全恢復,另一方面可能是因為在某個時刻錯誤地操作了數據,過了一段時間之後才發現問題,而其它的恢復手段都無法恢復數據,這時也不得不使用不完全恢復來找回數據。執行不完全恢復必須從備份中還原所有的數據文件,備份文件必須是要恢復的時間點之前創建的。當恢復完成,使用RESTLOGS選項打開數據庫,將重新初始化聯機Redo日志,創建一個新的日志序列號流,日志序列號從1開始,RESETLOGS之後的SCN還是在遞增。
如果是完全恢復,那麼數據庫就是最新的一致性狀態;如果是不完全恢復,那麼數據庫是非最新的一致性狀態。對於非歸檔模式的數據庫來說,不能執行不完全恢復。
不完全恢復的選項如下表所示:
不完全恢復方式
RMAN選項
用戶管理備份選項
恢復到某個時間點
UNTIL TIME
UNTIL TIME
恢復到某個日志序列號
UNTIL SUQUENCE
UNTIL CANCEL
恢復到某個SCN號
UNTIL SCN
UNTIL CHANGE
不完全恢復的幾種類型如下表所示(注意:下圖是小麥苗即將出版的書上的一個表格,現在提前分享給大家):
綜上所述,恢復的分類大致可以如下圖所示的分類(注意:下圖也是小麥苗即將出版的書上的一個表格,現在提前分享給大家):
About Me
...............................................................................................................................
● 本文作者:小麥苗,只專注於數據庫的技術,更注重技術的運用
● 本文在itpub(http://blog.itpub.net/26736162)、博客園(http://www.cnblogs.com/lhrbest)和個人微信公眾號(xiaomaimiaolhr)上有同步更新
● 本文itpub地址:http://blog.itpub.net/26736162/viewspace-2126407/
● 本文博客園地址:http://www.cnblogs.com/lhrbest/p/5961987.html
● 本文pdf版:http://yunpan.cn/cdEQedhCs2kFz (提取碼:ed9b)
● 小麥苗雲盤地址:http://blog.itpub.net/26736162/viewspace-1624453/
● QQ群:230161599 微信群:私聊
● 聯系我請加QQ好友(642808185),注明添加緣由
● 於 2016-10-08 15:00~ 2016-10-14 23:00 在中行完成
● 文章內容來源於小麥苗的學習筆記,部分整理自網絡,若有侵權或不當之處還請諒解!
● 【版權所有,文章允許轉載,但須以鏈接方式注明源地址,否則追究法律責任】
...............................................................................................................................
手機長按下圖識別二維碼或微信客戶端掃描下邊的二維碼來關注小麥苗的微信公眾號:xiaomaimiaolhr,免費學習最實用的數據庫技術。