Latch: redo writing

目次

基本情報

 

REDOバッファ内の空間を確保するためにLGWRに書き込み要求をしようとするプロセスは、redo writingラッチを獲得しなければなりません。LGWRによる書き込みは同時に実行されることがないので、自然にこのラッチは、インスタンス全体に一つだけ存在することになります。redo writingラッチは独立ラッチ(solitary latch)であるため、V$ LATCH_PARENTビューにより観察できます。

SQL> select name, gets, misses, immediate_gets, immediate_misses,
   wait_time
from v$latch_parent
where name = 'redo writing';

NAME             GETS     MISSES IMMEDIATE_GETS IMMEDIATE_MISSES  WAIT_TIME
---------- ---------- ---------- -------------- ---------------- --------
redo writing    829715         20              0                0          0

 

redo writingラッチはWilling-to-waitモードで獲得されます。redo writingラッチを獲得する過程で競合が発生した場合latch:redo writingイベントを待機することになります。

パラメータと待機時間

 

待機パラメータ

 

latch freeイベントと同じです。

 

待機時間

 

latch freeイベントと同じです。

 

チェックポイントと解決策

 

Redo関連の競合

 

一般的な環境では、REDO関連ラッチの競合はあまり発生しません。もし、システム全体の待機イベントリスト中のREDOラッチ関連の待機が上位を占めている場合、これのREDOと関連し激しい競合が発生するものと解釈することができます。メタリンクの文書番号14747.1によると、misses/getsが1%以上であるか、immediate_misses/(immediate_gets + immediate_misses)が1%以上であれば、REDOラッチを獲得する過程で競合が発生したものとみなされます。しかし、回収よりラッチの競合による待機時間を競合の発生の証拠として活用することが望ましいと考えられます。

REDOバッファのサイズが、REDOラッチの競合を引き起こす要因になることがあります。 REDOバッファのサイズが小さすぎる場合、LGWRのバックグラウンド記録(Background write)作業が頻繁に発生するようになります。特に長い間、多くのREDOデータを生成するトランザクションが多い場合には、LGWRが非常に頻繁にバックグラウンドの記録を行う必要があります。LGWRは記録処理を実行するために、REDO関連ラッチを獲得しなければならため、これにより、ラッチの競合が増加することになります。したがって、REDOラッチの競合が頻繁に発生する場合、REDOバッファサイズが小さすぎないか検証する必要があります。

システム全体で不必要に多くのREDOデータが生成される場合には、Nologging機能を活用することにより、REDOデータを減らすこともラッチの競合を減らす方法になることがあります。しかし、Nologging作業は、基本的に回復がされていないことに注意しなければなりません。

幸いなことに、REDOに関連するほとんどのパフォーマンスの問題がラッチ競合ではなく、アプリケーションの動作や、I/Oパフォーマンスと関連があります。 「幸いなことに」という表現を使った理由は、REDOラッチで発生する競合については、明確な解決策がない場合が多いからである。 Oracle 9iから10gへのアップデートで、REDOバッファに関連するOracleの内部アルゴリズムが大幅に改善されたため、ほとんどの場合、ラッチの競合はもはや問題ではないと思われます。

実際には、多くの、REDOデータが生成されるときに、REDOラッチでの競合がどのように発生するかをシミュレートしてみましょう。テストシナリオは次のとおりです。

同時に30個のセッションでDMLを実行しながら、多くの、REDOデータを生成します。

この過程で、REDOラッチでの競合が発生していることを確認します。

 

SQL> ed redo_test.sql
- 以下のように数百回のupdateとcommitを実行しながら、REDO領域の負荷を増加させるSQL文を作成します。
update redo_test set id= id、name= name where id=&1;
commit;
update redo_test set id= id、name= name where id=&1;
commit;
update redo_test set id= id、name= name where id=&1;
....

SQL> ed redo_test.bat
- 以下のように同時に30個のセッションでredo_test.sqlを実行します。
start sqlplus maxgauge/ maxgauge@ ora10gr2@redo_test1
start sqlplus maxgauge/ maxgauge@ ora10gr2@redo_test2
...
start sqlplus maxgauge/ maxgauge@ ora10gr2@redo_test30

cmd> redo_test.bat

 

上記のスクリプトを実行させた後、セッションの待機状況をキャプチャしてみると次のような結果を得ることができます。

 

SQL> select event, total_waits, time_waited
from v$session_event
where sid = (select sid from v$mystat where rownum = 1)
order by 3 desc;

EVENT                          TOTAL_WAITS TIME_WAITED
------------------------------ ----------- -----------
SQL*Net message from client            515        5458
buffer busy waits                              106         503
log file sync                                     129         231
latch: cache buffers chains                  86          84
latch: In memory undo latch               27          17
events in waitclass Other                    18          15
latch: library cache                            22          14
SQL*Net message to client                516           3
latch: redo copy                                             2               3
latch: library cache pin                         4           1
SQL*Net break/reset to client               2           0
cursor: mutex S                               193           0

 

log file sync待機とlatch:redo copy待機を観察できます。しかし、全体の待機に占める割合は低いことが確認できます。