藉助SCN的變化來理解oracle備份與恢複的基本原理

來源:互聯網
上載者:User

    SCN是oracle掛在牆上的時鐘。早上起床,曰“起床SCN”;吃早餐,名“早餐SCN”;出門上班,稱之為“出門SCN”。我們的任何活動,都會對應一個SCN。我們可藉助oracle內部的一個包來擷取系統的SCN(注意:這裡只是系統的scn,因為,oracle還有commit scn,checkpoint scn,select scn等等)。

SQL> select dbms_flashback.get_system_change_number "system's scn" from dual;system's scn------------      555956

    oracle內部只有一個SCN,其他的都是來自它。我們還可以看一下資料庫裡面最小的SCN。

SQL> select creation_change# "oracle內部最小scn" from v$datafile where file#=1;oracle內部最小scn-----------------                9

    我們加在oracle身上的事,無論好壞,oracle都會依據SCN,一一記在心裡(日誌),莫敢相忘。由於SCN是遞增的,我們對應到相關的SCN,就能找到那個時刻,我們對oracle所做的事。這便是SCN的重要性。
    我們對oracle所在的事,她會記在當前日誌組。我們可以用v$log來查詢。

SQL> select group#,sequence#,status from v$log;    GROUP#  SEQUENCE# STATUS---------- ---------- ----------------         1          5 CURRENT         2          3 INACTIVE         3          4 INACTIVE

    接下來,我們對oracle做件事。我們建個表t,有兩個欄位。其中,欄位scn可以約等於事務開始的scn。

  SQL> create table t(id int,scn number) tablespace users;Table created.SQL> insert into t values(1,dbms_flashback.get_system_change_number);1 row created.SQL> commit;Commit complete.SQL> select * from t;        ID        SCN---------- ----------         1     585887

    我們先把這件事緩緩,來看看v$log裡面的first_change#。

SQL> alter session set nls_date_format='yyyy/mm/dd hh24:mi:ss';Session altered.SQL> select group#,status,first_change#,first_time from v$log;    GROUP# STATUS           FIRST_CHANGE# FIRST_TIME---------- ---------------- ------------- -------------------         1 CURRENT                 583374 2012/07/17 19:59:23         2 INACTIVE                560959 2012/07/17 17:13:32         3 INACTIVE                560981 2012/07/17 17:14:33

    這裡的first_change#和first_time是一樣的,都是SCN的兩種表現形式。first_change#是日誌組成為當前日誌組時所取的系統的SCN,來作為這一組最小或者開始的SCN。我們所做的事,對應的SCN,都會比first_change#來得大。
    繼續我們的事,我們把當前日誌組歸檔。

SQL> alter system switch logfile;System altered.

    再瞧瞧v$log裡面的first_change#

SQL> select group#,status,first_change#,first_time from v$log;    GROUP# STATUS           FIRST_CHANGE# FIRST_TIME---------- ---------------- ------------- -------------------         1 ACTIVE                  583374 2012/07/17 19:59:23         2 CURRENT                 586090 2012/07/18 09:35:40         3 INACTIVE                560981 2012/07/17 17:14:33

    現在當前日誌組變成了第2組,first_change#也發生了變化。
    再來繼續我們未完的事。

SQL> insert into t values(2,dbms_flashback.get_system_change_number);1 row created.SQL> commit;Commit complete.SQL> select * from t;        ID        SCN---------- ----------         1     585887         2     586129

    從這裡我們可以看出,586129比當前日誌組2的first_change#(586090)大。從而,證明了first_change#是當前日誌組最小的SCN,之後,我們所做的任何事,產生的SCN,都會比這個來得大。
    我們再日誌卻,將日誌組2歸檔。

