前回の投稿 (AlwaysOn Availability Gruops のデータ同期の仕組みを調べてみる その 1) ではログキャッシュについてまとめてみました。
今回の投稿では [ログプール] についてみていきたいと思います。
■ログプールとは
Denali からパフォーマンスモニタに [SQLServer:Memory ManagerLog Pool Memory (KB)] という項目が追加されています。
これがログプールでどの程度メモリを使用しているかを表すカウンターになります。
# 他にもログプールに関するカウンターが追加されています。
ログプールは可用性グループでプライマリの更新をセカンダリに連携する際に使用されています。
SQL Server でデータが更新される場合、以下のような形で変更が連携されていきます。
プライマリとセカンダリで同様に流れになるかというと実はそうではありません。
上の図は一つ要素が欠けている状態の絵となります。
このかけている要素が [ログプール] になります。
プライマリで変更されたログ (正確にはログブロック) の内容をセカンダリに連携をするのですが、ログキャッシュからフラッシュしたタイミングでそのままログの内容を送るかというとそういう動作はしていません。
ログキャッシュの内容をログプールに格納し、そこからセカンダリに連携をするという流れでデータの同期がおこわなれます。
- プライマリで行われた変更はログキャッシュにログレコードが生成されます。
- チェックポイントやコミットが発生したタイミングでログキャッシュのログレコードがフラッシュされ、ログファイルに書き込まれます。
- フラッシュしたタイミングでログプールにもログレコードが書き込まれます。
- ログプールの内容がセカンダリに連携され、ログキャッシュに格納されます
- ログレコードがログファイル書き込まれます
- REDO スレッドによりログレコードの内容がデータファイルに書き込まれます。
このような流れでプライマリとセカンダリの同期が行われるようです。
ログプールに書き込まれた内容がセカンダリに連携されますので、ログフラッシュが行われるまでは、セカンダリにデータの連携は行われないことになります。
そのため、ログフラッシュが行われていない場合、プライマリとセカンダリのログレコードには差が出ます。
プライマリで以下のようなクエリを実行してみます。
BEGIN TRAN |
この状態でセカンダリのログの件数を確認してみます。
プライマリではまだログがフラッシュされていないため、ログキャッシュにログレコードが格納されていません。
そのため、セカンダリにはログが連携されておらず、プライマリとセカンダリでログレコードの数に差が出ています。
COMMIT TRAN を実行するとログがフラッシュされますので、プライマリとセカンダリでログレコードの数が一致します。
セカンダリが起動している場合は、逐次ログプールからセカンダリにログブロックが連携されていきます。
セカンダリが停止している場合はどうなるでしょう。
次の投稿ではセカンダリが停止していた場合のログの連携についてみていきたいと思います。