MySQL

2010年06月01日

MySQL "SHOW ENGINE INNODB STATUS"の読み方 その1

はてなブックマーク -MySQL Check

kouです。


何か困ったときに便利なのが各種統計情報出力コマンド。弊社では堅く作るシステムではMySQLを利用することが多く、ストレージエンジンもInnoDBを利用させていただくことが多いです。

というわけで負荷テスト時や運用時に"SHOW ENGINE INNODB STATUS"コマンドをよく使うのですが、各参考サイトを元に自分のメモ代わりに必要そうな項目をまとめてみました。


以下、各セクション毎にポイントをまとめていこうと思います。間違い等があればご指摘いただけるとうれしいです。


出力サンプルのMySQLのバージョンは5.0系です。

ステータスセクション

1  mysql> SHOW ENGINE INNODB STATUS\G
2  *************************** 1. row ***************************
3  Status:
4  =====================================
5  100530  9:10:18 INNODB MONITOR OUTPUT
6  =====================================
7  Per second averages calculated from the last 26 seconds


7行目のPer second ...は統計のためにデータを取得した時間です。とはいえ、全てのセクションの情報が同時に採取されるわけではないらしいので、この例では以降のセクションのカウンタ値はだいたい26秒間のもの。秒平均値は26秒間の中のどこかの期間内の平均値であることがわかります。


セマフォセクション

 8 ----------
 9 SEMAPHORES
10 ----------
11 OS WAIT ARRAY INFO: reservation count 359260, signal count 356251
12 Mutex spin waits 0, rounds 6471518, OS waits 83492
13 RW-shared spins 438760, OS waits 214212; RW-excl spins 34083, OS waits 15339


リレーショナルデータベースではそのデータの整合性を担保するために様々な処理でアトミック性を保証しなくてはいけません。MySQLで複数スレッドが動いている中で、クリティカルな処理を行う場合には、そのアトミック性を担保するために同時に1つの操作しかしていないことを保証する仕組み(同期機構)が必要です。LinuxのMySQLでは同期機構にセマフォとMutexを利用しています。

このセクションではそのセマフォ、Mutexに関する統計情報が出力されています。

11行目はスレッドがセマフォの配列に入ったOS待ち(OS wait)の回数です。reservation countが配列に入った回数、signal countが配列に入ってOSからシグナルを受け取った回数です。後述しますが、この回数は少ないほど良いです。

12行目はスレッドのMutex(相互排他ロック)による各種待ち回数を示していて、spin waitsはMutexのスピンロック待ちに入った回数、roundsはスピンロック待ちに入ったロックのスピンラウンド総数を示します。OS waitsはスピンロック待ちでもMutexを取得できなかったため、オペレーティングシステム管理下のセマフォに渡されたロック回数です。

InnoDBはスピンロック待ち→OS待ちの順にロック取得を試みます。スピンロック待ちに入ったロックはinnodb_sync_spin_loopsで設定されたスピンラウンド数(取得待ち回数)を超えるとOS待ちに引き渡されます。OS待ちはスピン待ちに比べて処理コストが大きいので一般的にはOS待ち数が小さい方が好ましいです。OS待ちが多く発生している場合はディスクI/OかInnoDB内部でこれらロックに関する競合が発生している可能性が高いです。OS待ちが毎秒10000以上であればOS待ちを減らす方向でチューニングしましょう。MySQLのスレッド数の変更(innodb_thread_concurrency設定値)が効くと思います。

とはいえ、スピン待ちもCPUリソースを消費するため、あまりspin rounds数が大きいようだとスピン待ちとOS待ちのバランスを取るためにチューニングが必要です(前述のinnodb_sync_spin_loops変数で設定できます。まだ試したことないですが、spin roundが毎秒1000以上であればinnodb_sync_spin_loopsを変更すると良いそうです。もしくはinnodb_thread_concurrency設定値を減らす)。

13行目は読み書きに関する共有ロック(RW-shared)、排他ロック(RW-excl)の各待ち種別カウンタを示していて、それぞれスピン待ち(spins)、OS待ち(OS waits)の回数を示しています。

まとめると、データベースへの並列アクセスが多い場合は同期機構に密接に関わるこのセクションの数字が特に重要で、ほとんどの状況ではOS待ちが多く発生してパフォーマンスが劣化していると思います。その場合はディスクI/OやInnoDB内部の競合が発生している可能性が多いので、MySQLのスレッド数を減らす(innodb_thread_concurrency)と症状が改善されることが多いです。パフォーマンスが出ないからとスレッド数をむやみに増やすと逆に競合が発生しやすくなるため逆効果です。


