web-dev-qa-db-ja.com

大規模な削除クエリがフリーズしているようです

18億行のデータベースで削除クエリを実行しました。この削除により、12億行が削除されます。

後から考えると、このクエリは一度に100mに分割されたはずですが、24時間実行されていて、ログファイルが2Tbの位置にあります。これは、ログファイルに許可されている最大サイズのようです。

データベースは単純復旧モードです。

このクエリを保存するものはありますか?または、SQL Serverを再起動して何が起こるかを確認する必要がありますか?データベースは使用できなくなりますか?これをできるだけきれいに殺すために私たちにできることはありますか?

10
Graeme

まず、SQLエラーログをチェックして、ログの最大サイズに実際に達しているかどうかを確認します。存在する場合、クエリは完了の見込みがなく、おそらくすでにロールバック状態にあります。

そうであっても、私は常に手動でspidを強制終了することを好みます(sp_who2またはsp_WhoIsActiveを使用してspidを見つけてから、kill 59などを実行します)。また、明示的なKILLを実行しない限り、ロールバックステータスをチェックできません この関連スレッドを参照

これは削除であり、更新や挿入ではないため、非常に幸運であり、すぐにロールバックされる場合があります。そうでない場合は、この時点までにロールバックするのと同じくらい長く(または長く)時間がかかることがあります。

ロールバックステータスを表示するには、次を使用します。

kill 59 with statusonly

残念ながら、私はこれがしばしば「0%完了」という有用なものを示さないことを発見しました。その場合は、sp_who2を使用し、IOとCPUを監視して、まだ何かを実行しているかどうかを確認する必要があります。

再起動に関しては、これは重大なリスクです。 spidがアクティブにロールバックしている場合(CPUとIOが変更されている場合)、SQLを再起動しても、データベースが完全にオフラインになるのは、ロールバックが完全に完了するまで(数時間)ですただし、CPUとIOがnot移動している場合、実際にはすぐにクリアされる可能性があります。いずれにしても、リスクです。

特に悲惨な場合の最後の1つのオプション:削除を開始する直前のバックアップがある場合(および、dbに他の更新がない場合)その後、最も速く回復する方法は、単にDBを削除し、SQLを再起動して、バックアップから復元することです。

DBを削除できない場合(またはインスタンスをすでに再起動していて、SQLエラーログが24時間の復旧時間を予測している場合)、SQLサービスをシャットダウンして、MDFおよびLDFを削除しますディスクからファイルを取得し、SQLを起動し、(ゴースト)データベースを削除して、バックアップから復元します。

明らかに、これが、ユーザーが操作しなかったバックエンド処理データベースである場合にのみ試行します。

14
BradC

SQLサーバーを再起動しないでください。回復が行われるため、これは苦痛を長引かせるだけであり、削除を含め、完了していないトランザクションをロールバックまたはやり直します。

削除を実行しているセッションを強制終了すると、ロールバックが発生し、完了までに長い時間がかかります。

次のクエリを見て、操作の状態を確認します。

SELECT des.session_id 
    , des.Host_name
    , des.login_name
    , der.command
    , der.estimated_completion_time
    , der.blocking_session_id
    , der.last_wait_type
    , der.percent_complete
    , der.start_time
    , der.status
    , der.wait_resource
    , der.wait_type
    , der.wait_time
FROM sys.dm_exec_sessions des
    INNER JOIN sys.dm_exec_requests der ON des.session_id = der.session_id
WHERE des.session_id <> @@SPID
    AND des.is_user_process = 1
ORDER BY des.session_id;

percent_complete列、およびestimated_completion_timeなどのそれに依存する列は、次の操作でのみ入力されます。

ALTER INDEX REORGANIZE
AUTO_SHRINK option with ALTER DATABASE
BACKUP DATABASE
DBCC CHECKDB
DBCC CHECKFILEGROUP
DBCC CHECKTABLE
DBCC INDEXDEFRAG
DBCC SHRINKDATABASE
DBCC SHRINKFILE
RECOVERY
RESTORE DATABASE
ROLLBACK
TDE ENCRYPTION

そのため、削除ステートメントをキャンセルしてロールバックしている場合、またはSQL Serverを既に再起動していて復旧中である場合にのみ、その列が意味を持つことがわかります。

blocking_session_id列に数値が含まれている場合は、他のセッションが削除操作をブロックしていることを示しています。そのセッションが開始してから削除操作をブロックしている場合は、ロールバックを実行する必要なく、操作をキャンセルできる場合があります。

8
Max Vernon