レプリケーション遅延とその調査方法
以下の本に、レプリケーション遅延についての調査について書いてあったので、メモっときます。
Mobageを支える技術 ~ソーシャルゲームの舞台裏~ (WEB+DB PRESS plus)
- 作者: DeNA
- 出版社/メーカー: 技術評論社
- 発売日: 2012/06/13
- メディア: 単行本(ソフトカバー)
- 購入: 31人 クリック: 737回
- この商品を含むブログを見る
レプリケーション遅延とは?
一般的に、データベースはその可用性の確保のため、レプリケーションを行います。それにより「マスター」と「スレーブ」が存在することになります。その状態で、アプリケーションにて「マスター」にデータを書き込む(または更新)と、その変更は「スレーブ」への非同期で通知され「スレーブ」でもその変更が取り込まれます。
以下、抜粋
レプリケーション遅延の原因は?
そのレプリケーション(データ同期)が、ある原因により遅延が発生し、データの不整合が発生する場合があります。その原因はほとんど以下のいずれかです。- IOスレッドまたはSQLスレッドが(実は)止まっている
- 重い更新(LOAD DATA、ALTER TABLE、WHERE句の無いUPDATEなど)
- 高頻度の更新(秒間10,000回以上のUPDATEなど)
- 過負荷の参照(SELECT)による、他更新処理の遅延
- ストール
調査方法
IOスレッドまたはSQLスレッドが(実は)止まっている
スレーブのステータスを調べることでわかります。以下のコマンドを実施して、その状態を調査します。特にIOスレッドやSQLスレッドが止まっていないかどうかを確認します。SHOW SLAVE STATUS
重い更新(LOAD DATA、ALTER TABLE、WHERE句の無いUPDATEなど)
スロークエリログを見ることでわかります。マスターでクエリの実行が遅ければ、スレーブでもその実行は遅くなります。なので、スロークエリの時間はそのままレプリケーション時間となります。調査で見つかったスロークエリは改善する必要があります。※注意点として、スロークエリログは、完了したクエリのログのみが表示されることです。ログを見ているときにまだ実行している重いクエリが処理中であった場合、そのログは表示されません。「SHOW (FULL) PROCESSLIST」コマンドで、今実行されているクエリを確認する必要があります。
高頻度の更新(秒間10,000回以上のUPDATEなど)
スロークエリログや「SHOW (FULL) PROCESSLIST」の結果でも、問題になりそうな原因が見つけられない場合があります。それは、処理自体は軽量だが高頻度で実行されている場合です。まずは、秒間当たりのクエリ実行数を見るのがよいでしょう。下記のコマンドで、「秒間当たりのクエリ実行数が見れます。」
>mysqladmin extended-status -i l -r -hslavel | grep -e "Com_insert" -e "Com_update" -e "Com_delete" -e "Com_select"
関係するレコード数を調べるときは以下のコマンドです。
>mysqladmin extended-status -i l -r -hslavel | grep -e "Innodb_rows_read" -e "Innodb_rows_inserted" -e "Innodb_rows_updated" -e "Innodb_rows_updated"
過負荷の参照(SELECT)による、他更新処理の遅延
重い更新だけでなく、重い参照でもレプリケーション遅延は発生します。なぜならば、スレーブへの高負荷の参照によりCPU、ディスク処理能力が食いつぶされ、後ろで実行される更新処理が進みにくくなるためです。この場合も、スレーブ(SELECTをスレーブに対して行っている場合)のスロークエリログを確認することで、事象が確認できます。ストール
上記の情報を参照しても原因が分からない場合、ストール(瞬間的に処理が止まってしまう情報)が起きている可能性があります。例えば1秒しか止まっていない場合でも、1秒に100処理を行う場合、1秒で100処理が停滞、10秒なら1000処理が停滞し、接続数の上限に到達してしまいます。この場合、Webアプリ側でもコネクションが作成できず、詰まってしまいます。このような状態は、OS側の統計情報を確認することでわかります。特にディスクI/Oを気にする必要があります(vmstatのbi、bo)。レプリケーション遅延が発生した場合に、これらの値がゼロの場合、ディスク周りで何からの問題が起きている可能性があります。新規のディスクと交換する必要があるかもしれません。