2018.08.31
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待機を観察できます。しかし、全体の待機に占める割合は低いことが確認できます。