前からまとめようと思っていた SQL Server の仮想ログファイル (VLF : Virtual Log File) について少し書いてみたいと思います。
SQL Server の Books Online の [トランザクション ログの物理アーキテクチャ] には以下の記載があります。
SQL Server データベース エンジンにより、各物理ログ ファイルは内部的に多くの仮想ログ ファイルに分割されています。
仮想ログ ファイルのサイズは固定されておらず、1 つの物理ログ ファイルに対する仮想ログ ファイルの数も決まっていません。
仮想ログ ファイルのサイズは、ログ ファイルの作成時や拡張時にデータベース エンジンにより動的に選択されます。データベース エンジンでは、管理する仮想ファイルの数を少なく保とうとします。
ログ ファイルを拡張した後の仮想ファイルのサイズは、既存のログのサイズと増加した新しいファイルのサイズの合計になります。
管理者が仮想ログ ファイルのサイズや数を構成または設定することはできません。
この内容についてみていきたいと思います。
MCM の Readiness Videos では、[LogFiles] が本内容に該当します。
■仮想ログファイルを確認
実際に仮想ログファイルを確認してみたいと思います。
仮想ログファイルを確認するためには、[DBCC LOGINFO] を実行します。
DBCC LOGINFO のヘルプはこちら。
dbcc LOGINFO [({‘dbname’ | dbid})] |
オプションを指定しなければ現在のデータベースに対して実行がされます。
Denali のデータベース作成時のデフォルトの設定 (データファイル 4MB / ログファイル 1MB) でデータベースを作成すると 4 つの仮想ログファイルが作成されています。
# FileSize は Byte になります。
[Status] については、Get the Fact の振り返りの時に少し書いたのですが、以下の技術情報に記載があります。
SQL Server を実行しているコンピュータでトランザクション ログのサイズが予期せず増大する、または、ログがいっぱいになる
私が知っている範囲では Status の状態は以下の三種類となるようです。
- Active : Status = 2
- RECOVERABLE : Status = 1
- REUSABLE : Status = 0
現在は、[FseqNo] が 32 のものが Status = 2 となっていますので、一つの仮想ログファイルが使われている状態で、残りの 3 つに関してはまだ未使用の状態となっているようですね。
■仮想ログファイルのファイル数
仮想ログファイルですが [2 ~ 16] のファイルで構成がされます。
仮想ログファイルの個数はログファイルの拡張 / 作成時のサイズによって以下のように構成がされます。
サイズ | 個数 |
<64MB | 4 VLF |
≧64MB ~ > 1GB | 8 VLF |
> 1GB | 16 VLF |
このファイルを 64MB に拡張して、仮想ログのファイル数を確認してみます。
1MB → 64MB への変更は 63MB のサイズ拡張となりますので [<64MB] となり、仮想ログファイルは拡張分に対して 4 個で作成されます。
DBCC LOGINFO で取得できる情報には CreateLSN が表示されますので、どのログシーケンス番号でログファイルが拡張されたのかを確認することも可能です。
SHRINK (圧縮) をして、ログファイルを 1MB に縮小し、今度は66 MB に拡張をして再度仮想ログのファイル数を確認してみます。
# ギリギリのところを狙うと微妙に 64 MB 以上の拡張にならないことがあるので 65 ではなく 66 にしています。私が範囲の上限の以上、未満を間違って理解しているようでしたらご指摘いただけると助かります…。
1MB → 66MB では、65MB の拡張となりますので、[≧64MB ~ > 1GB] の範囲となり、仮想ログファイルは拡張分に対して 8 個で作成されます。
以下の拡張も検証をしてみます。
# このサイズが私の環境では 1GB 以上の仮想ログファイルの個数になる分岐点でした。
拡張分の仮想ログのファイル数が 16 個に分割されているのが確認できます。
最小の仮想ログファイルの個数は [2] なのですが、これは拡張をしているだけでは見ることはできません。
# 拡張時には 4 個以上の仮想ログファイルで構成されるため。
■ログファイルの圧縮
現在、トランザクションログのサイズは 1026MB なのですが、これを 100MB に縮小してみます。
USE [TEST] |
[CurrentSize] が [16528] となっています。
これはページ数 (8KB) になりますので
16,528 ページ × 8,192 Byte = 135,397,376 Byte = 132,224 KB = 129MB
となります。
近似値になっていますね。
DBCC LOGINFO の結果は先ほどの結果 (拡張分が 16 個に分割された状態) から継続したものを使用しています。
圧縮をすることで
248KB × 4 + 65,600KB × 2
の仮想ログファイルで構成されていることが確認できます。
# FileSize は Byte になります。最初の仮想ログファイルのブロックは最後のファイルだけサイズが違いますが 248KB と丸めてしまっています。
ログファイルの圧縮ですが、仮想ログファイル単位に実施されます。
圧縮前は
248KB × 4 + 65,600KB × 16
の仮想ログファイルで構成がされていました。
圧縮は未使用の仮想ログを解放する処理になりますので、248KB または、64MB のどちらかの単位で未使用の領域が切り捨てられることになります。
先ほどは 100MB で圧縮をしましたが、次は 50MB に圧縮をしてみたいと思います。
DBCC SHRINKFILE と DBCC LOGINFO を実行した結果がこちらになります。
100MB に近い値は 248KB × 4 +64MB × 2 の仮想ログファイルの構成でしたが、
50MB に近い値は 248KB × 4 + 64MB × 1 の仮想ログファイルの構成となります。
アクティブ (Status = 2) の仮想ログファイルは使用中のため切り捨ては出来ないのですが、ログファイルの圧縮時には、再利用可能 (Status = 0) のログファイルを対象として切り捨てが行われます。
データの更新を行い、仮想ログファイルを以下の状態にしてみました。
いくつか Status = 0 の状態となっている仮想ログファイルが確認できますね。
それでは、以下のクエリを実行して仮想ログを圧縮してみます。
USE [TEST] |
先ほどまで Status = 0 となっていた、18 行目移行が圧縮により解放されていることが確認できますね。
ログを圧縮しても思うようにサイズが小さくならないことがあった場合は、Stauts が 0 になっていない仮想ログファイルが蓄積しているまたは、仮想ログファイルのサイズが大きめになっているため、解放できる領域が予定より確保できないといったことがあるかと思います。
# 補足ですが仮想ログファイルのサイズが大きいことは悪いことではありません。
■ログファイルのバックアップと再利用可能化
Status = 2 (Active) となっている仮想ログですが、これはずっと Active になっているわけではなく、トランザクションログのバックアップをすることで Status = 0 (Reusable) となります。
一度トランザクションログのバックアップを取得してみます。
バックアップが終了したら、仮想ログファイルの状態を確認してみます。
先ほどまで Status = 2 だったものが Status = 1 に変わっていますね。
アクティブだったログがバックアップを取得することで再利用可能になっていることが確認できます。
FSeqNo = 49 の仮想ログファイルに関しては現在アクティブな LSN のログを含んでいるため Status = 2 のままとなっています。
■最小の仮想ログファイルの構成
仮想ログファイルの最小構成数は [2] となっています。
ただし、新規作成や拡張の場合は最小構成数は [4] となります。
仮想ログファイルが 2 個で構成されるのは圧縮をした場合になります。
最初の仮想ログファイルが 1MB × 4 で構成されていると 2 個の状態にするのはちょっと面倒なのですが、
というように 2 個の構成にすることは可能です。
# 2 個にしたからといって何かが起きるわけではないのですが。
SQL Server の仮想ログファイルに関しては [DBCC LOGINFO] を使う事により情報を確認することができました。
仮想ログファイルの数ですが管理オーバーヘッドがあるので数が多いと、ログのバックアップなどの性能に少し影響してきます。
次の投稿では、仮想ログファイルの数による管理オーバーヘッドについて見ていきたいと思います。
SQL Server の仮想ログファイルについて ≪ SE の雑記…
素敵なエントリーの登録ありがとうございます – .NET Clipsからのトラックバック…
.NET Clips
14 1月 11 at 00:41