web-dev-qa-db-ja.com

いくつのVLFが不良になる可能性があります

サイズ840 GBのデータベースに948のVLFがあります。一方、サイズが1.6のデータベースがありますTB 320個のVLFがあります。これは、VLFの数が多い小さなデータベースが実際に問題であることを示していますか?また、その数をどのように決定することができますか?大きすぎるか、OKの範囲内です。

提案してください

6
BeginnerDBA

VLFcountが問題となるのは、VLFの数とそのサイズの組み合わせが回復プロセスに必要な時間よりも長い時間が必要な場合のみです目標復旧時間。

良いか悪いかという単一のVLFはありません。非常に一般的に、各VLFを512MB未満に保ち、VLFの数を1,000未満に抑えています。

特定のログファイルの実際のリカバリ時間を知るためには、テスト環境で同じハードウェアセットアップを行い、リカバリをテストする必要があります。アクティブなトランザクションの実行中にデータベースがシャットダウンされた完全なログ。数十万のVLFを含むデータベースがある場合、リカバリ時間に非常に恐れます。どうやって知っているか聞いてください。

目的のデータベースのコンテキストでDBCC LOGINFOを確認すると、VLFに関する現在の情報を表示できます。このコマンドの出力は次のようになります。

╔════════════════╦════════╦═══════════╦═══════════ ══╦════════╦════════╦════════╦═══════════╗
║RecoveryUnitId║ FileId║FileSize║StartOffset║FSeqNo║ステータス║パリティ║CreateLSN║
╠════════════════╬════════╬════ ═══════╬═════════════╬════════╬════════╬════════╬═ ══════════╣
║0║2║268369920║8192║34║2║64║0║
║0║2║268369920║268378112║0║0 ║0║0║
║0║2║268369920║536748032║0║0║0║0║
║0║2║268369920║805117952║0║0║0║0║
╚════════════════╩════════╩═══════════╩═══════ ══════╩════════╩════════╩════════╩═══════════╝

Status列は、特定のVLFのステータスを示します。ここで、2は、VLFにアクティブなログレコードがあり、それらのレコードがバックアップまたは切り捨てられるまで再利用できません。 (またはミラーリングの場合は、ミラーのログファイルに書き込まれます)。ログファイルを縮小しても(問題がなければ通常はお勧めできません)、ファイルのサイズを、ステータスが2の最後のVLFが占めるポイントより小さくすることはできません。上記の例では、ログファイルを圧縮すると、最後の3つのVLFを削除できますが、最初のVLFはステータス2であるため、圧縮できません。 4番目のVLFのステータスが2の場合、ログがバックアップ(完全復旧)または切り捨て(単純復旧)されるまで、ログファイルをまったく圧縮できません。 )。

次のクエリを使用して、ファイルサイズと拡張設定を確認できます。

SELECT [DB Name] = d.name
    , [File Name] = mf.name
    , mf.physical_name
    , Size = mf.size * 8192E0 / 1048576
    , MaxSize = mf.max_size * 8192E0 / 1048576
    , Growth = mf.growth * 8192E0 / 1048576
    , [Recovery Model] = CASE WHEN mf.type = 1 THEN d.recovery_model_desc ELSE '' END
    , [Log Reuse Wait Reason] = CASE WHEN mf.type = 1 THEN d.log_reuse_wait_desc ELSE '' END
FROM master.sys.databases d
    INNER JOIN master.sys.master_files mf ON d.database_id = mf.database_id
WHERE d.name = DB_NAME()
ORDER BY d.name
    , mf.type
    , mf.name;

上記のクエリの出力例は次のようになります。

╔══════╦══════════╦═════════════════════════╦═════ ═╦═════════╦════════╦══════════╦═════════════╗
║DB║ファイル║physical_name║サイズ║MaxSize║増加║リカバリ║ログの再利用║
║名前║名前║║║║║モデル║待機理由║
╠══════ ╬══════════╬═════════════════════════╬══════╬═════ ════╬════════╬══════════╬═════════════╣
║テスト║MyFile║D :\ Data\Test_MyFile.bak║125║1000║100║║║
║テスト║Test_DB║D:\ Data\Test_DB.mdf║384║2048║128║║║
║テスト║Test_Log║D:\ Logs\Test_DB.ldf║256║2048║128║シンプル║何もしない║
╚══════╩══════════╩════ ═════════════════════╩══════╩═════════╩════════╩══ ════════╩═════════════╝

次のクエリを使用して、SQL Server 2012+のログ領域の使用状況を確認できます。

SELECT su.database_id
    , LogSizeMB = su.total_log_size_in_bytes / 1048576E0
    , LogUsedMB = su.used_log_space_in_bytes / 1048576E0
    , LogUsedPercent = su.used_log_space_in_percent
FROM sys.dm_db_log_space_usage su;

sys.dm_db_log_space_usageの出力は次のようになります。

╔═════════════╦═════════════╦═══════════╦═════════ ═══════╗
║database_id║LogSizeMB║LogUsedMB║LogUsedPercent║
╠═════════════╬════════ ═════╬═══════════╬════════════════╣
║7║255.9921875║6.171875║2.410962║
╚═════════════╩═════════════╩═══════════╩═════ ═══════════╝

SQL Server 2016+には、VLFに関する詳細を提供するsys.dm_db_log_infoという名前の動的管理関数が含まれています。