SQL> alter system switch logfile;System altered.SQL> select group#,status,first_change#,first_time from v$log;    GROUP# STATUS           FIRST_CHANGE# FIRST_TIME---------- ---------------- ------------- -------------------         1 ACTIVE                  583374 2012/07/17 19:59:23         2 ACTIVE                  586090 2012/07/18 09:35:40         3 CURRENT                 586181 2012/07/18 09:39:21

    現在,日誌組3變成了當前日誌組了,相應的first_change#也發生了變化。
    再來繼續我們事情。為了產生更多的歸檔日誌,我們不斷的插入,提交,卻換。

SQL> insert into t values(3,dbms_flashback.get_system_change_number);1 row created.SQL> commit;Commit complete.SQL> alter system switch logfile;System altered.SQL> insert into t values (4,dbms_flashback.get_system_change_number);1 row created.SQL> commit;Commit complete.SQL> alter system switch logfile;System altered.SQL> insert into t values (5,dbms_flashback.get_system_change_number);1 row created.SQL> commit;     Commit complete.SQL> alter system switch logfile;System altered.SQL> insert into t values(6,dbms_flashback.get_system_change_number);1 row created.SQL> commit;Commit complete.SQL> alter system switch logfile;System altered.SQL> insert into t values (7,dbms_flashback.get_system_change_number);1 row created.SQL> commit;Commit complete.SQL> alter system switch logfile;System altered.SQL> insert into t values (8,dbms_flashback.get_system_change_number);1 row created.SQL> commit;Commit complete.SQL> alter system switch logfile;System altered.SQL> select * from t;        ID        SCN---------- ----------         1     585887         2     586129         3     586643         4     586666         5     586692         6     586722         7     586751         8     586805

    我們再來看一下,當前日誌組是哪一組?

SQL> select group#,status,first_change#,first_time from v$log;    GROUP# STATUS           FIRST_CHANGE# FIRST_TIME---------- ---------------- ------------- -------------------         1 ACTIVE                  586734 2012/07/18 09:45:12         2 ACTIVE                  586762 2012/07/18 09:46:15         3 CURRENT                 586816 2012/07/18 09:47:15

    當前的日誌組是3.那麼,我們再來插入。

SQL> insert into t values(9,dbms_flashback.get_system_change_number);1 row created.SQL> commit;Commit complete.

    這時,我們並沒有卻換日誌組。然後,再插入。

SQL> insert into t values(10,dbms_flashback.get_system_change_number);1 row created.

    注意了,此時,我們沒有提交也沒有卻換。那麼,第9,10條的資料都在日誌組3上面。
    這裡,我們類比一個實驗來闡述備份與恢複的基本原理。
    實驗:順利關機下,資料檔案損壞的完全恢複。

[oracle@localhost ~]$ sqlplus /nologSQL*Plus: Release 10.2.0.1.0 - Production on Tue Jul 17 20:48:19 2012Copyright (c) 1982, 2005, Oracle.  All rights reserved.SQL> conn / as sysdbaConnected.SQL> shutdown immediateDatabase closed.Database dismounted.ORACLE instance shut down.[oracle@localhost ORCL]$ cd datafile/[oracle@localhost datafile]$ lso1_mf_example_8050jhm7_.dbf  o1_mf_temp_8050j34j_.tmpo1_mf_sysaux_8050fk3w_.dbf   o1_mf_undotbs1_8050fkc6_.dbfo1_mf_system_8050fk2z_.dbf   o1_mf_users_8050fkdh_.dbf[oracle@localhost datafile]$ rm o1_mf_system_8050fk2z_.dbf[oracle@localhost datafile]$ rm o1_mf_sysaux_8050fk3w_.dbf[oracle@localhost datafile]$ rm o1_mf_users_8050fkdh_.dbf [oracle@localhost datafile]$ rm o1_mf_undotbs1_8050fkc6_.dbf

    這個時候,假如我們要啟動資料庫會報什麼錯呢?

