小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

深入淺出Oracle學習筆記(6)

 cinnamon 2011-10-09
第六章重做(Redo

 

Redo的內(nèi)容

Oracle通過Redo來實現(xiàn)快速提交,一方面是因為Redo Log File可以連續(xù)、順序地快速寫出,另一個方面也和Redo記錄的精簡內(nèi)容有關(guān)。

兩個概念:

改變向量(Change Vector

改變向量表示對數(shù)據(jù)庫內(nèi)某一個數(shù)據(jù)塊所做的一次變更。改變向量中包含了變更的數(shù)據(jù)塊的版本號、事務(wù)操作代碼、變更從屬數(shù)據(jù)塊的地址(DBA)以及更新后的數(shù)據(jù)。例如:一個update事務(wù)包含一系列的改變向量,對于數(shù)據(jù)塊的修改是一個向量,對于回滾段的修改又是一個向量。

重做記錄(Redo Record

重做記錄通常由一組改變向量組成,是一個改變向量的集合,代表一個數(shù)據(jù)庫的變更(INSERTUPDATE、DELETE等操作),構(gòu)成數(shù)據(jù)庫變更的最小恢復(fù)單位。例如:一個Update的重做記錄包括相應(yīng)的回滾段的改變向量和相應(yīng)的數(shù)據(jù)塊的改變向量等。

 

假定發(fā)出一個更新語句:

Update emp set sal=4000 where empno=7788;

這個語句的執(zhí)行如下所示:

檢查empno=7788記錄在Buffer Cache中是否存在,如果不存在則讀取到Buffer Cache中;

在回滾段表空間的相應(yīng)回滾段事務(wù)表上分配事務(wù)槽,這個操作需要記錄Redo信息;

從回滾段讀入或者在Buffer Cache中創(chuàng)建sal=3000的前鏡像,這需要產(chǎn)生Redo信息并記入Redo Log Buffer;

修改sal=4000,這是update的數(shù)據(jù)變更,需要記入Redo Log Buffer;

當用戶提交時,會在Redo Log Buffer記錄提交信息,并在回滾段標記該事務(wù)為非激活。

 

對于數(shù)據(jù)塊的修改,如果執(zhí)行寫出,那么通常需要寫出8KBBlock,而對于Redo日志來說,重做信息卻相當精簡,Oracle只需要記錄那些重構(gòu)事務(wù)必須的信息(如事務(wù)號、文件號、塊號、行號、字段等)即可,這個數(shù)據(jù)量大大減少。

 

產(chǎn)生多少Redo

SQL*Plus中使用autotrace功能

當在SQL*Plus中啟用autotrace跟蹤后,在執(zhí)行了特定的DML語句時,Oracle會顯示該語句的統(tǒng)計信息,其中,Redo size一欄表示的就是該操作產(chǎn)生的Redo的數(shù)量:

SQL> set autotrace trace stat

SQL> insert into test

 2 select empno,ename from scott.emp;

已創(chuàng)建12行。

Statistics

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

       189 recursive calls

         2 db block gets

        37 consistent gets

         4 physical reads

       564 redo size

       778 bytes sent via SQL*Net to client

       823 bytes received via SQL*Net from client

         4 SQL*Net roundtrips to/from client

         1 sorts (memory)

         0 sorts (disk)

        12 rows processed

 

通過v$mystat查詢:

Oracle通過v$mystat視圖記錄當前session的統(tǒng)計信息,也可以從該視圖中查詢得到sessionRedo生成情況:

SQL> col name for a30

SQL> select a.name,b.value

 2 from v$statname a,v$mystat b

 3 where a.statistic#=b.statistic# and a.name='redo size';

 

NAME                               VALUE

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

redo size                              5000

 

SQL> insert into test

 2 select empno,ename from scott.emp;

已創(chuàng)建12行。

 

SQL> select a.name,b.value

 2 from v$statname a,v$mystat b

 3 where a.statistic#=b.statistic# and a.name='redo size';

 

NAME                               VALUE

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

redo size                              5564

 

SQL> select 5564-5000 from dual;

 

 5564-5000

----------

      564

 

通過v$sysstat查詢:

對于數(shù)據(jù)庫全局redo的生成量,可以通過v$sysstat視圖來查詢得到:

SQL> col value for 999999999999

SQL> select name,value from v$sysstat

 2 where name='redo size';

 

NAME                                  VALUE

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

redo size                          11471552

 

v$sysstat視圖中得到的是自數(shù)據(jù)庫實例啟動以來累計日志生成量,可以根據(jù)實例啟動時間來大致估算每天數(shù)據(jù)庫的日志生成量:

SQL> select

 2 (select value/1024/1024/1024 from v$sysstat where name='redo size')/

 3 (select sysdate-(select startup_time from v$instance) from dual)

 4 redo_gb_per_day from dual;

 

REDO_GB_PER_DAY

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

    .073238253

 

 

Redo寫的觸發(fā)條件:

3秒鐘超時(Timeout

LGWR處于空閑狀態(tài)時,它依賴于rdbms ipc message等待,處于休眠狀態(tài),直到3秒超時時間到,如果LGWR發(fā)現(xiàn)有Redo需要寫出,那么LGWR將執(zhí)行寫出操作,log file parallel write等待時間將會出現(xiàn)。

啟用10046事件,從LGWR跟蹤文件中可以觀察到這些事件。

 

域值達到:

兩個觸發(fā)日志寫的條件:

Redo Log Buffer 1/3滿;

Redo Log Buffer具有1MB臟數(shù)據(jù)。

這兩者都是限制條件,在觸發(fā)時是協(xié)同生效的。

只要有進程在Log Buffer中分配和使用空間,已經(jīng)使用的Log Buffer的數(shù)量將被計算。如果使用的塊的數(shù)量大于或等于一個隱含參數(shù)_log_io_size的設(shè)置,那么將會觸發(fā)LGWR寫操作。如果此時LGWR未處于活動狀態(tài),那么LGWR將被通知去執(zhí)行后臺寫操作。

缺省的_log_io_size等于1/3log buffer大小,上限值為1MB,此參數(shù)在X$KSPPSV中顯示的0值意為缺省值。

也就是LGWR將在Min(1M,1/3 log buffer size)時觸發(fā),注意此處的log buffer size是以Log Block來衡量的。

經(jīng)常有人推薦Log Buffer設(shè)置為3MB大小,就是因為當Redo Log Buffer3MB時,以上兩個條件可能同時達到。

 

用戶提交

當一個事務(wù)提交時,在Redo Stream中將記錄一個提交標志。在這些Redo被寫到磁盤上之前,這個事務(wù)是不可恢復(fù)的。所以在事務(wù)返回成功標志給用戶前,必須等待LGWR寫完成。進程通知LGWR寫,并且以Log File Sync事件開始休眠,超時時間為1秒。

Oracle的隱含參數(shù)_wait_for_sync參數(shù)可以設(shè)置為false來避免Redo File Sync的等待,但是將無法保證事務(wù)的恢復(fù)性。

存在一個SGA變量用以記錄Redo線程序要同步的Log Block Number。如果多個提交在喚醒LGWR之前發(fā)生,此變量記錄最高的Log Block Number,在此之前的所有Redo都將被寫入磁盤,這有時被稱為組提交。

 

DBWn寫之前

 

Redo Log Buffer的大小設(shè)置

Redo Log Buffer的大小由初始化參數(shù)LOG_BUFFER定義,該參數(shù)的缺省值為:

MAX(512KB,128KB*CPU_COUNT)

通常這個缺省值是足夠的,由于Redo Log Buffer的寫出操作相當頻繁,所以過大的Log Buffer設(shè)置通常是沒有必要的。如果缺省值不能滿足要求,一般來說3MB是一個較合理的調(diào)整開端。

log_buffer參數(shù)的設(shè)置是否需要調(diào)整,可以從數(shù)據(jù)庫的等待事件來判斷:

SQL> select event#,name from v$event_name where name='log buffer space';

   EVENT# NAME

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

      178 log buffer space

Log Buffer Space等待事件出現(xiàn)并且較為顯著時,可以考慮增大Log Buffer以縮減競爭。

 

Commit做了什么

當完成事務(wù)操作,發(fā)出Commit命令之后,隨后會收到一個反饋“Commit complete”。

提交完成,意味著Oracle已經(jīng)將此時間點之前的Redo寫入重做日志文件中,這個日志寫完成之后,Oracle可以釋放用戶去執(zhí)行其他任務(wù)。如果此后發(fā)生數(shù)據(jù)庫崩潰,那么Oracle可以從重做日志文件中恢復(fù)這些提交過的數(shù)據(jù),從而保證提交之后的數(shù)據(jù)不會丟失。

 

日志的狀態(tài)

CURRENT:指的是當前的日志文件,該日志文件是活動的,當前正在被使用的,在進行崩潰恢復(fù)時,Current的日志文件時必須的。

ACTIVE:活動的非當前日志,該日志可能已經(jīng)完成歸檔也可能沒有歸檔,活動的日志文件在Crash恢復(fù)時會被用到。

ACITVE狀態(tài)意味著檢查點尚未完成,如果日志文件循環(huán)使用再次到達該文件,數(shù)據(jù)庫將處于等待的停頓狀態(tài),此時在alert文件中,可以看到類似如下記錄:Checkpoint not complete

當這種問題出現(xiàn)時,可以從數(shù)據(jù)庫內(nèi)部通過v$session_wait來觀察,該視圖會顯示數(shù)據(jù)庫當前哪些session正處于這種等待。

Checkpoint not complete在數(shù)據(jù)庫中體現(xiàn)為等待事件log file switch(checkpoint incomplete)

SQL> select sid,event,state from v$session_wait;

在此同時,可能DBWR進程正在進行db file parallel write,日志文件必須等待DBWR完成檢查點觸發(fā)的寫操作之后才能被覆蓋。如果設(shè)置了參數(shù)log_checkpoints_to_alertTRUE的話,還可以在alert文件中清晰地看到檢查點的增進和完成情況。

引起Checkpoint Incomplete可能有以下多種原因:

日志文件過小,切換過于頻繁;

日志組太少,不能滿足正常業(yè)務(wù)量的需要;

日志文件所在磁盤I/O存在瓶頸,導(dǎo)致寫出緩慢,阻塞數(shù)據(jù)庫正常運行;

由于數(shù)據(jù)文件磁盤I/O瓶頸,DBWR寫出過于緩慢;

由于事務(wù)量巨大,DBWR負載過高,不堪重負。

解決方法:

適當增加日志文件大??;

適當增加日志組數(shù);

使用更快的磁盤存儲日志文件(如采用更高轉(zhuǎn)速磁盤;使用RAID10而不是RAID5等方式);

改善磁盤I/O的性能

使用多個DBWR進程或使用異步I/O等。

 

注意:Checkpoint Incomplete是一類嚴重的等待,它意味著數(shù)據(jù)庫不能再產(chǎn)生日志,所有數(shù)據(jù)庫修改操作將全部掛起。

 

INACTIVE:非活動日志,該日志在實例恢復(fù)時不再需要,但是在介質(zhì)恢復(fù)時可能會用到。INACTIVE狀態(tài)的日志也可能沒有被歸檔。如果數(shù)據(jù)庫啟動在歸檔模式,在未完成歸檔之前,日志文件也不允許被覆蓋,這時候活動進程會處于log file switch(archiving needed)等待之中。

日志是否完成歸檔,可以根據(jù)v$log視圖的archived字段進行判斷。

 

UNUSED:是指該日志從未被寫入,這類日志可能是剛被添加到數(shù)據(jù)庫或者在RESETLOGS之后被重置。被使用之后,該狀態(tài)會被改變。

 

日志塊的大?。?/SPAN>

初始化參數(shù)LOG_BUFFER決定了Redo Log Buffer的大小,這個參數(shù)的缺省值為MAX(512KB,128KB*CPU_COUNT)。

雖然LOG_BUFFER中的Redo Entries的大小是以bytes為單位,但是LGWR仍然以block為單位把redo寫入磁盤,Redo Block SizeOracle源代碼中固定的,通常的操作系統(tǒng)都是以512bytes為單位。

可以從v$sysstat中的統(tǒng)計信息中通過計算粗略得到,主要有以下幾個統(tǒng)計信息:

Redo SizeRedo信息的大小;

Redo Wastage:浪費的Redo的大小;

Redo Block WrittenLGWR寫出的Redo Block的數(shù)量;

額外的信息:每個Redo Block Header需要占用16bytes。

SQL> select name,value from v$sysstat

 2 where name in('redo size','redo wastage','redo blocks written');

 

NAME                                                                 VALUE

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

redo size                                                          6298004

redo wastage                                                       1458232

redo blocks written                                                  15641

 

SQL> select ceil(16+(6298004+1458232)/15641) rbsize from dual;

   RBSIZE

----------

      512

 

Linux/UNIX下,Oracle還提供另外一個命令行工具可以用于檢查文件的Block Size大?。?/SPAN>dbfsize

也可以通過轉(zhuǎn)儲日志文件的方式來獲取日志文件塊大小:

SQL> alter session set events 'immediate trace name redohdr level 10';

 

LOG FILE #1:

 (name #3) D:\ORACLE\ORADATA\GVORA\REDO01.LOG

 Thread 1 redo log links: forward: 2 backward: 0

 siz: 0x32000 seq: 0x0000008chws: 0x6bsz: 512nab: 0xb060 flg: 0x0 dup: 1

 Archive links: fwrd: 0 back: 0 Prev scn: 0x0000.0060b530

 Low scn: 0x0000.00620001 05/03/2009 18:41:45

 Next scn: 0x0000.00635173 05/04/2009 08:57:50

 

日志文件的大?。?/SPAN>

當日志文件發(fā)生切換時,會觸發(fā)一個檢查點,那么日志文件的大小就和檢查點的觸發(fā)頻率相關(guān)。頻繁的檢查點操作可以縮短數(shù)據(jù)庫的恢復(fù)時間,但是過于頻繁的檢查點卻會帶來性能負擔。所以如何合理的設(shè)置日志文件的大小也是數(shù)據(jù)庫優(yōu)化的一個重要內(nèi)容。

一般來說,在實際生產(chǎn)環(huán)境中,把log switch的時間控制在半小時左右即可。

 

為什么熱備份期間產(chǎn)生的Redo要比正常的多:

在數(shù)據(jù)庫處于熱備份狀態(tài)時,會產(chǎn)生比平常更多的日志。這是因為在熱備份期間,Oracle為了解決SPLIT Block的問題,需要在日志文件中記錄修改的行所在的數(shù)據(jù)塊前鏡像,而不僅僅是修改信息。

簡單了解一下SPLIT Block的概念:

Oracle的數(shù)據(jù)塊是由多個操作系統(tǒng)塊組成。通常UNIX文件系統(tǒng)使用512bytes的數(shù)據(jù)塊,而Oracle使用8KBdb_block_size。當熱備份數(shù)據(jù)文件時,要使用文件系統(tǒng)的命令工具(cp)拷貝文件,并且使用文件系統(tǒng)的blocksize讀取數(shù)據(jù)文件。

這種情況下,可能出現(xiàn)如下狀況:當拷貝數(shù)據(jù)文件的同時,數(shù)據(jù)庫正好向數(shù)據(jù)文件寫數(shù)據(jù)。這就使得拷貝的文件中包含這樣的database block,它的一部分OS Block來自于數(shù)據(jù)庫向數(shù)據(jù)文件(這個DB Block)寫操作之前,另一部分來自于寫操作之后。對于數(shù)據(jù)庫來說,這樣的Block本身并不一致,而是一個分裂塊(SPLIT Block)。這樣的分裂塊在恢復(fù)時并不可用(會提示Corrupted Block)。

所以在熱備份狀態(tài)下,對于變更的數(shù)據(jù),Oracle需要在日志中記錄整個變化的數(shù)據(jù)塊的前鏡像。這樣如果在恢復(fù)的過程中,數(shù)據(jù)文件中出現(xiàn)分裂塊,Oracle就可以通過日志文件中的數(shù)據(jù)塊的前鏡像覆蓋備份,以完成恢復(fù)。

 

分裂塊產(chǎn)生的根本原因在于備份過程中引入了操作系統(tǒng)工具(如cp工具等),操作系統(tǒng)工具無法保證Oracle數(shù)據(jù)庫的一致性。如果使用RMAN備份,由于RMAN可以通過反復(fù)對區(qū)獲得一致的Block,從而可以避免Split Block的生成,所以不會生成額外的Redo。因此建議在備份時(特別是繁忙的數(shù)據(jù)庫),應(yīng)該盡量采用RMAN備份。

 

能否不生成Redo

NOLOGGING對于數(shù)據(jù)庫的影響

正常的數(shù)據(jù)庫必須生成Redo,這是數(shù)據(jù)庫的機制,否則數(shù)據(jù)庫在遇到故障或Crash時則無法恢復(fù)。但是Oracle為了增強某些特殊操作的性能,對于一些SQL語句,Oracle允許使用NOLOGGING子句,NOLOGGING可以使得日志生成大幅降低,但是必要日志(比如對于字典表的修改)仍然會被記錄。

可以使用NOLOGGING的環(huán)境非常有限,在以下操作中,可以增加NOLOGGING子句:

創(chuàng)建索引或重建索引時;

通過/*+append */提示,使用直接路徑批量INSERT操作或SQL*Loader直接路徑加載數(shù)據(jù);

CTAS方式創(chuàng)建數(shù)據(jù)表時;

大對象(LOB)的操作;

一些Alter table操作,如movesplit等。

  

需要注意的是,由于NOLOGGING操作會導(dǎo)致對于數(shù)據(jù)的操作不記錄日志,如果數(shù)據(jù)庫崩潰,這部分數(shù)據(jù)是無法恢復(fù)的,所以通常的建議是,在進行了NOLOGGING操作之后,需要對數(shù)據(jù)庫進行備份,以避免數(shù)據(jù)因數(shù)據(jù)庫實效而丟失。

 

disable_logging對于數(shù)據(jù)庫的影響

Oracle存在一個內(nèi)部參數(shù),可以使數(shù)據(jù)庫關(guān)閉日志記錄,從而實現(xiàn)某些特殊需要或測試目的,這個參數(shù)是_disable_logging,可以動態(tài)設(shè)置這個參數(shù)。

由于不記錄日志,在進行數(shù)據(jù)庫恢復(fù)時,這些數(shù)據(jù)是無法恢復(fù)的。

如果數(shù)據(jù)庫運行在歸檔模式下,設(shè)置該參數(shù)會導(dǎo)致日志文件損壞。因為在設(shè)置該參數(shù)之后,歸檔進程無法識別該日志文件格式,會將該日志文件標記為損壞。

設(shè)置了_disable_logging參數(shù),可以禁用日志的生成,從而提高某些測試的性能。

 

Force logging(強制日志)模式

當使用Dataguard作為數(shù)據(jù)庫的備份或容災(zāi)高可用性手段時,通常日志就變得不可缺少。在Oracle 9iR2中,可以將數(shù)據(jù)庫置于強制日志模式(Force Logging Mode)。在強制日志模式下,所有操作都將記錄日志。

 

Redo故障的恢復(fù)

丟失非活動日志組的故障恢復(fù):

如果數(shù)據(jù)庫丟失的是非活動(INACTIVE)日志組,由于非活動日志組已經(jīng)完成檢查點,數(shù)據(jù)庫不會發(fā)生數(shù)據(jù)損失,此時只需要通過clear重建該日志組即可。

清除日志組的命令:alter database clear logfile group 2;

如果數(shù)據(jù)庫處于歸檔模式下,并且該日志組未完成歸檔則需要使用如下命令強制清除:

Alter database clear unarchived logfile group 2;

 

丟失活動或當前日志文件的恢復(fù):

在損失當前日志時,數(shù)據(jù)庫是正常關(guān)閉的:

由于關(guān)閉數(shù)據(jù)庫前,Oracle會執(zhí)行全面檢查點,當前日志在實例恢復(fù)中可以不再需要。直接clear即可。

Oracle 9i中,可能無法對當前日志進行clear,需要通過until cancel恢復(fù)后,resetlogs打開。

 

在損失當前日志時,數(shù)據(jù)庫是異常關(guān)閉的:

如果在損失當前日志時,數(shù)據(jù)庫是異常關(guān)閉的,那么Oracle在進行實例恢復(fù)時必須要求當前日志,否則Oracle將無法保證提交成功的數(shù)據(jù)不丟失(也就意味著Oracle會丟失數(shù)據(jù)),在這種情況下,Oracle數(shù)據(jù)庫將無法啟動。

對于這種情況,通常需要從備份中恢復(fù)數(shù)據(jù)文件,通過應(yīng)用歸檔日志文件向前推演,直到最后一個完好的日志文件,然后通過resetlogs啟動數(shù)據(jù)庫完成恢復(fù)。丟失的數(shù)據(jù)就是損壞的日志文件中的數(shù)據(jù)。

可是不幸的是,很多數(shù)據(jù)庫是從來不備份的,那么在面對這種情況時,Oracle提供了一種內(nèi)部手段可以用來強制性數(shù)據(jù)庫打開、忽略一致性等問題。在打開數(shù)據(jù)庫之后,Oracle建議導(dǎo)出數(shù)據(jù),然后重建數(shù)據(jù)庫,再導(dǎo)入數(shù)據(jù),完成災(zāi)難恢復(fù)。

SQL> select ksppinm,ksppdesc from x$ksppi

 2 where ksppinm like '%_resetlogs_%';

 

KSPPINM

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

KSPPDESC

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

_allow_resetlogs_corruption

allow resetlogs even if it will cause corruption

 

該參數(shù)的含義是,允許在破壞一致性的情況下強制重置日志,打開數(shù)據(jù)庫。_allow_resetlogs_corruption將使用所有數(shù)據(jù)文件最舊的SCN打開數(shù)據(jù)庫,所以通常需要保證SYSTEM表空間擁有最舊的SCN

丟失ACTIVE日志和CURRENT日志的情況下,如果沒有備份,只能使用隱含參數(shù)_allow_resetlogs_corruption強制啟動數(shù)據(jù)庫,設(shè)置此參數(shù)后,在數(shù)據(jù)庫open過程中,Oracle會跳過某些一致性檢查,從而使數(shù)據(jù)庫可能跳過不一致狀態(tài),直接打開。

Alter system set “_allow_resetlogs_corruption”=true scope=spfile;

Recover database using backup controlfile until cancel;     ----mount

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多