それを使用する方法の例:

DECLARE @DatabaseId tinyint = DB_ID('msdb');
SELECT DatabaseName = d.name
    , FileName = mf.physical_name
    , ddli.vlf_begin_offset
    , ddli.vlf_size_mb
    , ddli.vlf_active
    , ddli.vlf_status
FROM sys.dm_db_log_info (@DatabaseId) ddli
    INNER JOIN sys.databases d ON ddli.database_id = d.database_id
    INNER JOIN sys.master_files mf ON ddli.file_id = mf.file_id AND ddli.database_id = mf.database_id
ORDER BY d.name
    , mf.file_guid;

出力は次のようになります。

╔══════════════╦══════════════════════════════╦═══ ═══════════════╦═════════════╦════════════╦═══════ ═════╗
║DatabaseName║FileName║vlf_begin_offset║vlf_size_mb║vlf_active║vlf_status║
╠══════════════╬═════ ═════════════════════════╬══════════════════╬═════ ════════╬════════════╬════════════╣
║msdb║F:\ Data\msdb\log\msdblog.ldf║31064064║10║0║0║
║msdb║F:\ Data\msdb\log\msdblog.ldf║41549824║10║0║0║
║msdb ║F:\ Data\msdb\log\msdblog.ldf║52035584║10║1║2║
║msdb║F:\ Data\msdb\log\msdblog.ldf║62521344║10║0║0 ║
║msdb║F:\ Data\msdb\log\msdblog.ldf║73007104║10║0║0║
║msdb║F:\ Data\msdb\log\msdblog.ldf 834 83492864║10║ 0║0║
║msdb║F:\ Data\msdb\log\msdblog.ldf 939 93978624║10.37║0║0║
╚═══════════ ═══╩══════════════════════════════╩═══════════════ ═══╩═════════════╩════════════╩════════════╝

ログの詳細については、sys.dm_db_log_statsが優れた情報を提供します。

SELECT *
FROM sys.dm_db_log_stats(@DatabaseId)

出力には次の列が含まれます。

database_id 
 recovery_model 
 log_min_lsn 
 log_end_lsn 
 current_vlf_sequence_number 
 current_vlf_size_mb 
 total_vlf_count 
 total_log_size_mb [____。] total_log_size_mb [.______ .____。 。] log_recovery_size_mb 
 recovery_vlf_count

詳細については、SQLServerScience.comにブログの投稿を書きました ログファイルのVLFの最適な数のサイズ設定

14
Max Vernon

もちろん、フルリカバリを使用するかどうかは非常に重要です。これには、はるかに大きなログファイルが必要になるためです。そして、それはあなたのバックアップがデータ損失からのあなたの唯一の保護ではないことを意味します。重要なのは、データをまったく失うことがビジネスにとって非常に悪い場合です。私たちの一部は、非常にまれに、一日のデータを失うことに耐えることができます。

関連する読み物:

https://www.brentozar.com/blitz/high-virtual-log-file-vlf-count/

https://www.sqlskills.com/blogs/kimberly/transaction-log-vlfs-too-many-or-too-few/

https://www.sqlskills.com/blogs/paul/important-change-vlf-creation-algorithm-sql-server-2014/

これらの最初のものは、1000の仮想ログファイルが都合の良いときにアクションを実行する計画の理由であると断言し、指示にリンクしています。さて、アプローチの概要に。

2番目のコメントでは、VLFは少なすぎたり、大きすぎたりする可能性があります。

3番目は、動作が変更されたSQL Server 2014の前後で、指定された増分サイズ内に作成されるVLFの数の式を示しています。何と言ってみませんか...

また、物理ログファイルの数を考慮することもできます...

ここには、多くのデータベースがあり、ある程度大きいデータベースとそうでないデータベースがあり、シンプルリカバリを使用しています。私が実際にログの自動拡張に選択した妥協点は、1 MB(!)の初期サイズと63 MBの増分であり、4つの仮想ログファイルを構成していました。小規模なデータベースの場合、1 MBが不足している場合にこれが十分な合計ログスペースであると想定して、16 MBの増分を作成しました。次のサイズステップとして、それぞれに64 MBを割り当てる必要はありません。 、データベースがたくさんあります。

(更新-「はるかに大きなログファイルが必要になるため」を追加。)

5
Robert Carnegie

古いバージョンのSQLでは、VLFが回復時間に影響を及ぼし始めるしきい値は低くなりましたが、新しいバージョンのSQLでは、5kマーク以上になるまで悪影響が見られない場合があります。その多くは、実際にはハードウェア構成と実行しているSQL Serverのバージョンによって異なります。

たとえば、約10年前に、500以上のVLFを備えた200以上のGBデータベースを含むSQL 2005インスタンスを管理し、それらの量/サイズを削減/再構成した後、回復時間が大幅に改善されました。 SQL 2012で同様の構成を使用した同様のデータベースには何の問題もありませんでした。これは、SQLの新しいバージョンと更新されたハードウェアが原因であると考えられます。

とりあえず、最初に1000 VLFのデータベースのリカバリ時間を確認することをお勧めします。その数のVLFがリカバリ/起動時間に悪影響を与えていないようであれば、心配を始める前にしきい値を1500〜2000 VLFに調整し、必要に応じてさらに調整します。本当に、あなたの設定はあなたが心配すべきしきい値を決定するでしょう。

3
John Eisbrener