web-dev-qa-db-ja.com

トランザクションログがいっぱいになるたびにデータベースがリカバリモードになる

なかなか対応が難しい状況にあります。何が起こっているのか理解するのに助けが必要です。

TL; DR:SQL Serverでトランザクションログがいっぱいになるたびにneedsデータベースをシャットダウンしてリカバリモードに入り、問題のあるトランザクションをロールバックしますか?これは常に設計によって行われますか、またはこれは何か悪いことが起こったときにのみ起こりますか?


シナリオ:

使用頻度の高い本番データベースの1つは、いくつかのETLジョブと長時間実行されるテーブルバッチを実行し、リカバリモードになり、しばらくの間アクセスできなくなりました。これは今週3回発生しました(このサーバーは約2年間稼働しており、過去にこの問題に気づいていませんでした)。

エラーログを確認すると、何が起こったのかがわかりました。トランザクションログがいっぱいで、データベースがトランザクションをロールバックする必要があり、ロールバックが失敗し、データベースがシャットダウンし、リカバリモードで起動しました。

DBAはこれをSQL Serverの通常の動作として防御します。つまり、彼によると、トランザクションログがいっぱいになり、トランザクションがデータベースをロールバックする必要があるときは、ログスペースの不足のためにリカバリモードに移行します。ロールバック(回復モードでのみ実行できる)の後、データベースは再び使用可能になります。

この情報への参照は見つかりませんでした。だから私は強く同意しません。私が間違っていると誰かに説得されたら、私は本当に感謝します。

私のポイント:

私の知る限り、DBMSはクエリを管理/実行するために構築されています。スペースがない場合、クエリは失敗します。単純です。そして、私は他のもののパフォーマンスについて話しているのではなく、可用性のみについて話している。

トランザクションをロールバックするために、DBMSがそれ自体をシャットダウンする必要があることを受け入れることは、私にとって意味がありません。私の理解では、大量のクエリを実行しているかどうか、またはクエリの設計が悪いかどうかは問題ではありません。不正なクエリは失敗し、寿命は続くはずです。ね?

私の推測では、何か他のことが原因で失敗しているため、何が起こっているのか追跡する必要があります。

私の理解が間違っているのですか、これが実際にSQL Serverが機能するように設計されているのですか?私が間違っていないとしたら、この問題の原因を追跡するために他に何ができますか?


いくつかの追加情報

  • select @@version:Microsoft SQL Server 2012(SP1)-11.0.3156.0(X64)May 5 2015 18:48:09 Copyright(c)Microsoft Corporation Standard Edition(64-bit)on Windows NT 6.2(Build 9200:)
  • このデータベースは単純復旧モデルです。
  • 同じインスタンスに他のデータベースがあります。同じ問題は発生しませんが、あまり使用されていません。
  • トランザクションログのみがいっぱいで、ディスクはいっぱいではありません。ディスクには十分なスペースがありますが、データベースのログサイズは制限されています。
  • このサーバーを監視し、CPU負荷、メモリ使用量、ディスクがRAID-5を使用しており、コントローラーはクラッシュや読み取りエラーを発生させていません。リソース使用量にはいくつかのピークがありますが、珍しいものはありません。
  • クエリを改善してログを効率的に使用できることを知っています。また、トランザクションログ領域を増やすことができることも知っています。しかし、これは本当にここでの私のポイントではありません。
  • 最近、このデータベースを管理するためにDBAが雇われました。そのため、チューニングのために、いくつかの構成が最近変更されました。彼は私にすべての変更を認識させました(自動縮小の無効化、自動拡張サイズの拡大など)。データベースに害を及ぼす可能性のあるものは何も見つかりませんでした。

ログダンプ(発生順に、重複が削除されます)