[oracle@localhost ~]$ sqlplus /nologSQL*Plus: Release 10.2.0.1.0 - Production on Tue Jul 17 20:57:00 2012Copyright (c) 1982, 2005, Oracle.  All rights reserved.SQL> conn / as sysdbaConnected to an idle instance.SQL> startupORACLE instance started.Total System Global Area  419430400 bytesFixed Size                  1219760 bytesVariable Size             142607184 bytesDatabase Buffers          272629760 bytesRedo Buffers                2973696 bytesDatabase mounted.ORA-01157: cannot identify/lock data file 1 - see DBWR trace fileORA-01110: data file 1:'/u01/app/oracle/oradata/ORCL/datafile/o1_mf_system_8050fk2z_.dbf'

    因為,有控制檔案,所以,我們會到mount狀態,這是個oracle的介態。這個狀態,我們可以做很多事。這時,它報檔案1不能鎖定。那麼,我們一個個來。先把冷備的檔案1拷來。
    [oracle@localhost datafile]$ cp o1_mf_system_8050fk2z_.dbf  /u01/app/oracle/oradata/ORCL/datafile
    然後,再來開啟資料庫,看會報什麼錯?

SQL> alter database open;alter database open*ERROR at line 1:ORA-01113: file 1 needs media recoveryORA-01110: data file 1:'/u01/app/oracle/oradata/ORCL/datafile/o1_mf_system_8050fk2z_.dbf'

    這個時候報的錯誤不一樣了。報檔案1需要媒介恢複。oracle是根據什麼報這個錯誤的呢?要瞭解這個,我們需要藉助兩個視圖。

SQL> select file#,checkpoint_change# from v$datafile;     FILE# CHECKPOINT_CHANGE#---------- ------------------         1             587004         2             587004         3             587004         4             587004         5             587004SQL> select file#,checkpoint_change# from v$datafile_header;     FILE# CHECKPOINT_CHANGE#---------- ------------------         1             583375         2                  0         3                  0         4                  0         5             587004

    這兩個視圖所取的資訊來源完全不一樣。v$datafile的資訊來自控制檔案;v$datafile_header的資訊則來自每個資料檔案的檔案頭。我們剛剛已經把file 1拷回來,所以,oracle可以讀到它頭上的scn。而2,3,4已經被刪了便是讀不到的。但是,file 1在兩處的scn不一致。記住了,oracle會橫向比較,縱向是不會比較的。即:不會拿file 1和file 3比較。oracle開啟的必要條件是控制檔案和資料檔案的檔案頭的scn要一致。那麼大於583375,而小於585469的scn都在歸檔日誌裡面。每個scn對應相關的操作。

SQL> select sequence#,first_change#,next_change# from v$archived_log; SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#---------- ------------- ------------         5        544404       558719         6        558719       559931         7        559931       560709         8        560709       560959         9        560959       560981        10        560981       583374

    什麼是next_change#?日誌組由當前日誌組卻換到非當前日誌組時,所取的系統scn,來作為它的最大scn。first_change#是它成為current的開始;而next_change#則是它結束了current生涯的標誌。
    我們知道,比583375小的scn都已經寫入資料檔案。現在,我們需要確定583375是落在哪對first_change#和next_change#之間。從而確定廣義前滾的起點。

SQL> select sequence#,first_change#,next_change# from v$archived_log  2  where 583375>=first_change# and  3  583375<=next_change#; SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#---------- ------------- ------------        11        583374       586090

    由此,我們知道,583375落在歸檔日誌11的first_change#和next_change#之間。我們恢複的時候,就從歸檔日誌11開始。那麼,我們到底需要多少的歸檔日誌呢?

