高速データベース復旧を管理する

適用対象: はいSQL Server 2019 (15.x)

ADR の有効化と制御

SQL Server 2019 (15.x) では ADR は既定でオフになっており、DDL 構文を使用して制御できます。

ALTER DATABASE [DB] SET ACCELERATED_DATABASE_RECOVERY = {ON | OFF}
[(PERSISTENT_VERSION_STORE_FILEGROUP = { filegroup name }) ];

この構文を使用してこの機能のオン/オフを制御し、永続的なバージョン ストア (PVS) データに特定のファイルグループを指定します。 ファイル グループが指定されていない場合、PVS はプライマリ ファイル グループに格納されます。

この状態を変更する場合、SQL によってデータベースが排他的ロックされることに注意してください。 つまり、ALTER DATABASE コマンドはすべてのアクティブなセッションが終了するまで停止し、新しいセッションは ALTER DATABASE コマンドが終了するまで待機します。 操作を完了してロックを解除することが重要な場合は、終了句 WITH ROLLBACK [IMMEDIATE | AFTER {数値} SECONDS | NO_WAIT] を使用して、データベース内のすべてのアクティブなセッションを中止できます。

永続的なバージョン ストア ファイルグループの管理

ADR 機能は変更をバージョン管理することを基盤としており、さまざまなバージョンのデータ要素が PVS に保管されます。 PVS の場所の見つけ方と PVS に含まれるデータ サイズの管理方法には注意点があります。

ファイルグループを指定せずに ADR を有効にするには

ALTER DATABASE [MyDatabase] SET ACCELERATED_DATABASE_RECOVERY = ON;
GO

この場合、PVS ファイルグループが指定されていないとき、PRIMARY ファイルグループで PVS データが保持されます。

ADR を有効にし、PVS を [VersionStoreFG] ファイルグループに格納するように指定するには

このスクリプトを実行する前に、ファイルグループを作成します。

ALTER DATABASE [MyDatabase] SET ACCELERATED_DATABASE_RECOVERY = ON
(PERSISTENT_VERSION_STORE_FILEGROUP = [VersionStoreFG])

ADR 機能を無効にするには

ALTER DATABASE [MyDatabase] SET ACCELERATED_DATABASE_RECOVERY = OFF;
GO

ADR 機能が無効になった後でも、論理的に元に戻すときに必要となる永続的なバージョン ストアにバージョンが格納されます。

PVS の場所を別のファイルグループに変更する

さまざまな理由から、PVS の場所を別のファイルグループに移さなければならないことがあります。 たとえば、PVS でもっとたくさんの領域が必要になったり、高速のストレージが必要になったりすることがあります。

PVS の場所の変更は、3 つの手順からなるプロセスです。

  1. ADR 機能をオフにします。

    ALTER DATABASE [MyDatabase] SET ACCELERATED_DATABASE_RECOVERY = OFF;
    GO
    
  2. PVS に格納されているすべてのバージョンを解放できるようになるまで待ちます。

    ADR をオンにし、永続的なバージョン ストアに新しい場所を指定するには、まず、PVS の前の場所からバージョン情報がすべて削除されていることを確認する必要があります。 その消去を強制するには、次のコマンドを実行します。

    EXEC sys.sp_persistent_version_cleanup [database name]
    

    sys.sp_persistent_version_cleanup ストアド プロシージャは同期型です。つまり、現行の PVS からすべてのバージョン情報が消去されるまで完了となりません。 完了したら、DMV sys.dm_persistent_version_store_stats を問い合わせ、persistent_version_store_size_kb の値を調べることでバージョン情報が確かに削除されていることを確認できます。

    SELECT DB_Name(database_id), persistent_version_store_size_kb 
    FROM sys.dm_tran_persistent_version_store_stats where database_id = [MyDatabaseID]
    

    persistent_version_store_size_kb の値が 0 のとき、ADR 機能を再度有効にし、PVS を新しいファイルグループに置くように構成できます。

  3. PVS の新しい場所を指定して ADR をオンにする

    ALTER DATABASE [MyDatabase] SET ACCELERATED_DATABASE_RECOVERY = ON
    (PERSISTENT_VERSION_STORE_FILEGROUP = [VersionStoreFG])
    

トラブルシューティング

注意

このセクションは Azure SQL Database にも適用されます。

sys.dm_tran_persistent_version_store_stats を問い合わせ、PVS のサイズを確認します。

% of DB のサイズを確認します。 また、一般的なサイズとの違いにもご注意ください。

PVS は、ベースラインより大幅に大きいか、データベース サイズの 50% に近くなっている場合に大きいと見なされます。

  1. oldest_active_transaction_id を取得し、トランザクション ID に基づいて sys.dm_tran_database_transactions を問い合わせることでこのトランザクションが本当に長時間アクティブになっているのかを確認します。

    アクティブなトランザクションがあると、PVS を消去できません。

  2. データベースが可用性グループに含まれる場合、secondary_low_water_mark を確認してください。 これは sys.dm_hadr_database_replica_states によって報告される low_water_mark_for_ghosts と同じです。 sys.dm_hadr_database_replica_states を問い合わせ、いずれかのレプリカでこの値が隠されていないか確認します。これも PVS の消去を妨げるためです。

  3. min_transaction_timestamp (あるいは、オンライン PVS の消去が妨げられている場合は online_index_min_transaction_timestamp) を確認し、それに基づいて列 transaction_sequence_numsys.dm_tran_active_snapshot_database_transactions を確認し、古いスナップショット トランザクションが PVS の消去を妨げているセッションを見つけます。

  4. 上記のいずれも該当しない場合、中止となったトランザクションによって消去が妨げられていることになります。 aborted_version_cleaner_last_start_timeaborted_version_cleaner_last_end_time を確認し、中止となったトランザクションの消去が完了しているかを確認します。 中止となったトランザクションの消去が完了した後は、oldest_aborted_transaction_id の値が上位に移動するはずです。

  5. 中止となったトランザクションが最近、正常に完了しなかった場合、エラー ログを確認し、VersionCleaner の問題を報告しているメッセージがないか確認します。

トラブルシューティングの支援として、以下のサンプル クエリをお使いください。

SELECT pvss.persistent_version_store_size_kb / 1024. / 1024 AS persistent_version_store_size_gb,
       pvss.online_index_version_store_size_kb / 1024. / 1024 AS online_index_version_store_size_gb,
       pvss.current_aborted_transaction_count,
       pvss.aborted_version_cleaner_start_time,
       pvss.aborted_version_cleaner_end_time,
       dt.database_transaction_begin_time AS oldest_transaction_begin_time,
       asdt.session_id AS active_transaction_session_id,
       asdt.elapsed_time_seconds AS active_transaction_elapsed_time_seconds
FROM sys.dm_tran_persistent_version_store_stats AS pvss
LEFT JOIN sys.dm_tran_database_transactions AS dt
ON pvss.oldest_active_transaction_id = dt.transaction_id
   AND
   pvss.database_id = dt.database_id
LEFT JOIN sys.dm_tran_active_snapshot_database_transactions AS asdt
ON pvss.min_transaction_timestamp = asdt.transaction_sequence_num
   OR
   pvss.online_index_min_transaction_timestamp = asdt.transaction_sequence_num
WHERE pvss.database_id = DB_ID();