[02:58:37am ~ 04:47:42pm, 12 times]エラー:845。重大度:17.状態:1。ページのバッファーラッチタイプ3を待機中にタイムアウトが発生しました(1:8728760)。データベースID 7. FlushCache:db 7:0の平均スループットが1.0540 MB /秒の場合、77540ミリ秒で6709回の書き込みで10460バフをクリーンアップ(864の新しいダーティバフを回避)。 I/O飽和:107。コンテキストスイッチ391最後のターゲットの未解決:4800。avgWriteLatency0 FlushCache:95448のブフをクリーンアップし、85820ミリ秒で37560の書き込み(60465の新しいダーティバッファを回避)で、db 7:0の平均スループット:8.69 MB /秒。 I/O飽和:17026。コンテキストスイッチ20713未処理の最後のターゲット:446。avgWriteLatency3。

[02:58:37am ~ 04:47:42pm, 13 times]バッファラッチの待機中にタイムアウトが発生しました-タイプ3。bp000000109B9E69C0。ページ1:73430228。 stat 0x10b。データベースID:7.アロケーションユニットID:72057594304790528。タスク0x00000008BC0850C8:1.待機時間300秒。フラグ0x100000001a。所有タスク0x0000000827B38188。待ち続けない。

[02:58:37am ~ 04:47:42pm, 12 times]エラー:5901。重大度:16.状態:1.データベース「XXXXXXXXXX」に属する1つ以上のリカバリユニットがチェックポイントの生成に失敗しました。これは通常、ディスクやメモリなどのシステムリソースの不足や、場合によってはデータベースの破損が原因です。このエラーの詳細については、エラーログの以前のエントリを調べてください。

[05:14:29pm ~ 05:14:53pm, 9 times]エラー:9002。重大度:17.状態:4。'ACTIVE_TRANSACTION 'により、データベース' XXXXXXXXXX 'のトランザクションログがいっぱいです。

[05:14:53pm, once]エラー:3314。重大度:21。状態:3.ルーチン「XdesRMReadWrite :: RollbackToLsn」のエラー3314により、データベースXXXXXXXXXXがシャットダウンされました。データベースへのすべての接続が中止された後、非スナップショットデータベースの再起動が試行されます。

[05:14:53pm ~ 05:14:53pm, 16 times]エラー:3314。重大度:21。状態:3。データベース「XXXXXXXXXX」でログに記録された操作を元に戻すときに、ログレコードID(8064074:20971:110)でエラーが発生しました。通常、特定の障害は、Windowsイベントログサービスのエラーとして以前に記録されています。バックアップからデータベースまたはファイルを復元するか、データベースを修復します。

[05:14:53pm ~ 05:14:53pm, 9 times]エラー:9001。重大度:21。状態:5.データベース「XXXXXXXXXX」のログは使用できません。イベントログで関連するエラーメッセージを確認してください。エラーを解決し、データベースを再起動します。

[05:14:58, once]データベース「XXXXXXXXXX」を起動しています。

[05:15:02, once]データベース 'XXXXXXXXXX'(7)のリカバリは0%完了しています(残り約2931秒)。フェーズ1/3。これは情報メッセージです。ユーザーの操作は必要ありません。

...

[05:51:01pm, once] 6個のトランザクションがデータベース 'XXXXXXXXXX'(7:0)にロールバックされました。これは情報メッセージです。ユーザーの操作は必要ありません。

[05:51:01pm, once]リカバリはデータベース 'XXXXXXXXXX'(7)にチェックポイントを書き込んでいます。これは情報メッセージです。ユーザーの操作は必要ありません。

[05:56:47pm, once]データベースXXXXXXXXXX(データベースID 7)のリカバリが2505秒で完了しました(分析1774 ms redo 406623 ms undo 1749182 ms。)これは情報メッセージです。ユーザーの操作は必要ありません。

エラーログまたはイベントビューアで他の関連するログエントリが見つかりませんでした。イベントビューアで発生する最も近いエラーは次のとおりです。

[04:56:45pm ~ 05:27:24pm, 13 times]アプリケーション固有の権限設定は、CLSID {FDC3723D-1588-4BA3-92D4-42C430735D7D}およびAPPID {83B33982-693D-4824-B42E-7196AE61BB05}を使用して、COMサーバーアプリケーションのローカルアクティベーション権限をユーザーMY_DOMAIN \に付与しませんアプリケーションコンテナーで実行されているアドレスLocalHost(LRPCを使用)からのdba.personal.user SID(S-1-5-21-000000000-000000000-0000000000-00000)使用不可SID(使用不可)。このセキュリティ権限は、コンポーネントサービス管理ツールを使用して変更できます。