SQL> select sequence#,first_change#,next_change# from v$archived_log  2  where sequence#>=11; SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#---------- ------------- ------------        11        583374       586090        12        586090       586181        13        586181       586656        14        586656       586676        15        586676       586704        16        586704       586734        17        586734       586762        18        586762       586816

    從上面可知,如果我們想把資料全部找回,我們需要藉助到歸檔日誌18.我們看一下這些first_change#和next_change#有什麼特色?
    歸檔日誌11的next_change#是歸檔日誌12的first_change#。以此類推,所以,這麼多的歸檔日誌,其實,邏輯上就只是一個歸檔日誌。因此,歸檔日誌必須連續!如果,你歸檔日誌13壞了,那麼只能恢複到12的next_change#。後面再多的歸檔也是徒然。
    接下來,我們開始恢複。

SQL> recover datafile 1;ORA-00279: change 583375 generated at 07/17/2012 19:59:23 needed for thread 1ORA-00289: suggestion :/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_11_%u_.arcORA-00280: change 583375 for thread 1 is in sequence #11Specify log: {<RET>=suggested | filename | AUTO | CANCEL}

    oracle告訴我們,583375 對於執行個體是需要的。並且,歸檔日誌11在閃回區。如果敲斷行符號,則採納oracle的建議,oracle會自己到閃回區裡面去找。我們敲一下斷行符號鍵採納oracle的建議。第二個選項,是不在預設路徑裡面,由你來告訴oracle,歸檔日誌身在何處。你只要告訴oracle,歸檔日誌的絕對路徑+名稱,就可以了。第三個選項,如果歸檔日誌很多,一個個挨著去找,顯得很麻煩,那麼我們就去auto。第四個選項,如果恢複到一半,或者,沒有了歸檔日誌,那麼你可以敲cancel。

ORA-00279: change 586090 generated at 07/18/2012 09:35:40 needed for thread 1ORA-00289: suggestion :/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_12_%u_.arcORA-00280: change 586090 for thread 1 is in sequence #12ORA-00278: log file'/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_11_80d4qdmh_.arc' no longer needed for this recoverySpecify log: {<RET>=suggested | filename | AUTO | CANCEL}

    這時,oracle會再告訴我們,日誌12是執行個體所需要的。我們先把這事給擱著。先去資料檔案檔案頭,把scn給取出來瞧瞧。

SQL> select file#,checkpoint_change# from v$datafile_header;     FILE# CHECKPOINT_CHANGE#---------- ------------------         1             586090         2                  0         3                  0         4                  0         5             587004

    發現沒?file 1 的scn變成了586090。而586090是歸檔日誌12的first_change#。難怪oracle告訴我們日誌12是執行個體必須的。接下來,我們敲auto。

Specify log: {<RET>=suggested | filename | AUTO | CANCEL}autoORA-00279: change 586181 generated at 07/18/2012 09:39:21 needed for thread 1ORA-00289: suggestion :/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_13_%u_.arcORA-00280: change 586181 for thread 1 is in sequence #13ORA-00278: log file'/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_12_80d4y9fp_.arc' no longer needed for this recoveryORA-00279: change 586656 generated at 07/18/2012 09:42:06 needed for thread 1ORA-00289: suggestion :/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_14_%u_.arcORA-00280: change 586656 for thread 1 is in sequence #14ORA-00278: log file'/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_13_80d53g42_.arc' no longer needed for this recoveryORA-00279: change 586676 generated at 07/18/2012 09:42:59 needed for thread 1ORA-00289: suggestion :/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_15_%u_.arcORA-00280: change 586676 for thread 1 is in sequence #15ORA-00278: log file'/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_14_80d5541h_.arc' no longer needed for this recoveryORA-00279: change 586704 generated at 07/18/2012 09:44:03 needed for thread 1ORA-00289: suggestion :/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_16_%u_.arcORA-00280: change 586704 for thread 1 is in sequence #16ORA-00278: log file'/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_15_80d57315_.arc' no longer needed for this recoveryLog applied.Media recovery complete.

    發現沒?oracle只運用了歸檔日誌到16。接下來的17,18就沒有再提示了。為什嗎?我們先去資料檔案的檔案頭把file 1的scn再取來看看。

