SE の雑記

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

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

one comment

数回に分けてAlwaysOn Availability Groups (可用性グループ) のデータ同期の仕組みについて調べてみたいと思います。

まずは、データ同期を考えるうえで重要になってくる [ログキャッシュ] についてまとめていきたいと思います。

■ログキャッシュについて


可用性グループだけにかかわらず、データベースミラーリングも該当するのですが、これらの可用性の構成をとった場合、デー更新の流れを考えるときにはログキャッシュの存在を意識することが重要となってきます。
# 通常の更新処理でもログキャッシュは使われているのですが、あまり意識していないかと思います。(私だけかもしれませんが)

テーブルの更新をするときの流れを考えた際に、以下のような図がよくあるかと思います。
image

それでは、以下のクエリを実行してテーブルにデータを挿入してみます。

BEGIN TRAN
INSERT INTO Table_1(Col2) VaLUES (1)

COMMIT TRAN を実行していないのでトランザクションは完了していないですが、1 件データを挿入しています。
この状態でログの内容を確認してみます。
image

BEGIN TRAN のログレコード (LOP_BEGIN_XACT) と INSERT INTO のログレコード (LOP_INSERT_ROWS) がログに記録されていることが確認できますね。

ここで、SQL Server を強制終了したいと思います。
今回は問答無用で SQL Server のプロセスを終了させています。
image

SQL Server のサービスを起動させてからログの内容を確認してみます。
image

先ほどのログは [00000073:0000bb09:0002] [00000073:0000bb09:0003] という LSN を持っていたのですが、レコードが見当たらないですね。
このレコードですがログキャッシュと呼ばれるメモリ上に格納されていたレコードになるため、メモリ内ののログレコードがディスク上書き込まれる前に SQL Server を強制終了させたため、レコードが存在していないことになります。
# このレコードがディスクに記録されていないと問題になるかというと、コミット前のログレコードがなくなった (更新を確定する前の操作記録) 状態ですので、実際の運用で問題になることはないはずです

それでは、以下のようにクエリを変更して実行してみます。

BEGIN TRAN
INSERT INTO Table_1(Col2) VaLUES (1)
COMMIT TRAN

今回はトランザクションを最後まで終了させています。
image

[00000073:0000bb11:0002] ~ [00000073:0000bb11:0004] までが一連のトランザクションのログレコードになります。
BEGIN TRAN ~ COMMIT TRAN まで一連の操作が記録されていますね。

それではこの状態で SQL Server を強制終了し、再度起動してからログレコードを確認してみます。
image

コミットした場合は、ログファイルにログレコードが書き込まれた状態になりますので、強制終了しても確定した更新はロールフォワードができるようになります。

データへの更新だけでなく、ログの更新にも実はメモリが使われていて、メモリ上のログレコードでディスクにアクセスを発生させずにロールバックが可能な仕組みとなっています。

それではこの時の流れを見ていきます。
image

データの更新が発生した場合、最初にログファイルに書くのではなく、ログキャッシュというメモリ上の領域がワンクッション入っています。
コミットやチェックポイントといった要求 (ログキャッシュのサイズが圧迫してきた場合も) が発生すると、ログファイルにログレコードが書き込まれる形になります。

COMMIT TRAN を実行しなかった時には、チェックポイントやコミットが発生しておらず、ログキャッシュも圧迫していなかったため、ディスク上の永続データであるログファイルには書き込が発生せず、ログキャッシュまでしか書き込みが行われていないためプロセスを強制終了させたタイミングでメモリがクリアされ、ログキャッシュ上にのみ存在していたログレコードがなくなった形になります。

ログキャッシュの状態ですが、パフォーマンスモニタで [SQL Server:Databases] の [Log Bytes Flushe xxx] 系のカウンタを見ると動いているのがわかってくると思います。
# 1 件の更新をしたとき、コミットしたタイミングでカウンターが触れているのが確認できると思います。
image

データの更新を行う場合、ログレコードの書き込み時にもメモリが使われているということが少し見えてくるのかなと。

可用性グループでデータを同期する場合、このログキャッシュのほかに、もう一つ [ログプール] というメモリ上の領域が使われることになります。

次の投稿ではこのログプールについて少し見ていきたいと思います。

Share

Written by Masayuki.Ozawa

9月 9th, 2011 at 8:29 am

Posted in SQL Server

Tagged with , ,

One Response to 'AlwaysOn Availability Gruops のデータ同期の仕組みを調べてみる その 1'

Subscribe to comments with RSS or TrackBack to 'AlwaysOn Availability Gruops のデータ同期の仕組みを調べてみる その 1'.

  1. […] (AlwaysOn Availability Gruops のデータ同期の仕組みを調べてみる その 1) […]

Leave a Reply