web-dev-qa-db-ja.com

ロールバックでデータベースをオフラインに設定すると、すぐに完了するまでに1時間かかります

バックアップ手順を開始する前に、毎晩、本番データベースをオフラインにし、デタッチしてから、再接続してアクティブな接続を切断します。最初のコマンドは次のとおりです。

USE master
ALTER DATABASE thedb SET OFFLINE WITH ROLLBACK IMMEDIATE

このコマンドは、以前は20秒から2分早く完了していましたが、許容範囲内でした。過去数週間から、完了するまでに15分から1時間以上かかりました。この問題の原因となるデータベースの使用法の変更はありません。約3/4の時間しか発生しません。

私の知る限り、これを引き起こす設定は変更していません。 WITH ROLLBACK IMMEDIATEはすべての接続を切断し、データベースはすぐにオフラインになることを理解していました。私は以下を調査してみました:

  • リカバリ間隔は0に設定されているため、チェックポイントは数分ごとに発生し、完了するのに1秒しかかかりません
  • 統計は非同期に更新されません
  • データベースがオフラインになる直前に大きなクエリが実行されていない
  • データベースがオフラインになっているときにsp_who2をチェックすると、それに接続しているユーザーが表示されません。
  • データベースのログファイルは非常に小さく、30 MB以下です。

現在、MSSQL Server 2012(Standard Edition)をミラーリングなしのシンプルリカバリモードで実行しています。データベースのサイズは約300 GBです。

助けてくれてありがとう、ありがとう!

6
GUIs

あなたが見ているものは完全に正常だと思います。

毎晩、本番データベースをオフラインにし、デタッチしてから再作成し、バックアップ手順の開始時に接続を切断します。

あなたはなぜこれをやっているのですか ?。これは常に正しいことではなく、これがまさに問題に直面している理由です。データベースがオンラインのときにデータベースをバックアップできます。これはhow SQL Serverデータベースをバックアップする必要があります。データベースがonlineのときに実行する完全バックアップには、バックアップの完了時にデータベースに対して行われたすべてのコミット済み変更が含まれます。アクティビティの前にsingle_userモードとrestricted_userモードを維持すると、問題が完全に解決しない場合があります。

このコマンドは、完了するまでに20秒から2分かかりましたが、これは許容範囲でした。過去数週間、完了するまでに15分から1時間以上かかりました。

また、実行時間の長いクエリはないと言っていました。そのため、トリプルチェックと言います。データベースの変更にはデータベースへの排他的アクセスが必要であり、他のクエリによってブロックされている可能性があります。確認してください。

_begin transaction_で実行されているトランザクションを確認しましたが、コミットが失敗した可能性があります。 DBCC OPENTRAN()を実行して、開いているトランザクションを確認します。エラーログにはこれに関する詳細情報があります

他に目にするのは、alterコマンドを実行すると、ロールバックが必要なクエリがほとんど実行されないため、コマンドがすぐに終了する一方で、データベースをオフラインにする前に完全にロールバックする必要があるコマンドが実行されている場合があります。実行する必要があるロールバックの量に応じて、時間は異なります。

データベースをオフラインモードにすることはお勧めしません。これを使用することはありません。

4
Shanky

まず、データベースがシンプルリカバリモードで維持される理由がわかりません。データベースが本番データベースの場合は、データベースをフルリカバリモードで維持し、トランザクションのボリュームに基づいて差分バックアップとログバックアップを行うことを強くお勧めします。また、データの損失または復旧ポイントに関するSLAのビジネス要件に基づいています。詳細については、こちらをご覧ください。

https://www.sqlshack.com/backup-and-restore-sql-server-disaster-recovery/

現在、夜間に完全バックアップのみを実行しており、他のバックアップは実行していない場合(回復モードがシンプルであるため、ログバックアップは実行できないため、差分バックアップ)、データベースが日中にクラッシュした場合-すべての変更が失われます最後に成功した完全バックアップの後にデータベースに。したがって、私の最初のアドバイスは、回復モードを変更し、差分バックアップとログバックアップを取ることです。

バックアップを取る前に接続を切断するという点で-まったく必要ありませんが、ホットバックアップを行うことができます。これは、データベースがマルチユーザーモードでユーザーがアクティブに作業しているときに行うことができます(バックアップはより少ない時間で実行することをお勧めしますが)交通時間)。バックアップ前にすべての接続を閉じるのが難しくて速い場合は、提供されたコマンドを使用してオフラインにする前に、データベースをシングルユーザーモードにする必要があります。

アクティブなトランザクションを確認するために、Adam Machanic氏の非常に有名なストアドプロシージャsp_whoisactiveを使用できます。これにより、実行中のセッションに関するすべての情報と、sp_whoまたはsp_who2を使用して実行できない他の多くの詳細が得られます。バックアップの直前にこの手順をスケジュールし、後で参照するために出力をテーブルにリダイレクトできます。上記の回答で提案されているように、DBCC OPENTRAN()を使用してアクティブなトランザクションを確認することもできます。

全体として、バックアップを取るために実行されているプロセスに問題があるようです。これで問題が解決した場合はお知らせください。

0