SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

AlwaysOn Availability Gruops のデータ同期の仕組みを調べてみる その 2

leave a comment

前回の投稿 (AlwaysOn Availability Gruops のデータ同期の仕組みを調べてみる その 1) ではログキャッシュについてまとめてみました。

今回の投稿では [ログプール] についてみていきたいと思います。

■ログプールとは


Denali からパフォーマンスモニタに [SQLServer:Memory ManagerLog Pool Memory (KB)] という項目が追加されています。
image

これがログプールでどの程度メモリを使用しているかを表すカウンターになります。
# 他にもログプールに関するカウンターが追加されています。

ログプールは可用性グループでプライマリの更新をセカンダリに連携する際に使用されています。
SQL Server でデータが更新される場合、以下のような形で変更が連携されていきます。
image

これにセカンダリを追加してみます。
image

プライマリとセカンダリで同様に流れになるかというと実はそうではありません。
上の図は一つ要素が欠けている状態の絵となります。
このかけている要素が [ログプール] になります。

プライマリで変更されたログ (正確にはログブロック) の内容をセカンダリに連携をするのですが、ログキャッシュからフラッシュしたタイミングでそのままログの内容を送るかというとそういう動作はしていません。

ログキャッシュの内容をログプールに格納し、そこからセカンダリに連携をするという流れでデータの同期がおこわなれます。
image

  1. プライマリで行われた変更はログキャッシュにログレコードが生成されます。
  2. チェックポイントやコミットが発生したタイミングでログキャッシュのログレコードがフラッシュされ、ログファイルに書き込まれます。
  3. フラッシュしたタイミングでログプールにもログレコードが書き込まれます。
  4. ログプールの内容がセカンダリに連携され、ログキャッシュに格納されます
  5. ログレコードがログファイル書き込まれます
  6. REDO スレッドによりログレコードの内容がデータファイルに書き込まれます。

このような流れでプライマリとセカンダリの同期が行われるようです。

ログプールに書き込まれた内容がセカンダリに連携されますので、ログフラッシュが行われるまでは、セカンダリにデータの連携は行われないことになります。
そのため、ログフラッシュが行われていない場合、プライマリとセカンダリのログレコードには差が出ます。

プライマリで以下のようなクエリを実行してみます。

BEGIN TRAN
INSERT INTO Table_1(Col2) VALUES(1)
SELECT COUNT(*) FROM fn_dblog(NULL, NULL)

この時のログの件数は以下のようになります。
image

この状態でセカンダリのログの件数を確認してみます。

image

プライマリではまだログがフラッシュされていないため、ログキャッシュにログレコードが格納されていません。
そのため、セカンダリにはログが連携されておらず、プライマリとセカンダリでログレコードの数に差が出ています。
COMMIT TRAN を実行するとログがフラッシュされますので、プライマリとセカンダリでログレコードの数が一致します。
imageimage

 

セカンダリが起動している場合は、逐次ログプールからセカンダリにログブロックが連携されていきます。
セカンダリが停止している場合はどうなるでしょう。

次の投稿ではセカンダリが停止していた場合のログの連携についてみていきたいと思います。

Share

Written by Masayuki.Ozawa

9月 11th, 2011 at 7:08 pm

Posted in SQL Server

Tagged with , ,

Leave a Reply