oracle實驗記錄 (oracle 詳細分析redo(1))

fufuh2o發表於2009-10-23

redo詳細分析

執行機制結構:

redo log buffer 迴圈使用在SGA中。存redo entries

change vector用來描述對db 中任何單個block所做的一次改動:存版本號(可以讓block始終能夠體現當前的最新狀態),事務操作程式碼,被改動的資料塊地址等,在建立change vector時oracle會從data block copy其版本號,在recover時 oracle應用change vecotr並將改動應用於相應的block後,被恢復的資料塊版本號加一(臨時段的資料塊不會生成change vector)
多個change vector按順序組合在一起,從而完成一次改動,oracle叫這組改動為redo record(也可以叫 redo entries),redo record用來描述對db的一個原子改動(應用redo record 中 change vector要麼全部成功,要麼全部失敗,不會存在部分成功 部分失敗情況)

 


redo entries內容被oracle process 從PGA copy到SGA REDO LOG BUFFER,redo entries在記憶體中是佔用連續的順序的空間,lgwr不斷將redo log buffer中內容,寫入redo file
由於user process 向redo log buffer寫資料,所以需要latch保護
redo copy latch:寫redo 到redo log buffer
redo allocation latch:控制log buffer分配
使用這2個latch
程式修改資料時產生redo,此時redo存pga中,將PGA中redo copy到 redo log buffer 要redo copy latch,lgwr只有等待程式COPY 完成才能把目標log buffer block寫入disk

NAME                           VALUE                     ISDEFAULT ISMOD
            ISADJ
------------------------------ ------------------------- --------- ----------------
---------------- --------------------------------
KSPPDESC
-----------------------------------------------------------------------------------
-------------------------------------------------
_log_simultaneous_copies       4                         TRUE      FALSE
            FALSE
