次の方法で共有


マークされたトランザクションを使用して関連データベースを一貫して復旧する (完全復旧モデル)

このトピックは、完全復旧モデルまたは一括ログ復旧モデルを使用している SQL Server データベースにのみ関連します。

2 つ以上のデータベース (関連するデータベース) に 関連する更新を行う場合は、トランザクション マークを使用して、論理的に一貫性のあるポイントに復旧できます。 ただし、この復旧では、復旧ポイントとして使用されたマークの後にコミットされたトランザクションはすべて失われます。 トランザクションのマーキングは、関連するデータベースをテストする場合、または最近コミットされたトランザクションを失うことをいとわない場合にのみ適しています。

関連するすべてのデータベースで関連するトランザクションを定期的にマークすると、データベース内に一連の共通の復旧ポイントが確立されます。 トランザクション マークはトランザクション ログに記録され、ログ バックアップに含まれます。 障害が発生した場合は、各データベースを同じトランザクション マークに復元して、一貫性のあるポイントに復旧できます。

異なるデータベースのログ バックアップは、互いに独立して作成でき、同時に作成する必要はありません。

次のシナリオで関連データベースを復旧するには、すべての関連データベースでトランザクションを既にマークしておく必要があります。

  • 1 つ以上のトランザクション ログが破棄されます。 前回のログ バックアップ時に、一連のデータベースを一貫した状態に復元する必要があります。

  • データベースのセット全体を、ある時点で相互に一貫性のある状態に復元する必要があります。

重要

関連するデータベースは、特定の時点ではなく、マークされたトランザクションにのみ復旧できます。

マーキング トランザクションを作成する方法については、このトピックで後述する「マークされたトランザクションの作成」を参照してください。

マークされたトランザクションを使用する一般的なシナリオ

マークされたトランザクションを使用する一般的なシナリオには、次の手順が含まれます。

  1. 関連する各データベースの完全または差分データベース バックアップを作成します。

  2. すべてのデータベースでトランザクション ブロックをマークします。

  3. すべてのデータベースのトランザクション ログをバックアップします。

  4. NORECOVERY を使用してデータベース バックアップを復元します。

  5. STOPATMARK を使用してログを復元します。

マークされたトランザクションの使用に関する考慮事項

トランザクション ログに名前付きマークを挿入する前に、次の点を考慮してください。

  • トランザクション マークはログ領域を消費するため、データベース復旧戦略で重要な役割を果たすトランザクションにのみ使用します。

  • マークされたトランザクションのコミット後、msdblogmarkhistory テーブルに行が挿入されます。

  • マークされたトランザクションが、同じデータベース サーバー上または異なるサーバー上の複数のデータベースにまたがる場合は、影響を受けるすべてのデータベースのログにマークを記録する必要があります。

マークされたトランザクションの作成

マークされたトランザクションを作成するには、 BEGIN TRANSACTION ステートメントと WITH MARK [description] 句を使用します。 省略可能な 説明 は、マークのテキストの説明です。 トランザクションの識別名が必要です。 マーク名は再利用できます。 トランザクション ログには、マーク名、説明、データベース、ユーザー、datetime 情報、ログ シーケンス番号 (LSN) が記録されます。 datetime 情報はマーク名と共に使用され、マークを一意に識別します。

一連のデータベースでマークされたトランザクションを作成するには:

  1. BEGIN TRAN ステートメントでトランザクションに名前を付け、WITH MARK 句を使用する

    既存のトランザクション内で、ステートメント BEGIN TRAN new_mark_name WITH MARK を入れ子にすることができます。 new_mark_nameの値は、トランザクションがトランザクション名を持っている場合でも、トランザクションのマーク名です。

    2 つ目の入れ子になった BEGIN TRAN...WITH MARK を発行した場合、そのステートメントはスキップされますが、警告メッセージが表示されます。

  2. セット内のすべてのデータベースに対して更新を実行します。

    特定のトランザクションのマークは、BEGIN TRAN...WITH MARK ステートメントが実行されるサーバー インスタンスでのみ、トランザクション ログに挿入されます。 トランザクション マークは、そのサーバー インスタンス上のマークされたトランザクションによって更新されたすべてのデータベースのトランザクション ログに配置されます。 データベースが異なるサーバー インスタンスに存在する場合は、各サーバー インスタンスに同じマークを作成する必要があります。

例示

次の例では、ListPriceUpdateという名前のマーク付きトランザクションのマークまでトランザクション ログを復元します。