(もちろん、ボトルネックがどこにあるかによって増やした方がいい場合もありますので、innodb_thread_concurrencyを変更しながらベンチマークをとってチューニングすることが一番望ましいです。)


「その2」へ続く。

参考サイト/書籍:
MySQL Performance Blog - SHOW INNODB STATUS walk through
MySQL 5.0 Reference Manual - 13.2.13.2. SHOW ENGINE INNODB STATUS and the InnoDB Monitors
実践ハイパフォーマンスMySQL 第2版

はてなブックマーク -MySQL Check
日時: 2010年06月01日 01:37 | コメント (0) | トラックバック (0)
2010年11月30日

MySQL "SHOW ENGINE INNODB STATUS"の読み方 その2

はてなブックマーク -MySQL Check


kouです。


だいぶ間が空いてしまいましたが、続きを書いてみたいと思います。


トランザクションセクション

14 ------------
15 TRANSACTIONS
16 ------------
17 Trx id counter 0 487637614
18 Purge done for trx's n:o < 0 487637607 undo n:o < 0 0
19 History list length 1
20 Total number of lock structs in row lock hash table 0
21 LIST OF TRANSACTIONS FOR EACH SESSION:
22 ---TRANSACTION 0 0, not started, process no 3424, OS thread id 1169332544
23 MySQL thread id 11166, query id 14476345 localhost root
24 SHOW ENGINE INNODB STATUS
25 ---TRANSACTION 0 487637613, ACTIVE 4799 sec, process no 3424, OS thread id 1089030464 starting index read, thread declared inside InnoDB 239
27 mysql tables in use 2, locked 0
28 MySQL thread id 10794, query id 14474613 172.16.xx.xx batch Sending data
29 SQL文(省略)
30 Trx read view will not see trx with id >= 0 487637614, sees < 0 487637614


このセクションには現在実行中のトランザクションに関する情報が出力されます。

17行目のTrx id counterは現在のトランザクションIDカウンターの値を表します。これはトランザクション毎に発行されインクリメントされていきます。"0"と"487637607"と数値が二つありますが、上位32ビットと下位32ビットで区切られているためです。以下のその他の数値も同様です。


18行目のPurge done for trx's n:0はどこまでロールバックセグメントのパージ処理が終わったかを示しています。ここではトランザクションID "487637607"までのパージが終わっています。InnoDBはマルチバージョニングデータベースであるため古いバージョンのレコード情報を保持しています。レコード削除した場合でもストレージエンジン内ではすぐにレコードは物理削除されず、削除フラグが立った状態です。この削除フラグが立ったレコードは適切なタイミングでパージされます。ここでは"487637607"までパージされたことを示しています。

undo n:oはUNDOログのレコード数を示していて現在は"0"です。


19行目のHistory list lengthはロールバックセグメントでまだパージされていないヒストリ数です。


21行目からは個々のトランザクションの状態が表示されています。
この例ではトランザクションが二つです。22?24行目、25?30行目がそれぞれのトランザクションです。

22?24行目のトランザクションはこのコマンド(SHOW ENGINE INNODB STATUS)を発行している自身のトランザクションです。25?30行目が実際に発行されているSQLのトランザクションになります。


ここでは25?30行目のトランザクションをみていきます。


25行目のTRANSACTION 0 487637613は当トランザクションIDです。ACTIVE 4799 secはこのトランザクションのステータスと生存時間です。"Active"となっていますので、現在処理中です。重たいクエリを発行していますので大変時間がかかっています。


process no 3432はOSのプロセス番号、OS thread id 1089030464 starting index readはOSのスレッドIDでインデックスデータを読み込んでいます。gdbなどでデバッグする際にこれらの情報が役に立ちます。

thread declared inside InnoDB 239はInnoDB内部でのスレッド割当状況です。


27行目のmysql tables in use 2, locked 0はこのトランザクションが利用しているテーブル数("2")と取得しているロックの数("0")を示します。


28行目のMySQL thread id 10794, query id 14474613はこのクエリ("14474613")がどのスレッド("10794")で実行されているかを表示しています。SHOW PROCESSLISTで表示される情報と同様です。


29行目は実際に実行されているSQL文を表示。


30行目のTrx read view will not see trx with id >= 0 487637614はこのトランザクション開始後に開始されたトランザクションIDです。またsees < 0 487637614はこのトランザクション開始前に終了していたトランザクションです。利用しているトランザクション分離レベルと前後のトランザクションの情報からこのトランザクション内でどのようなデータの見え方をしているかが推測できるため、トラブルシュート時に役立つことがあるかもしれません。

「その3」へ続く。