SQL> select file#,checkpoint_change# from v$datafile_header;     FILE# CHECKPOINT_CHANGE#---------- ------------------         1             587003         2                  0         3                  0         4                  0         5             587004

    587003是不是比歸檔日誌18的next_change#(586816)來得大呢。我們再來看看,當前日子組是哪一組。

SQL> select group#,sequence#,status,first_change# from v$log;    GROUP#  SEQUENCE# STATUS           FIRST_CHANGE#---------- ---------- ---------------- -------------         1         17 INACTIVE                586734         3         19 CURRENT                 586816         2         18 INACTIVE                586762

    可以看出,歸檔日誌19的first_change#為586816。而資料檔案頭的scn是587003。當我們敲recover datafile 1時,oracle在做完全恢複。完全恢複的起點和終點是已經確定了。起點在資料檔案的檔案頭,終點在控制檔案裡擷取。因為,歸檔重做記錄檔17,18是從聯機重做記錄檔1,2裡面讀出來的。oracle會優先去找聯機重做記錄檔。或者說,完全恢複時,oracle會自己去找聯機重做記錄檔;不完全恢複,我們可以把online redo log file的絕對路徑和名稱輸進去。當前日誌組是3,它的first_change#為586816,而587003比這個數大。可見,oracle也將當前記錄檔給用上了。
    接著恢複。這次,我們把剩餘的資料檔案全部拷回。然後大家一起往前走,直到步伐一致時,才能夠同時停下來,這樣子,oracle就處於一致的狀態了。

SQL> recover database;ORA-00279: change 583375 generated at 07/17/2012 19:59:23 needed for thread 1ORA-00289: suggestion :/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_11_%u_.arcORA-00280: change 583375 for thread 1 is in sequence #11Specify log: {<RET>=suggested | filename | AUTO | CANCEL}autoORA-00279: change 586090 generated at 07/18/2012 09:35:40 needed for thread 1ORA-00289: suggestion :/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_12_%u_.arcORA-00280: change 586090 for thread 1 is in sequence #12ORA-00278: log file'/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_11_80d4qdmh_.arc' no longer needed for this recoveryORA-00279: change 586181 generated at 07/18/2012 09:39:21 needed for thread 1ORA-00289: suggestion :/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_13_%u_.arcORA-00280: change 586181 for thread 1 is in sequence #13ORA-00278: log file'/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_12_80d4y9fp_.arc' no longer needed for this recoveryORA-00279: change 586656 generated at 07/18/2012 09:42:06 needed for thread 1ORA-00289: suggestion :/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_14_%u_.arcORA-00280: change 586656 for thread 1 is in sequence #14ORA-00278: log file'/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_13_80d53g42_.arc' no longer needed for this recoveryORA-00279: change 586676 generated at 07/18/2012 09:42:59 needed for thread 1ORA-00289: suggestion :/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_15_%u_.arcORA-00280: change 586676 for thread 1 is in sequence #15ORA-00278: log file'/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_14_80d5541h_.arc' no longer needed for this recoveryORA-00279: change 586704 generated at 07/18/2012 09:44:03 needed for thread 1ORA-00289: suggestion :/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_16_%u_.arcORA-00280: change 586704 for thread 1 is in sequence #16ORA-00278: log file'/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_07_18/o1_mf_1_15_80d57315_.arc' no longer needed for this recoveryLog applied.Media recovery complete.

    接下來,我們就可以開啟資料庫了。

SQL> alter database open;Database altered.

  事務對應的scn如果落在了哪個archivelog裡,那麼這個archivelog在恢複時就被用到  .

 總結,這篇部落格裡,我利用SCN和順利關機下資料檔案損壞的完全恢複來協助自己和大家一起理解oracle備份與恢複的原理。如果有足,希望走過路過的網友,給力批評。oracle的備份與恢複是門藝術。大家一起成長。go for it。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.