MySQL Clusterのチェックポイント処理
提供:MySQL Practice Wiki
MySQL Clusterには、クラスタ全体が停止した場合にリカバリを行うためのチェックポイント処理が実装されている。それらを適切に設定するのは、MySQL Clusterのチューニングやサイジングを行う上でとても重要なことである。
LCP
LCP - Locak Check Pointとは、MySQL Clusterが利用するチェックポイント処理の一つである。LCPはDataMemoryの完全なスナップショットであると考えれば良い。TimeBetweenLocakCheckpointsで定められた量の更新があると、LCPが開始される。TimeBetweenLocakCheckpointsは名前とな似て非なるもので、LCPの間隔ではなくデータ容量を指している。しかもデータ容量は単純にバイト数ではなく、2の累乗として表される。しかも単位は4バイトワードである。TimeBetweenLocakCheckpointsのデフォルトは20であるが、この場合は 4 × 220 = 4MB の更新があるとLCPが開始されるという意味である。つまり、全く更新がない場合はLCPは開始されない。TimeBetweenLocakCheckpointsを6以下に設定すると、連続的にLCPが実行されるようになる。
LCPはDataMemoryの完全なスナップショットであり、MySQL Cluster 6.2までは3世代分、6.3以降は2世代分のLCPが保存される。従って、6.2以前のバージョンではDataMemory × 3、6.3以降のバージョンではDataMemory × 2だけの空きディスク容量を確保する必要がある。また、6.3ではCompressedLCPオプションが追加されたので、このオプションを利用すれば必要ディスク容量を減らすことができる。
DataMemoryが大きくなるとLCPは非常に時間が掛かってしまう。この問題を緩和するには、高速なディスクを利用してLCPを速くするしかない。その際、DiskCheckpointSpeedオプションを調整するのを忘れないようにしよう。DiskCheckpointSpeedはLCPの速度を決定するためのオプションである。デフォルトは10MB/sec。
GCP
GCP - Global Checkpointとは、MySQL Clusterで利用されるチェックポイント処理の一つである。GCPは全ての変更履歴を保存する。いわゆるREDOログと同じであると考えれば良い。クラスタ全体がクラッシュした時は、最新のLCPに対してGCPの内容を追加することでリカバリが行われる。LCP+GCP=最新の状態、というわけである。GCPを実行する間隔はTimeBetweenGlobalCheckpointsで調整することができる。デフォルトは2秒である。不幸にもクラスタ全体がクラッシュしてしまった場合には、最大2秒間の更新が失われることになってしまう。
GCPは一番古いLCPが削除されるまで保持される。MySQL Cluster 6.2では3世代分のLCPが保存されるので、それに合わせてGCPの容量を大きくする必要がある。つまり、LCP<--->LCP<--->LCP<--->最新の状態に至るまでの更新をGCP内に保持する必要があるのである。倍のマージンを見込んだ場合、GCPに必要な容量は次の式で算出できる。
LCPに掛かる時間 × 単位時間あたりの更新量 × (version >= 6.3 ? 2 : 3) × 2
GCPのサイズはNoOfFragmentLogFilesとFragmentLogFileSizeで調整することができる。GCPは4つのファイルがセットになって構成される。各ファイルのサイズはFragmentLogFileSizeであり、そのセットがNoOfFragmentLogFiles個作成されるわけである。従って、GCPの合計サイズは次の式で算出される。
FragmentLogFileSize × NoOfFragmentLogFiles × 4
デフォルトはFragmentLogFileSize=16MB、NoOfFragmentLogFiles=16なので1024MB=1GBである。DataMemoryが大きくなるとLCPにも時間がかかるようになるので、GCPも大きくしよう。
MySQL Cluster 6.2で、micro-GCPという機能が追加された。micro-GCPはGCPをより細かく実行する機能であり、MySQL Clusterレプリケーションの性能を向上させるためのものである。GCPとの違いは、ディスクへのフラッシュを行うかどうかであり、micro-GCPではフラッシュは行われない。micro-GCPを実行すると、Epochが生成される。Epochとはトランザクション(更新)の集合である。生成されたEpochには連番がついており、Epochの順番に適用することで更新の整合性が保たれる。micro-GCPの間隔は、TimeBetweenEpochsで調整する。デフォルトは100ミリ秒である。micro-GCPが完了した時点で、全ての更新はスレーブ側へ送信可能な状態となる。micro-GCPが追加される以前は、GCPごとにスレーブへのデータ転送が行われたが、micro-GCPが追加されたことにより、より短い間隔でデータ転送をできるようになった。その結果、スレーブの遅延が軽減されるというわけである。
micro-GCPはTimeBetweenEpochsごとに行われるが、現在実行中のCOMMITが完了するのを待つ。COMMITに時間がかかってしまう場合、例えばディスクテーブルへ大量に更新を行ったりすると、タイムアウトが発生する可能性がある。タイムアウトが発生すると、データノードが自ら停止してしまう。タイムアウトの間隔はTimeBetweenEpochsTimeoutで調整することができるので、ディスクテーブルを利用している場合にはタイムアウト値を延ばしておくといい。デフォルトは4秒、最大32秒である。
ディスクテーブル利用時のチェックポイント
ディスクテーブルを利用している場合、LCPは異なる動きをする。インメモリ型テーブルに対してLCPが実行されているとき、DiskPageCache上にある全てのダーティページをフラッシュするのである。そうすることで、LCPまでに行われた全ての更新がテーブルスペースに含まれることになる。一方で、ディスクテーブル利用時にはUndoログが付随する。最後にLCPを行われてから現在に至るまでの、ディスクテーブルに対する全ての更新が含まれる。そして、その名が示すとおり、クラッシュリカバリ時にはUndoログの内容がテーブルスペースから差し引かれるのである。すると、テーブルスペースの内容は最後にLCPが行われた時の状態に戻る。その状態に戻れば、GCPを適用することが可能なのである。つまり、
テーブルスペース − Undoログ + GCP = 最新の状態
となるわけである。最新の状態は、(テーブルスペース + DiskPageCache)と表現することも可能であるが、クラッシュリカバリ時にはDiskPageCacheの内容は失われているので、上記のようなリカバリの仕組みが必要なのである。ディスクテーブル利用時にも、PKやインデックスがついているカラムはDataMemoryに格納される。従って、システム全体ではリカバリは次のよなイメージで行われる。
(LCP + (テーブルスペース − Undoログ)) + GCP = 最新の状態
MySQL Clusterのディスクテーブルにおける注意点も参照のこと。