このエラーは、データベースがリカバリプロセスを開始する約18分前に発生し、リカバリの開始時にときどき繰り返されました。それはDBAユーザーと多少関係がありますが、それが何であるかは本当にわかりません(まだDBAに依頼する時間はありませんでした)。

7
Diego Queiroz

まず、いくつかのハウスキーピングルールです。

  • ユーザー(またはDBA)は、復旧モデルに応じてトランザクションログ領域を管理する必要があります。
  • トランザクションログがいっぱいになり、データベース/アプリケーションの可用性に影響を与えないようにしてください。

2つのリンクをたどると、トランザクションログファイルをより適切に管理できます。

トランザクションログファイルがいっぱいになり、それ以上拡張できない場合、通常の動作ではありません。

トランザクションログがいっぱいになると、SQL Serverデータベースエンジンは9002エラーを発行します。ログは、データベースがオンラインのとき、またはリカバリ中にいっぱいになることがあります。データベースがオンラインのときにログがいっぱいになると、データベースはオンラインのままですが、読み取ることはできますが、更新することはできません。回復中にログがいっぱいになると、データベースエンジンはデータベースをRESOURCE PENDINGとしてマークします。どちらの場合も、ログ領域を使用可能にするためにユーザーの操作が必要です。

完全なトランザクションログへの適切な応答は、ログがいっぱいになる原因となった条件によって部分的に異なります。特定のケースでログの切り捨てを妨げている原因を見つけるには、sys.databaseカタログビューのlog_reuse_waitおよびlog_reuse_wait_desc列を使用します。

表示されているのは、トランザクションのロールバックの失敗です。詳細については、この投稿をご覧ください。

Paul Randalのブログ投稿によると、SQL 2012 SP4で修正されたバグを見つけました。

エラー3314の詳細:

参照:

3
SqlWorldWide

これはあなたの問題に対する私の見解です:

Microsoft SQL Server 2012(SP1)-11.0.3156.0

これはかなり古いビルドで、新しいSPには多くの修正が加えられています。サーバーに SP4 atleast-11.00.7001 をパッチする必要があります。

エラー:845。重大度:17。状態:1。

これは問題を引き起こしているディスクサブシステムです。 \ MSSQL\LOG\sqldumpフォルダーを確認します。スタックダンプが作成されます。 SQL Serverラッチ&デバッグラッチタイムアウト に従って分析するか、Microsoftにケースをオープンすることができます。もう一度、ディスクサブシステムを確認します。

エラー:5901。重大度:16。状態:1

これは修正されました SQL Server 2012 SP2の累積的な更新8

だからお持ち帰り:

  • SP4でパッチを適用し、問題が発生するかどうかを確認します。
  • ディスクの競合については、Windowsまたはストレージ管理者に確認してください。
  • 十分なRAM=があり、最大メモリが適切に設定されていることを確認してください。
  • CPU電源プランは、バランスのとれたパフォーマンスではなく、高パフォーマンスに設定されています。
  • 自動拡張を有効にする 固定MBにして、dbが適切に拡張できるようにします。
  • sp_Blitzを実行して、潜在的な問題を特定します
2
Kin Shah

データベースがすでにシンプルリカバリモードになっているため、ログが1つのトランザクションによって保持されるまで、ログは大きくなりません。チェックポイントになると、ログ自体が切り捨てられます。ログサイズを制限したので、SQL Serverは、トランザクションが途中であり、ログを拡大する余地がない場合に、トスを行います。簡単に言えば、トランザクションを拡大するにはログが必要です。必要に応じてログを大きくしないと、トランザクションを完了できません。このため、AUTOGROWTHを有効にしておくのが最適な設定です。

SQL Serverはそれをクラッシュとして扱い、エラーログにあるように、不完全なコマンドをロールバックするためにリカバリを行います。

解決策:AUTOGROWTHを有効にします。また、これが重要なデータベースである場合は、完全復旧モードに切り替えて、ログバックアップを構成します。

2