SE の雑記

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

FCI の SQL Server の分散トランザクションで未解決のトランザクションを意図的に作り出す

leave a comment

Always On FCI (フェールオーバークラスターインスタンス) の SQL Server の分散トランザクション (MSDTC) で、意図的に未解決(in-doubt) のトランザクションを作成して検証をしたいケースがあったので意図的に作り出す方法を。

以前は SQL Server の分散トランザクション使用時のインダウトトランザクション (未解決のトランザクション) について で作り出していましたが、FCI であればもう少しシンプルな方法で作り出すことができます。

FCI で意図的に未解決のトランザクションを作り出す方法

サービスの再起動を伴う方法となりますが、「分散トランザクションのトランザクションが存在している状態で MSDTC アクセスができなくなる」というような状態を作り出すことによって未解決のトランザクションを作り出すことができます。

最初に、SQLQueryStress 等のツールで次のようなクエリを実行しておきます。

SET XACT_ABORT ON;
BEGIN TRAN
	INSERT INTO T1 VALUES(1)
	INSERT INTO [SQL-CL02].[DB01].[dbo].[T1] VALUES (1)
COMMIT TRAN

 

今回は次のような設定で実行しています。

image

このようなクエリを実行している最中に、次のようなコマンドを実行して MSDTC が停止している状態で、SQL Server のサービスを再起動します。

Start-ClusterResource -Name MSDTC-SQL-CL01-DTC
Start-Sleep -Seconds 10
Test-ClusterResourceFailure -Name MSDTC-SQL-CL01-DTC

Stop-ClusterGroup -Name "SQL Server (MSSQLSERVER)"
Start-ClusterGroup -Name "SQL Server (MSSQLSERVER)"

これを実行すると、SQL Server のサービスは起動しているが MSDTC は障害が発生している状態となります。

image

これにより、SQL Server のサービスが再起動したタイミングで MSDTC にアクセスすることができず、サービスの再起動前に実行していた分散トランザクションの復元ができない状態となります。

この状態で SQL Server に接続をしてみると、分散トランザクションを実行していたデータベースが「未確認」の状態となります。

image

ERRORLOG を確認すると、次のようなメッセージが出力され、未解決の分散トランザクションが存在する状態になっていることが確認できます。

Resource Manager Creation Failed: 0x8004d01c(XACT_E_CONNECTION_DOWN)
SQL Server detected a DTC/KTM in-doubt transaction with UOW  {F75BDB59-DB62-4550-B02D-C1287A0B9AFA}.Please resolve it following the guideline for Troubleshooting DTC Transactions.
Error: 3437, Severity: 21, State: 3.
An error occurred while recovering database 'DB01'. Unable to connect to Microsoft Distributed Transaction Coordinator (MS DTC) to check the completion status of transaction (0:3406620). Fix MS DTC, and run recovery again.
Parallel redo is shutdown for database 'DB01' with worker pool size [2].
Error: 3414, Severity: 21, State: 2.
An error occurred during recovery, preventing the database 'DB01' (5:0) from restarting. Diagnose the recovery errors and fix them, or restore from a known good backup. If errors are not corrected or expected, contact Technical Support.
Recovery is complete. This is an informational message only. No user action is required.
Attribute synchronization initialized
Attribute synchronization manager initialized

 

この状態になった場合の解決方法については、次のドキュメント / 記事が参考となります。

未解決のトランザクションが数個なのであれば、トランザクション単位で次のようなクエリを実行することで、トランザクションの取り消しを行うことができます。(UOW の GUID については ERRORLOG から確認することができます)

KILL '<UOW>' WITH ROLLBACK
GO
ALTER DATABASE <DB 名> SET ONLINE
GO

実行例:
KILL 'F75BDB59-DB62-4550-B02D-C1287A0B9AFA' WITH ROLLBACK
GO
ALTER DATABASE DB01 SET ONLINE
GO

 

複数の未解決のトラザクションが存在する場合、一つ一つ UOW を指定して DB のオンライン化を試す必要があるのですが、大量のトランザクションが未解決となってしまっている場合一つ一つを取り消して行くことは難しいかと思います。

そのような場合は、次のように in-doubt xact resolution を設定することで一括で処理することができます。

EXEC sp_configure 'show advanced options', 1
RECONFIGURE

EXEC sp_configure 'in-doubt xact resolution', 2
RECONFIGURE  
GO

ALTER DATABASE DB01 SET ONLINE
GO

-- 既定値に戻す場合は次のクエリを実行
EXEC sp_configure 'in-doubt xact resolution', 0
RECONFIGURE  
GO

 

上記のサンプルクエリはロールバックを行っていますが、「KILL ‘<UOW>’ WITH COMMIT」「EXEC sp_configure ‘in-doubt xact resolution’, 1」でコミットを行うことも可能です。

 

分散トランザクションを実行している最中で、MSDTC のサービスを起動 / 停止を繰り返すことで、SQL Server のサービスを再起動しなくても未解決のトランザクションが発生した状態を作り出すこともできるのですが、発生する確度が低く、すぐに状況を作り出すことも難しいため、SQL Server のサービス再起動が許容されるのであれば、このような方法を使ってしまったほうが手っ取り早いかと思います。

Share

Written by Masayuki.Ozawa

4月 11th, 2024 at 11:19 pm

Posted in SQL Server

Tagged with

Leave a Reply