web-dev-qa-db-ja.com

SQL Server sys.dm_tran_active_transactions長時間実行トランザクションワークテーブル

今日、私はシステムオブジェクトsys.dm_tran_active_transactionsを使用しました(正直に言うと)。私は分散トランザクション(Microsoft DTC)に問題があり、sp_whoIsActive oputputだけでは手がかりがなくなった後、そこに掘り込みました。この問題は解決されましたが、テーブルに「worktable」タイプの非常に古いトランザクションがあることがわかりました。これは次のクエリの出力です

SELECT  *,
 case transaction_type   
      when 1 then 'Read/Write'   
      when 2 then 'Read-Only'    
      when 3 then 'System'   
      when 4 then 'Distributed'  
      else 'Unknown - ' + convert(varchar(20), transaction_type)     
 end as tranType,    
 case transaction_state 
      when 0 then 'Uninitialized' 
      when 1 then 'Not Yet Started' 
      when 2 then 'Active' 
      when 3 then 'Ended (Read-Only)' 
      when 4 then 'Committing' 
      when 5 then 'Prepared' 
      when 6 then 'Committed' 
      when 7 then 'Rolling Back' 
      when 8 then 'Rolled Back' 
      else 'Unknown - ' + convert(varchar(20), transaction_state) 
 end as tranState, 
 case dtc_state 
      when 0 then NULL 
      when 1 then 'Active' 
      when 2 then 'Prepared' 
      when 3 then 'Committed' 
      when 4 then 'Aborted' 
      when 5 then 'Recovered' 
      else 'Unknown - ' + convert(varchar(20), dtc_state) 
 end as dtcState
FROM    sys.dm_tran_active_transactions 
ORDER BY transaction_begin_time

enter image description here

Transaction_begin_timeは、SQL Serverサービスが最後に再起動された時刻と相関関係があります。

私はこれについて少し心配する必要がありますか? dmvの詳細については、 https://www.sqlservergeeks.com/sys-dm_tran_active_transactions/ を確認しました。ただし、一時的なクエリ結果をtempdbに格納するためにワークテーブルが使用されることについては言及しています。ただし、私の理解では、実行プランがtempdbにスプールしてワークテーブルを使用することを決定するクエリを開始すると、必要になるたびに新しいワークテーブルが作成されるということです。したがって、6つの作業テーブルが非常に古いのは奇妙に思われます。サービスが再起動してから、常に実行されるクエリを監視するために再利用されたテーブルや、内部のSQLサーバーなどで再利用されたテーブルであると仮定できます。とにかく、読み取り専用のトランザクションタイプは無害であるように見え、ブロックやバージョンストアの増加の兆候に気づきませんでした。

よろしくお願いします

マーティン

1
Martin Guth

私の2016インスタンスでも同じことがわかります-サーバーが起動して数秒後に開始された、正確に6つの作業テーブルトランザクション。 sys.dm_tran_database_transactionsに参加すると、これらのトランザクションがtempdb(database_id = 2)に存在することがわかります。

SELECT 
    dtat.transaction_id,
    dtat.[name],
    dtat.transaction_begin_time,
    dtdt.database_id
FROM sys.dm_tran_active_transactions dtat
    INNER JOIN sys.dm_tran_database_transactions dtdt
        ON dtat.transaction_id = dtdt.transaction_id;

screenshot of query results showing worktable transaction starting at 04:41:04

これは、インスタンスの起動時にtempdbがクリアされて起動されたことを示すログメッセージともかなり密接に一致しています。

screenshot of error log messages showing tempdb starting up at 04:41:03

DMVを介してこれらの「トランザクション」を特定のセッションにリンクする方法を見つけることはできませんが、システムプロセスであり、心配する必要がないと言っても安全だと思います。


これらはsp_WhoIsActiveに表示されなかったと述べたので、システムセッションはデフォルトでそのプロシージャ出力から除外されていることを指摘する価値があります。追加のパラメータを渡すことでそれらを見ることができます:

EXEC sp_WhoIsActive @show_system_spids = 1;
1
Josh Darnell