number of simultaneous copies into redo buffer(# of copy latches)

redo copy latch數量 defalut cpu_count*2

SQL> show parameter cpu

NAME                                 TYPE                             VALUE
------------------------------------ -------------------------------- -------------
-----------------
cpu_count                            integer                          2

SQL> select name,gets,immediate_gets from v$latch_children where name='redo copy';

NAME                                 GETS IMMEDIATE_GETS
------------------------------ ---------- --------------
redo copy                              10              0
redo copy                              10              0
redo copy                              10              0
redo copy                              10            943

SQL> select name,gets,immediate_gets from v$latch where name='redo copy';

NAME                                 GETS IMMEDIATE_GETS
------------------------------ ---------- --------------
redo copy                              40            943

GETS NUMBER    Number of times the latch was requested in willing-to-wait mode
MISSES NUMBER  Number of times the latch was requested in willing-to-wait mode and the requestor had to wait
SLEEPS NUMBER  Number of times a willing-to-wait latch request resulted in a session sleeping while waiting for the latch
IMMEDIATE_GETS NUMBER Number of times a latch was requested in no-wait mode
IMMEDIATE_MISSES NUMBER Number of times a no-wait latch request did not succeed (that is, missed)

redo copy latch 與redo allocation latch 合作
在將PGA中redo copy到 log buffer時,獲取redo copy latch,獲取後接著獲取redo allocation latch 分配redo log buffer空間,分配後釋放redo allocation latch,然後server process 將PGA中redo資訊 COPY 到redo log buffer,OK 後redo copy latch釋放


例 一個UPDATE的過程
1.server process 搜尋buffer cache中是否有update要更新的block(記憶體中叫buffer),沒有從disk讀入buffer cache,用EXCLUSIVE PING住
2.server process 構造一組change vector來記錄對資料塊的改動(此時放PGA中),這組change vector組成 redo record
3.用redo record大SIZE 判斷需要多少redo log buffer空間
4.判斷current scn,將其存到redo record(不同的redo record可能會共享同樣的SCN值)
5.獲得redo copy latch,接著獲得redo allocation latch
6.檢視當前是否有其它process比當前持有的SCN 更高的SCN值,有的話生成一個新SCN,替換第4步中的SCN
7.判斷是否有足夠的redo log buffer空間(邏輯上判斷比較複雜) 具體如下:
如果redo log buffer沒有足夠空間,釋放redo copy latch,redo allocation latch,釋放後如果此時有其它程式或條件出發了lgwr則要等待lgwr完成,如果此時lgwr沒啟動,則觸發lgwr 啟動(需要reodo writing latch,從LOG BUFFER 把redo record寫入current redo log file中時 LGWR程式會一直佔著這個LATCH,防止其他process同時觸發lgwr,其它process要嘗試獲得該latch必須等待,還會獲得redo allocation latch 防止有新的change vector繼續寫入log buffer,造成LGWR無法確定應該寫多少redo),當沒有足夠空間時,釋放完redo copy/allocation latch後,會立刻嘗試獲取redo writing latch 獲取不到 就表明lgwr被其他process啟動了,等待,繼續嘗試,獲取到後會先檢查log buffer是否有空間了(因為前面LGWR 可能釋放了大量redo log buffer空間)此時要是有空間了 釋放redo writing latch,然後獲得redo copy/allocation latch,沒空間的話觸發lgwr,並且釋放redo writing latch(把這個latch給了lgwr).如果沒有空間,且lgwr 將redo log buffer redo record 寫入online current redo logfile時 redo logfile空間不足不夠寫入時,則process會檢查是否有其它process啟動了switch logfile,如果沒有則觸發switch logfile,有其他程式啟動了,則當前程式等待,switch logfile 後,繼續讓lgwr寫入redo log buffer .(注意switch log時候 禁止生成redo)

如果redo log buffer有足夠的空間,則分配空間 釋放redo allocation latch,然後把change vector從PGA COPY  reod log buffer,把redo record 對應在buffer cache中修改的block 掛到ckptq(checkpoint queue)上去(等dbwr寫入)然後釋放redo copy latch.

8.檢查寫完後的redo log buffer ,redo record是否達到threadshold,到了則觸發lgwr
9.**********更新buffer cache 中block********************


具體過程實驗:


SQL> show user
USER 為 "XH"
SQL> create table t1(id int, a char(2000),b char(2000), c char(2000));

表已建立。

SQL> insert into t1 values(1,'a','a','a');

已建立 1 行。

SQL> insert into t1 values(2,'b','b','b');

已建立 1 行。

SQL> commit;

 

SQL> show user;
USER 為 "SYS"
SQL>


SQL> select file#,block# from (select dbms_rowid.rowid_relative_fno(rowid) file#
,dbms_rowid.rowid_block_number(rowid) block# from xh.t1);

     FILE#     BLOCK#
---------- ----------
         4       1326
         4       1327

SQL> select data_object_id ,owner from dba_objects where object_name='T1';

DATA_OBJECT_ID OWNER
-------------- ------------------------------
         54369 XH
SQL> alter system flush buffer_cache;

系統已更改。

SQL> select file#,block#,dirty from v$bh where bjd=54369;

     FILE#     BLOCK# D
---------- ---------- -
         4       1325 N
         4       1328 N
         4       1323 N
         4       1326 N
         4       1321 N
         4       1324 N
         4       1327 N
         4       1322 N

已選擇8行。


SQL> update t1 set a='aa' where id=1;(user xh )

已更新 1 行。


SQL> select file#,block#,dirty from v$bh where bjd=54369;(user sys)

     FILE#     BLOCK# D
---------- ---------- -
         4       1325 N
         4       1328 N
         4       1323 N
         4       1326 N
         4       1326 Y*****************
         4       1324 N
         4       1327 N

已選擇7行。

SQL> select  XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK from v$transaction;(user sys)

    XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK
---------- ---------- ---------- ---------- ----------
         4         20       1130          2         71

oracle 找出id=1的 block file4,block 1326放入buffer_cache ,並且找到一個可用的undo塊,將 舊值放入undo block(71) 產生重做記錄,新值放入新data block(1326)產生重做記錄

 


SQL> update xh.t1 set a='aaa' where id=2;(另一個 sesssion)

已更新 1 行。

SQL> select file#,block#,dirty from v$bh where bjd=54369;

     FILE#     BLOCK# D
---------- ---------- -
         4       1325 N
         4       1328 N
         4       1323 N
         4       1326 N
         4       1326 Y
         4       1326 N
         4       1326 N
         4       1324 N
         4       1327 N
         4       1327 Y~~~~~

已選擇10行。
SQL> select  XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK from v$transaction;

    XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK
---------- ---------- ---------- ---------- ----------
         4         20       1130          2         71~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~叫t1
         2         28       1421          2         28~~~~~~~~~~~新多的update xh.t1這個事務(起名叫t2)
一樣產生redo record
此時事務t1 commit LGWR 會將 事務T2的redo 一起寫入 log file


SQL> select name,usn from v$rollname where usn in (4,2);

NAME                                  USN
------------------------------ ----------
_SYSSMU2$                               2
_SYSSMU4$                               4

 

 

SQL> ALTER SYSTEM DUMP UNDO HEADER '_SYSSMU2$';

系統已更改。

SQL> ALTER SYSTEM DUMP UNDO HEADER '_SYSSMU4$';

系統已更改。

 


檢視trace
'_SYSSMU2$的dump
  TRN TBL::
 
  index  state cflags  wrap#    uel         scn            dba            parent-xid    nub     stmt_num    cmt
  ------------------------------------------------------------------------------------------------
0x1c   10    0x80  0x058d  0x0000  0x0000.004befdc  0x0080001c  0x0000.000.00000000  0x00000001   0x00000000  0
0x1c是slot (28)v$transaction.XIDSLOT ,10 代表活動的

SQL> select to_number('1c','xxxxxx') from dual;

TO_NUMBER('1C','XXXXXX')
------------------------
                      28

 

 

 

'_SYSSMU4$的dump

TRN TBL::
 
  index  state cflags  wrap#    uel         scn            dba            parent-xid    nub     stmt_num    cmt
  ------------------------------------------------------------------------------------------------

   0x14   10    0x80  0x046a  0x0001  0x0000.004beea0  0x00800047  0x0000.000.00000000  0x00000001   0x00000000  0

 

SQL> select to_number('14','xxxxxx') from dual;

TO_NUMBER('14','XXXXXX')
------------------------
                      20

0x1c是slot (20) v$transaction.XIDSLOT ,10 代表活動的


SQL> commit;(USER XH)

提交完成。

SQL> select  XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK from v$transaction;

    XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK
---------- ---------- ---------- ---------- ----------
         2         28       1421          2         28


那麼剛才t1事務結束,並且觸發lgwr,連同T2的redo一起寫入redo log file

 


SQL> ALTER SYSTEM DUMP UNDO HEADER '_SYSSMU4$';

系統已更改。


 TRN TBL::
 
  index  state cflags  wrap#    uel         scn            dba            parent-xid    nub     stmt_num    cmt
  ------------------------------------------------------------------------------------------------

  0x1c    9    0x00  0x046a  0x0007  0x0000.004bec85  0x00800046  0x0000.000.00000000  0x00000001   0x00000000  1256274692

state 9表示已經 提交.

 

 

補充:快速獲取 當前session的 dump trace

SQL> conn xh/a831115
已連線。
SQL>  ALTER SYSTEM DUMP UNDO HEADER '_SYSSMU2$';

系統已更改。

SQL> select c.value || '/' || d.instance_name ||
  2   '_ora_' || a.spid || '.trc' trace
  3   from v$process a, v$session b, v$parameter c, v$instance d
  4   where a.addr = b.paddr
  5   and b.audsid = userenv('sessionid')
  6   and c.name = 'user_dump_dest'
  7  /

TRACE
--------------------------------------------------------------------------------

F:\ORACLE\PRODUCT\10.2.0\ADMIN\XHTEST\UDUMP/xhtest_ora_3920.trc

 

 

LGWR寫時具體過程:
1.先嚐試獲取redo writing latch,確保其他process不會繼續觸發lgwr
2.獲取redo allocation latch(public redo allocation latch),防止有新的change vector繼續寫入log buffer,造成LGWR無法確定應該寫多少redo.
3.LGWR確定寫的範圍(從上次lgwr啟動所寫的最後一個日誌塊到這個時間點時的最後一個被使用的所有寫滿or未寫滿的日誌塊)此時前臺process仍可以向這個範圍內的redo block(buffer)寫內容(從PGA寫)所以lgwr不阻挨其它程式獲得redo copy latch(既不阻止其它程式向log buffer 中可用塊中寫change vector)
4.確定redo block(buffer)後生成新SCN號
5.LGWR釋放redo allocation latch與redo writing latch
6.LGWR需要等待 其它程式對要寫入日誌檔案的block的更新操作完成(pga-log buffer的操作),通過判斷日誌block(buffer)上的redo copy latch是否都釋放.
7.將第4步scn號copy到要寫入logfile的log buffer的塊頭裡,然後觸發物理的寫操作,將這些待寫日誌塊寫入redo file

 

SQL> select total_waits,time_waited,average_wait,time_waited/total_waits as avg fro
m v$system_event where event = 'log file parallel write';

TOTAL_WAITS TIME_WAITED AVERAGE_WAIT        AVG
----------- ----------- ------------ ----------
       1313          54          .04  .04112719

time_waited/total_waits:表示平均lgwr寫入完成時間 若>1表示寫入過慢 主要表現了lgwr的 io效能

 

 

 

關於log buffer 資訊
SQL> col name format a30
SQL> select name,value from v$sysstat where name like '%redo%';

NAME                                VALUE
------------------------------ ----------
redo synch writes                    2481
redo synch time                        15
redo blocks read for recovery          48
redo entries                         6997
redo size                         3392844
redo buffer allocation retries          0
redo wastage                       378756
redo writer latching time               0
redo writes                          1337
redo blocks written                  7609
redo write time                        60

NAME                                VALUE
------------------------------ ----------
redo log space requests                 0
redo log space wait time                0
redo log switch interrupts              0
redo ordering marks                   132
redo subscn max counts                  0

已選擇16行。

以上是log buffer的統計資訊

redo writes表示寫了多少次(1337次),redo blocks written 表示總共寫了多少日誌塊(7609塊),redo write time表示寫入日誌檔案用了多少時間(10毫秒),這3個是在lgwr寫完redo record到logfile 後更新.
redo size表示產生了多少重做記錄(位元組),redo entries也表示產生多少重做記錄(個數為單位),從PGA COPY到SGA LOG BUFFER前更新

redo wastage:表示log buffer中日誌塊寫入redo log file時,沒有被利用的空間數量(位元組單位)

 


redo log space wait time表示對online redo log file 發出請求空間後等待時間,redo log space requests 表示對online redo logfile 發出請求空間的次數. 它們的值只在程式在發出請求logfile space沒有請求到空間的時候才增加,然後請求的程式等待switch logfile,如果沒有手動alter system switch logfile,redo log space requests 可以代表switch logfile次數


redo buffer allocation retries :表示再次嘗試從log buffer中分空間的次數(最好為0),process第一次沒請求成功 會觸發LGWR 然後等待完成或其它PROCESS 已經觸發而 這個程式等待lgwr完成,完成後再次嘗試從log buffer中分配空間
用 redo buffer allocation retries和redo entries可以計算出從PGA copy change vector到SGA LOG BUFFER 時必須等待的重做記錄的數量所佔的比例
最好為0 或<1%如果>1%且不斷邊大 說明從PGA copy change vector到SGA LOG BUFFER時必須等待log buffer空的日誌塊,可以考慮加大log buffer or  提高lgwr寫效率


SQL> select a.value/b.value from v$sysstat a , v$sysstat b where a.name='redo buffe
r allocation retries' and b.name='redo entries';

A.VALUE/B.VALUE
---------------
              0

 

redo synch writes:提交重新整理log buffer的次數   redo synch time:COMMIT 書信log buffer花費的時間(10毫秒),使用者commit時增加.

 

redo copy latch:將PGA中change vector寫入SGA LOG BUFFER中需要
redo allocation latch:在log buffer中分配空間時需要
redo writing latch:當使用者COMMITor系統觸發LGWR 寫REDO FILE時 都會獲得該latch,如果redo wrting latch 競爭太多,可能代表使用者過多commit

 


關於redo wastage:
LGWR commonly writes up to and including the current log buffer block, which is normally only partially full. The SGA variable containing the index into the log buffer for redo generation is then advanced to the beginning of the next log buffer block before LGWR releases the redo allocation latch prior to writing. In this way, some space is left unused in the last log block of most redo writes. The number of bytes skipped is accumulated in the redo wastage statistic. The following diagram illustrates redo wastage within the first few blocks of a sample Oracle redo log file.

Redo wastage is not a problem. Indeed, it benefits performance by preserving LGWR's sequential I/O pattern. However, high redo wastage is a symptom of a very active LGWR, and that might be a problem. LGWR is expected to be highly active in many instances, but it can be overactive if the log buffer (more correctly, the _log_io_size) is too small, or if the commit rate is too high. If LGWR is overactive, it will place unnecessary load on the redo latches, and on the I/O subsystem. The operating system may also degrade LGWR's execution priority.

 

產生的 redo先從PGA寫入 redo buffer中 ,然後 由lgwr寫入redo logfile,redo block一般是 512位元組(不同的OS不一樣),redo block header是 16位元組 ,那麼oracle中redo block可使用的空間是 512-16位元組,邏輯上 redo file 由redo record組成(由change vector組成)lgwr程式 從 log buffer將redo寫入logfile時將產生一些未使用的 空間,主要 因為lgwr寫時要釋放redo allocation latch,但事務是不停止的,不斷產生新的redo,這些redo要不停的寫入log buffer,所以oracle在 釋放 redo allocation latch之前必須給隨後的redo寫 一個 新的buffer的 起始地址,存在sga fixed area,中的 一個INDEX中 ,這個 INDEX 告訴oracle redo buffer寫的 起始位置,當分配這個INDEX時,oracle SKIPPED 當前已使用的 塊,在下一個沒有使用的 塊上分配,這部分跳過的size叫redo wastage,這種方法模式會讓大部分寫redo到 logfile 時最後一個redo block中一部分空間還未使用

LGWR是正塊的寫一個塊是 512-16位元組,假如用了 100K 就寫入redofile了 ,這樣512-16-100 就 等於未使用但也 寫入redofile了,就是浪費的空間

Redo wastage並不是大問題,如果過多表示lgwr啟動過多造成需要多的latch,也有可能是commit過於頻繁

SQL> select * from v$sga;

NAME                      VALUE
-------------------- ----------
Fixed Size              1248576~~~~~~~~~~~INDEX存這裡
Variable Size         113246912
Database Buffers      167772160
Redo Buffers            7139328

SQL> select max(lebsz) from x$kccle;

MAX(LEBSZ)
----------
       512~~~~~~~~~~~~redo block大小


  1* select round((a.redosize+b.redowast)/c.redoblks) + 16 as redo_block_size fr
om (select value redosize from v$sysstat where name='redo size') a,(select value
 redowast from v$sysstat where name='redo wastage') b,(select value redoblks fro
m v$sysstat where name='redo blocks written') c
SQL> /

REDO_BLOCK_SIZE
---------------
            512
計算redo block size公式:16+(redosize+redowast)/redoblks=16+(產生多少位元組+浪費多少位元組)/寫了多少日誌塊

 


oracle10G R2 預設提供了 20 redo allocation latch

SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE    10.2.0.1.0      Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
SQL> col name format a20
SQL> select name,gets,misses,misses/gets from v$latch where name='redo allocation';


NAME                       GETS     MISSES MISSES/GETS
-------------------- ---------- ---------- -----------
redo allocation             321          0           0
SQL> select name,gets,misses,misses/gets from v$latch_children where name='redo all
ocation';

NAME                       GETS     MISSES MISSES/GETS
-------------------- ---------- ---------- -----------
redo allocation               5          0           0
redo allocation               5          0           0
redo allocation               5          0           0
redo allocation               5          0           0
redo allocation               5          0           0
redo allocation               5          0           0
redo allocation               5          0           0
redo allocation               5          0           0
redo allocation               5          0           0
redo allocation               5          0           0
redo allocation               5          0           0

NAME                       GETS     MISSES MISSES/GETS
-------------------- ---------- ---------- -----------
redo allocation               5          0           0
redo allocation               5          0           0
redo allocation               5          0           0
redo allocation               5          0           0
redo allocation               5          0           0
redo allocation              19          0           0
redo allocation              45          0           0
redo allocation              62          0           0
redo allocation             116          0           0

已選擇20行。


SQL> select name,gets,misses,misses/gets from v$latch where name='redo writing';

NAME             GETS     MISSES MISSES/GETS
---------- ---------- ---------- -----------
redo writi      11396          3   .00026325

 

可以看到redo writing latch都是願意等待模式,如果MISSES/GETS >1%(0.01)那麼可以認為存在latch 競爭

SQL> select name,gets,immediate_gets from v$latch_children where name='redo writing
';

未選定行
沒有子 latch

 

關於redo中子池,與shared pool類似
每個子redo buffer 都對應一個redo allocation latch(shared pool每個SUB POOL 對應一個shared pool latch)


NAME                           VALUE                     ISDEFAULT ISMOD
            ISADJ
------------------------------ ------------------------- --------- ---------------
---------------- --------------------------------
KSPPDESC
----------------------------------------------------------------------------------
-------------------------------------------------
_log_parallelism               1                         TRUE      FALSE
            FALSE
Number of log buffer strands

_log_parallelism  控制是否有多個redo log buffer,且每個對應獨立的redo allocation latch,提高併發性,多個redo log buffer叫做public redo log strands(9i)

(9I中不是隱藏引數,10G中成為隱藏引數了) ,下面兩個引數允許動態調整,_log_parallelism_max 比_log_parallelism  大時,oracle會自動選擇並行度(public redo log strands)

 

_log_parallelism_dynamic       TRUE                      TRUE      FALSE
            FALSE
Enable dynamic strands

_log_parallelism_max           2                         TRUE      FALSE
            FALSE

 

注意當 _log_parallelism>1那麼logmnr將無法使用 ora-01374

10GR2 orcle引入private redolog strands ,會從shared pool分配大量小記憶體(64-128KB),有地理的 redo allocation latch保護,一些特定小事務會在開始時繫結在獨立且空閒的private redo log strands中,change vector生成後 不在存pga而是存private redolog strands,這樣不從PGA COPY 到 SGA LOG BUFFER 就不需要redo copy latch,所以private redo log strands也叫zero-copy redo
寫入redo log file時候 oracle lGWR後臺程式 將private redolog strands&public redo log strands都寫入redo log file,
lgwr  redo flush時,所有public redo allocation latch 都會被獲取(避免在分配redo buffer空間 造成 lgwr不能確定寫的 範圍)所有public strands 的 redo copy latch需要檢查,包含活動事務的private strands要被持有(oracle仍允許pga向 log buffer 中 可用空間 copy  change vector)
SQL> select * from v$sgastat where name='private strands';

POOL         NAME                            BYTES
------------ -------------------------- ----------
shared pool  private strands               1198080


相關引數:
log_private_mul               5                         TRUE      FALSE      FA
SE
rivate strand multiplier for log space preallocation

log_private_parallelism       FALSE                     TRUE      FALSE      FA
SE
umber of private log buffer strands for zero-copy redo

log_private_parallelism_mul   10                        TRUE      FALSE      FA
SE
ctive sessions multiplier to deduce number of private strands

 


alert.log中
Private strand flush not complete
  Current log# 1 seq# 44 mem# 0: D:\ORACLE\PRODUCT\10.2.0\ORADATA\XH\REDO01.LOG
Thread 1 advanced to log sequence 45
表示log buffer到redo log file還沒有完成(LGWR 寫如redo log file)


SQL> select name from v$event_name where name like 'log%';

NAME
----------------------------------------------------------------
log file sequential read
log file single write
log file parallel write
log buffer space
log file switch (checkpoint incomplete)
log file switch (private strand flush incomplete)
log file switch (archiving needed)
log file switch completion
log file sync
log switch/archive
log file switch (clearing log file)

NAME
----------------------------------------------------------------
log write(odd)
log write(even)

已選擇13行。

log file switch (private strand flush incomplete)  反映在 evnet 裡 就是這個事件


redo file切換(SWITCH LOG FILE)
一個online redo log file寫完後,要轉換到另外一個redo file
基本過程:
1.從controlfile中取得下一個可用online redo file
2.記錄寫入current online redo log file的最後一個redo block的SCN (HIGHT SCN),關閉current online
redo log file
3.增加SCN,再次操作CONTROLFILE,將下一個online redo log file,標記為current,還需要判斷前一個current
redo file中是否有未寫入disk的dirty buffer,如果有的話標記為active(雖然已經switch logfile了,但是是一個
這種檢查點級別低,且還沒到INCREMANETAL CHECKPOINT的條件比如dirty buffer少,所以swtich logfile後,仍然有沒有
寫入disk 的dirty buffer ,此時對應的redo filE 狀態為active表示活動的),如果都寫入disk了,標記為in
active,另外如果是archive log mode那麼lgWR將前一個online redofile 加入archive log列表,等待歸檔
4.開啟redo logfile group中的所有member,記錄當前日誌sequence#和第一個redo block 的SCN(LOW SCN)

 

 

 

archived log:
1.archivelog mode lgwr觸發arch
2.如果arch background process 5分鐘後還未接到lgwr通知則發生超時,arch被喚醒檢查時候存在要歸檔的
redo file(通過讀取contorlfile來判斷應該歸檔哪寫redo),instance recovery & media recovery時 arch
processes不會啟動


arch process 過程:
1.從controlfile中讀取未archivelog的redofile
2.在記憶體中分配歸檔redo block,個數由(_log_archive_buffer確定),大小由(_log_archive_buffer_size確定)
3.開啟online redofile group中所有日誌檔案,check file header
4.搜尋可用archivelog dest
5.在可用archive log dest建立並開啟歸檔日誌檔案
6.在redofile 取出每個redo block ,放入記憶體中archived log block,按SCN 順序放入archived lof file
7.關閉所有開啟的檔案(online redofile & archivelog file)

 

arch process 將online redo file裡的redo block讀到archived log block時,如果發現所讀取redo block發生損壞
則會轉到相同的redo group中,另外一個日誌檔案(member)讀取相同的redo block,整個group中所有member
這個redo block都壞了,那麼arch error

arch process 在redo group中 進行迴圈讀取(迴圈讀取member)為了物理I/O平衡,比如讀取一個redo block從
member 1 後,arch會到相同group中 讀取另一個 比如member 2 讀取下一個redo block


 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12020513/viewspace-617285/,如需轉載,請註明出處,否則將追究法律責任。

相關文章