参考サイト/書籍:
MySQL Performance Blog - SHOW INNODB STATUS walk through
MySQL 5.0 Reference Manual - 13.2.13.2. SHOW ENGINE INNODB STATUS and the InnoDB Monitors
実践ハイパフォーマンスMySQL 第2版


はてなブックマーク -MySQL Check
日時: 2010年11月30日 13:47 | コメント (0) | トラックバック (0)
2011年07月25日

完全公開!ソーシャルゲーム設計事例:プロローグ

はてなブックマーク -完全公開!ソーシャルゲーム設計事例:プロローグ Check

はじめに

こんにちは。樽八です。

ちょうど1年ほど前になりますが、弊社にてGREEプラットフォームにおけるソーシャルアプリ携帯ゲーム「偉人伝心」のリリースを致しました。
その時のシステムに対する機能要求および非機能要求に対してできたこと、できなかったことをエンジニア視点で列挙したいと思います。

システムに対する要求と、達成、未達成状況

ほぼ達成された要求項目(4項目)

2000万PV/日のアクセスに耐えるシステムを作ること。

  →負荷試験時において、画像合成、Flash合成ページを含めて、webサーバ10台時の構成において、1400リクエスト/秒(単純計算だと1億2000万PV/日)以上のスループットを達成。
 (※残念なことに、これだけの負荷が実際に掛かることはありませんでした。)

会員数の増減に合わせて速やかにシステム全体の構成を変更出来ること。

  →サーバの追加に応じてシステム全体のスループットを上げることのできる、スケールアウト可能な構成としました。
  →上記負荷試験時の数字もWebサーバの追加によりさらに引き上げることが出来る事を確認しました。

予期される障害発生に関しては、たとえスループットが落ちた状態状態であったとしても通常サービスの継続が可能であること。

  →全てのHW機器を冗長化して構築しました。

特定の機器が障害によって復旧不可能な状態に陥っても、サービス継続に必要なデータが復旧可能であること。

  →上記、HW機器の冗長化に加えて、データの保有に関しても冗長化を行いました。

続きを読む "完全公開!ソーシャルゲーム設計事例:プロローグ" »
はてなブックマーク -完全公開!ソーシャルゲーム設計事例:プロローグ Check
日時: 2011年07月25日 10:44 | コメント (0) | トラックバック (0)
2011年07月26日

完全公開!ソーシャルゲーム設計事例:前編

はてなブックマーク -完全公開!ソーシャルゲーム設計事例:前編 Check

はじめに

こんにちは。樽八です。
この記事は、前記事「完全公開!ソーシャルゲーム設計事例:プロローグ編」の続きになります。

おさらいとして、今回要求されたシステム要件(機能要件および非機能要件)

  • 2000万PV/日のアクセスに耐えるシステムを作ること。
  • 会員数の増減に合わせて速やかにシステム全体の構成を変更出来ること。
  • 予期される障害発生に関しては、たとえスループットが落ちた状態状態であったとしても通常サービスの継続が可能であること。
  • 特定の機器が障害によって復旧不可能な状態に陥っても、サービス継続に必要なデータが復旧可能であること。
  • 負荷のピーク時においても、各ページの応答時間が5秒を超えないこと。
  • サービスを動かしながらの頻繁なアップデートおよびデータ更新が可能であること。
続きを読む "完全公開!ソーシャルゲーム設計事例:前編" »
はてなブックマーク -完全公開!ソーシャルゲーム設計事例:前編 Check
日時: 2011年07月26日 11:00 | コメント (0) | トラックバック (0)
2011年07月27日

完全公開!ソーシャルゲーム設計事例:後編

はてなブックマーク -完全公開!ソーシャルゲーム設計事例:後編 Check

はじめに

こんにちは。樽八です。
この記事は、前記事「完全公開!ソーシャルゲーム設計事例:前編」の続きになります。

まだの方は是非合わせてお読みください。
完全公開!ソーシャルゲーム設計事例:プロローグ編
完全公開!ソーシャルゲーム設計事例:前編

前編では、弊社構築ソーシャルゲームにおける。コンテンツ生成Webサーバの構成とキャッシュまわりについて紹介いたしました。
いよいよ後編では、データベース構成とシステム全体の冗長化に関して記述させていただきます。
本丸であり、少々長くなりますがお付き合い下さい。

続きを読む "完全公開!ソーシャルゲーム設計事例:後編" »
はてなブックマーク -完全公開!ソーシャルゲーム設計事例:後編 Check
日時: 2011年07月27日 11:00 | コメント (3) | トラックバック (0)
ゆめみ深田浩嗣のブログ Mercury mobmail
YUMEMI Labs Sweet