現象
たとえば次のようなシナリオを考えてみます。
ローリング アップグレードの一部として、可用性グループのセカンダリ レプリカをホストするサーバーで Microsoft SQL Server 2014 または Microsoft SQL Server 2012 Service Pack 2 (SP2) を実行している。
次のいずれかの更新プログラムを SQL Server のインストールに適用しました。
- SQL Server 2014 累積更新プログラム 5
- SQL Server 2012 Service Pack 2 累積更新プログラム 4
- SQL Server 2012 Service Pack 2 累積的な更新プログラム 3
重要: この記事に記載されている修正プログラムを適用すると、これらの累積的な更新プログラムが置き換えられます。 これらの更新プログラムをまだ行っていない場合は、インストールしないでください。
累積的な更新プログラムのインストールを完了するには、このセカンダリ レプリカを再起動します。
更新されたセカンダリ レプリカをプライマリ ロールに移行する可用性グループをフェールオーバーします。
このシナリオでは、SQL Server を実行していて、現在可用性グループのプライマリ レプリカをホストしているサーバーで、次の現象の 1 つ以上が発生することがあります。
セカンダリ レプリカは "同期していません" と報告されます。
sys.dm_exec_requestsをクエリすると、ユーザー セッションと、コマンドが "DB_STARTUP" と報告されるセッションの間で断続的なロック ブロックが発生することがわかります。 また、CHECKPOINT コマンドと DB_STARTUP コマンドの間でブロックが発生することがあります。
可用性データベースの 1 つを回復したセッションが関与するデッドロックは、SQL Server エラー ログに報告されます。 これらのログは次のようになります。
<日付/時刻> spid<xx> リカバリはデータベース <dbname/dbid> にチェックポイントを書き込みます。 これが
情報メッセージのみです。 ユーザー操作は必要ありません。
<日付/時刻> spid<xx> データベース <dbname/dbid> の回復は <x> 秒で完了しました (分析
<x> ms、やり直し <x> ms、元に戻す <x> ms) これは唯一の情報メッセージです。 ユーザー操作は必要ありません。
…
<日付/時刻> spid<xx> エラー: 1205、重大度: 13、状態: 28。
<日付/時刻> spid<xx> トランザクション (プロセス ID <xx>) が別のトランザクションとのロック リソースでデッドロックされていました
処理され、デッドロックの対象として選択されています。 トランザクションを再実行します。可用性データベースで Microsoft SQL Server Service Broker が有効になっている場合、可用性データベース内のメッセージが正常に処理されない可能性があります。 プロファイラー トレース ツールを起動した後で、"Broker:Message Classify" イベントをキャプチャすると、次のイベントがキャプチャされます。
9791, 送信者のデータベースでブローカーは無効になっています
注: これは体系的な問題ではありません。 これらの累積的な更新プログラムを、この問題が発生することなく AlwaysOn 構成に適用できる場合があります。 これらの累積的な更新プログラムを既に適用していて、この問題に気付かなかった場合、システムは影響を受けず、この情報は適用されません。
原因
この問題は、システム スレッドとユーザー接続の間で競合状態が発生する場合があるために発生します。 これにより、累積的な更新プログラムの修正プログラム ロジックが更新プロセスを完了するために必要なロックを取得できなくなります。
解決策
この問題を解決するには、次の 重要なオンデマンド (COD) 修正プログラムを適用します。
3034679 修正: AlwaysOn 可用性グループが同期していないと報告されることがある
重要: 次の累積的な更新プログラムの代わりに、この COD 修正プログラムを適用する必要があります。
- SQL Server 2014 累積更新プログラム 5
- SQL Server 2012 Service Pack 2 累積更新プログラム 4
- SQL Server 2012 Service Pack 2 累積的な更新プログラム 3
注: これらの累積的な更新プログラムを既に適用している場合は、次の回避策を使用してこの問題を解決する必要があります。
回避策
この問題は、データベースがプライマリ ロールに移行している間に、ユーザー セッションとアップグレード セッションの間で可用性データベースに対する競合が原因で発生するため、データベースがこの状態から回復できるようにするには、この競合を排除する必要があります。
この問題を回避するには、次の手順に従ってください。
指定された順序で次の方法を試してください。
方法 1: データベースへのアクセスを排除するデータベースで「現象」に記載されている現象が発生している場合は、必要に応じて次の手順のいずれかまたは両方を使用して、ロック ブロック状態を解消します。
- クエリ sys.dm_exec_requestsを使用して、可用性データベースでロック ブロックが発生しているセッションを特定します。 これらのセッションを終了するには、KILL ステートメントを使用します。
- 可用性データベースにアクセスしているアプリケーションを無効または停止します。
方法 1 で問題が解決しない場合は、方法 2 に進みます。
方法 2: SQL Server ホスト サーバーを再起動するアプリケーション アクセスとユーザー アクセスがまだ無効になっている場合は、影響を受ける可用性データベースをホストしている SQL Server のインスタンスを再起動します。 手順は次のとおりです。
- 可用性グループの自動フェールオーバーを無効にします。
- プライマリ レプリカをホストしている影響を受ける SQL Server のインスタンスを再起動します。
- 可用性グループの自動フェールオーバーを有効にします。
影響を受けたデータベースが完全に回復したら、アプリケーションとユーザーの接続を再確立します。
状態
Microsoft は、これが "適用対象" セクションに記載されている Microsoft 製品の問題であることを確認しました。
参考資料
この問題の影響を受ける累積的な更新プログラムの詳細については、次のマイクロソフト サポート技術情報を参照してください。