バックアップを復元するとき、アクティブな接続をすべて切断するにはどうすればよいですか?


166

SQL Server 2005は、アクティブな接続のためにバックアップを復元しません。どうすれば強制できますか?


「復元」するデータベースへのすべての接続を常に強制終了しますか?または、既存の接続を削除したくない場合がありますか?また、接続プールについて心配する必要がありますか?
フィリップケリー

回答:


177

SQL Server Management Studio 2005

データベースを右クリックしてをクリックしTasks、次にをクリックDetach Databaseすると、アクティブな接続のダイアログが表示されます。

画面を切り離す

「メッセージ」の下のハイパーリンクをクリックすると、アクティブな接続を終了できます。

その後、データベースを切断せずにそれらの接続を強制終了できます。

詳細はこちら

SQL Server Management Studio 2008

SQL Server Management Studio 2008のインターフェイスが変更されました。手順は次のとおりです(Tim Leung経由)。

  1. オブジェクトエクスプローラーでサーバーを右クリックし、[アクティビティモニター]を選択します。
  2. これが開いたら、[プロセス]グループを展開します。
  3. 次に、ドロップダウンを使用して、データベース名で結果をフィルタリングします。
  4. 右クリックの「プロセスの強制終了」オプションを選択して、サーバー接続を終了します。

21
@Ryanと同じ問題が発生している場合は、Management Studio 2005ではなくManagement Studio 2008(またはそれ以上)を使用していることが原因と考えられます。ManagementStudio 2008で同じことを行うには、Objectでサーバーを右クリックしますエクスプローラーで「アクティビティモニター」を選択します。これが開いたら、[プロセス]グループを展開します。次に、ドロップダウンを使用して、データベース名で結果をフィルタリングします。これで、右クリックの「プロセスの強制終了」オプションを選択して、接続を強制終了できます。
Tim Leung

195

dbをシングルユーザーモードに設定し、復元を実行してから、マルチユーザーに戻したい場合:

ALTER DATABASE YourDB
SET SINGLE_USER WITH
ROLLBACK AFTER 60 --this will give your current connections 60 seconds to complete

--Do Actual Restore
RESTORE DATABASE YourDB
FROM DISK = 'D:\BackUp\YourBaackUpFile.bak'
WITH MOVE 'YourMDFLogicalName' TO 'D:\Data\YourMDFFile.mdf',
MOVE 'YourLDFLogicalName' TO 'D:\Data\YourLDFFile.ldf'

/*If there is no error in statement before database will be in multiuser
mode.  If error occurs please execute following command it will convert
database in multi user.*/
ALTER DATABASE YourDB SET MULTI_USER
GO