USE AdventureWorks  
GO  
BEGIN TRANSACTION ListPriceUpdate  
   WITH MARK 'UPDATE Product list prices';  
GO  
  
UPDATE Production.Product  
   SET ListPrice = ListPrice * 1.10  
   WHERE ProductNumber LIKE 'BK-%';  
GO  
  
COMMIT TRANSACTION ListPriceUpdate;  
GO  
  
-- Time passes. Regular database   
-- and log backups are taken.  
-- An error occurs in the database.  
USE master  
GO  
  
RESTORE DATABASE AdventureWorks  
FROM AdventureWorksBackups  
WITH FILE = 3, NORECOVERY;  
GO  
  
RESTORE LOG AdventureWorks  
   FROM AdventureWorksBackups   
   WITH FILE = 4,  
   RECOVERY,   
   STOPATMARK = 'ListPriceUpdate';  

マークを他のサーバーに拡散させる

トランザクション が分散されるため、トランザクション マーク名は別のサーバーに自動的に分散されません。 マークを他のサーバーに強制的に分散させるには、BEGIN TRAN WITH MARK ステートメントを含むストアド プロシージャを記述する必要があります。 そのストアド プロシージャは、元のサーバーのトランザクションのスコープの下でリモート サーバーで実行する必要があります。

たとえば、SQL Server の複数のインスタンスに存在するパーティション データベースを考えてみましょう。 各インスタンスには、 coyoteという名前のデータベースがあります。 まず、すべてのデータベースで、ストアド プロシージャ (たとえば、 sp_SetMark) を作成します。

CREATE PROCEDURE sp_SetMark  
@name nvarchar (128)  
AS  
BEGIN TRANSACTION @name WITH MARK  
UPDATE coyote.dbo.Marks SET one = 1  
COMMIT TRANSACTION;  
GO  

次に、すべてのデータベースにマークを配置するトランザクションを含むストアド プロシージャ sp_MarkAll を作成します。 sp_MarkAll は、任意のインスタンスから実行できます。

CREATE PROCEDURE sp_MarkAll  
@name nvarchar (128)  
AS  
BEGIN TRANSACTION  
EXEC instance0.coyote.dbo.sp_SetMark @name  
EXEC instance1.coyote.dbo.sp_SetMark @name  
EXEC instance2.coyote.dbo.sp_SetMark @name  
COMMIT TRANSACTION;  
GO  

Two-Phase コミット

分散トランザクションのコミットは、準備とコミットの 2 つのフェーズで行われます。 マークされたトランザクションがコミットされると、マークされたトランザクション内の各データベースのコミット ログ レコードは、どのログにも疑わしいトランザクションがない時点でログに格納されます。 この時点で、あるログではコミット済みとして表示されるが、別のログではコミットされていないトランザクションが存在しないことが保証されます。

次の手順では、マークされたトランザクションのコミット中にこれを実現します。

  1. マーキングトランザクションの準備フェーズでは、すべての新しい準備とコミットが停止します。

  2. 続行できるのは、既に準備されているトランザクションのコミットのみです。

  3. トランザクションをマークした後、準備中のすべてのトランザクションが完了するまで待機します(タイムアウトあり)。

  4. マークされたトランザクションが準備され、コミットされます。

  5. 新しい準備とコミットの遅延が解消されました。

複数のデータベースにまたがるマークされたトランザクションによって生成されるストールにより、サーバーのトランザクション処理パフォーマンスが低下する可能性があります。

マークされた同時トランザクションは実行しないことをお勧めします。 分散マーク付きトランザクションのコミットが、同時にコミットされている他の分散マーク付きトランザクションとデッドロックする可能性はまれです。 この場合、マーキング トランザクションはデッドロックの対象として選択され、ロールバックされます。 このエラーが発生すると、アプリケーションはマークされたトランザクションを再試行できます。 複数のマークされたトランザクションが同時にコミットしようとすると、デッドロックの可能性が高くなります。

マークされたトランザクションへの復旧

特定のマークに対して、または特定のマークの直前にマークされたトランザクションを含むデータベースを回復する方法については、「マークされたトランザクションを 含む関連データベースの復旧」を参照してください。

こちらもご覧ください

分散トランザクションの開始 (Transact-SQL)
システム データベースのバックアップと復元 (SQL Server)
BEGIN TRANSACTION (Transact-SQL)
トランザクション ログ バックアップの適用 (SQL Server)
データベースの完全バックアップ (SQL Server)
RESTORE (Transact-SQL)
マークされたトランザクションを含む関連データベースの復旧