参照:Pinal Dave(http://blog.SQLAuthority.com

公式リファレンス:https : //msdn.microsoft.com/en-us/library/ms345598.aspx


11
IMMEDIATE ROLLBACKを発行するのではなく、特定のDELAYの後でのみROLLBACKに関係する場合があるため、ユーザーはクエリを実行して自然に完了することができます。
ジョン・サンソム

2
良い点、現在のクエリを完了できるようにするAFTER 60コマンドを含むようにロールバックに更新
brendan

こんにちは@brendan、ロールバックに60秒以上かかる場合はどうなりますか?感謝
user3583912 2015

11
データベースを復元する場合は、開いているトランザクションは、あなたかどうか失われますROLLBACK IMMEDIATEROLLBACK AFTER 60。そのデータを保存する唯一の方法は、ロールバック後に別のバックアップを実行することです。ただし、別のバックアップから復元しています。だから、待つ意味は何ですか?何か不足していますか?
Dave Mason

@DMason、私もこの質問に興味があります。single_userをロールバックモードで使用すると、待ち時間中に新しい接続ができなくなりますか?もしそうなら、それは、少なくとも読み取り専用のアクションを突然終了させるのではなく、完了させるためのよりクリーンでナイスな方法なのだろうか?
ジェイソン

43

このコードは私にとってはうまくいきました、それはデータベースのすべての既存の接続を殺します。行@Setname = 'databaseName'を変更して、データベース名を指定するだけです。

Use Master
Go

Declare @dbname sysname

Set @dbname = 'databaseName'

Declare @spid int
Select @spid = min(spid) from master.dbo.sysprocesses
where dbid = db_id(@dbname)
While @spid Is Not Null
Begin
        Execute ('Kill ' + @spid)
        Select @spid = min(spid) from master.dbo.sysprocesses
        where dbid = db_id(@dbname) and spid > @spid
End

この後、私はそれを復元することができました


1
これが最速のアプローチでした(SingleUserMode * 20 = 60秒、Kill * 20 = 5秒)。
Karson、2015年

うまくいきませんでした。データベースはまだ使用中です。私は、SQL Server 2008の使用
マレクバー

そのコードを次々と数回実行すると、やっとうまくいくでしょう。時々、KILLと復元の間に何かが潜入します。そして、時々あなたは次々とキルを実行してから復元を実行しなければなりません。
John Waclawski、2016年

再接続しようとするアプリケーションの積極性に完全に依存します。怠惰なユーザーのカップル?よく働く。1秒未満で再接続する大量のアプリサーバー?それほどではありません。
BradC 2017

5

これを試して:

DECLARE UserCursor CURSOR LOCAL FAST_FORWARD FOR
SELECT
    spid
FROM
    master.dbo.sysprocesses
WHERE DB_NAME(dbid) = 'dbname'--replace the dbname with your database
DECLARE @spid SMALLINT
DECLARE @SQLCommand VARCHAR(300)
OPEN UserCursor
FETCH NEXT FROM UserCursor INTO
    @spid
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @SQLCommand = 'KILL ' + CAST(@spid AS VARCHAR)
    EXECUTE(@SQLCommand)
    FETCH NEXT FROM UserCursor INTO
        @spid
END
CLOSE UserCursor
DEALLOCATE UserCursor
GO

4

SQLサーバーを再起動すると、ユーザーが切断されます。私が見つけた最も簡単な方法-サーバーをオフラインにしたい場合にも適しています。

ただし、非常に奇妙な理由により、「オフラインにする」オプションでは確実にこれが実行されず、管理コンソールがハングまたは混乱する可能性があります。再起動してオフラインで作業する

時々これはオプションです-例えばあなたが接続のソースであるウェブサーバーを止めたなら。


+1。SQL Expressにはアクティビティモニターがないため、受け入れられた回答はSQL Express(たとえば、
開発

1
@MattFrear:これは真実ではありません!少なくとも2008 R2 Expressでは、サーバーノードにツールバーボタンとコンテキストメニューエントリが表示されます。
ステファン

4
SQLサーバー全体を再起動すると、すべてのデータベースへの接続が切断されます。サーバーは多くのデータベースをサポートしている可能性がありますが、現在復元する必要があるのは1つだけです。
ロスプレッサー、2015

3
これは、1つのデータベースへの接続を強制終了するための絶対に最悪の方法です。特に、他の多くのデータベースがまだ他のユーザーによって使用されている場合。この方法を使用することを強くお勧めします。それは100%です、合計過剰です!!
John Waclawski、2016年

@JohnWaclawski私は最悪のことは知りませんが、確かに最も怠惰です-それが私が時々言った理由です。とにかく、他の方法よりも時間を節約するわけではありません
Simon_Weaver

3

SQL Server 2008で復元プロセスを自動化しているときにこの問題に遭遇しました。私の(成功した)アプローチは、提供された2つの回答を組み合わせたものでした。

まず、上記のデータベースのすべての接続を実行し、それらを強制終了します。

DECLARE @SPID int = (SELECT TOP 1 SPID FROM sys.sysprocess WHERE dbid = db_id('dbName'))
While @spid Is Not Null
Begin
        Execute ('Kill ' + @spid)
        Select @spid = top 1 spid from master.dbo.sysprocesses
        where dbid = db_id('dbName')
End

次に、データベースをsingle_userモードに設定します

ALTER DATABASE dbName SET SINGLE_USER

次に、復元を実行します...

RESTORE DATABASE and whatnot

接続を再度強制終了します

(same query as above)

そして、データベースをmulti_userに戻します。

ALTER DATABASE dbName SET MULTI_USER

この方法では、シングルモードに設定する前に、データベースを保持している接続がないことを確認します。


2

これらのどれも私のために働いていなかった、現在のユーザーを削除または切断することができませんでした。また、DBへのアクティブな接続を確認できませんでした。SQL Serverを再起動(右クリックして[再起動]を選択)すると、それを実行できました。


2

すでに与えられたアドバイスを追加するには、DBを使用するIISを介して実行しているWebアプリがある場合、復元中にアプリのアプリプールを停止(リサイクルではなく)してから再起動する必要がある場合があります。アプリプールを停止すると、アクティブなhttp接続が強制終了され、それ以上は許可されなくなります。そうしないと、データベースに接続し、それによってデータベースをロックするプロセスがトリガーされる可能性があります。これは、データベースの復元時のUmbracoコンテンツ管理システムなどの既知の問題です


1

上記のどれも私にとってはうまくいきませんでした。データベースに、Activity Monitorまたはsp_whoを使用したアクティブな接続が表示されませんでした。最終的に私はしなければなりませんでした:

  • データベースノードを右クリック
  • 「デタッチ...」を選択します
  • 「ドロップ接続」ボックスをチェックします
  • 再接続

最もエレガントなソリューションではありませんが、機能し、SQL Serverを再起動する必要はありません(DBサーバーが他の多くのデータベースをホストしていたため、私には選択肢がありません)。


これは完全な過剰です。上記のKILLコードを使用します。何百ものリストアジョブで機能します。
John Waclawski

私が使用していたデータベースはすべてを殺すわけではありませんが、それは彼らの設定に問題があったかもしれません。私はそれが一般的にはるかに簡単であることに同意します。
ブレントワゴナー2016年

0

私はこのようにすることを好む、

データベースセットをオフラインに変更し、すぐにロールバックします

次にデータベースを復元します。その後、

データベースセットをオンラインに変更し、すぐにロールバックします

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.