Quando si ripristina un backup, come posso disconnettere tutte le connessioni attive?


166

Il mio SQL Server 2005 non ripristina un backup a causa delle connessioni attive. Come posso forzarlo?


Vuoi sempre uccidere tutte le connessioni al database che vuoi "ripristinare"? O ci saranno momenti in cui non si desidera interrompere le connessioni esistenti? Inoltre, devi preoccuparti del pool di connessioni?
Philip Kelley,

Risposte:


177

SQL Server Management Studio 2005

Quando si fa clic con il tasto destro su un database e si fa clic Taskse quindi Detach Databasesi fa clic , si apre una finestra di dialogo con le connessioni attive.

Stacca schermo

Facendo clic sul collegamento ipertestuale in "Messaggi" è possibile interrompere le connessioni attive.

È quindi possibile interrompere tali connessioni senza scollegare il database.

Maggiori informazioni qui .

SQL Server Management Studio 2008

L'interfaccia è cambiata per SQL Server Management Studio 2008, ecco i passaggi (tramite: Tim Leung )

  1. Fare clic con il tasto destro del mouse su Esplora oggetti e selezionare "Activity Monitor".
  2. Quando si apre, espandi il gruppo Processi.
  3. Ora usa il menu a discesa per filtrare i risultati in base al nome del database.
  4. Interrompere le connessioni al server selezionando l'opzione "Termina processo" con il pulsante destro del mouse.

21
Se hai lo stesso problema di @Ryan, è probabilmente perché stai usando Management Studio 2008 (o versioni successive), anziché Management Studio 2005. Per fare la stessa cosa in Management Studio 2008, fai clic con il pulsante destro del mouse sul server in Object Esplora risorse e seleziona "Monitoraggio attività". Quando si apre, espandi il gruppo Processi. Ora usa il menu a discesa per filtrare i risultati in base al nome del database. Ora puoi eliminare le tue connessioni selezionando l'opzione "Termina processo" del tasto destro.
Tim Leung,

195

Vuoi impostare il tuo db in modalità utente singolo, eseguire il ripristino, quindi ripristinarlo su multiutente:

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

Riferimento: Pinal Dave ( http://blog.SQLAuthority.com )

Riferimento ufficiale: https://msdn.microsoft.com/en-us/library/ms345598.aspx


11
Invece di emettere un ROLLBACK IMMEDIATO, può essere pertinente al ROLLBACK solo dopo un RITARDO specifico, dando così alle domande degli utenti l'opportunita 'di completarsi naturalmente.
John Sansom,

2
Buon punto, aggiornato al rollback per includere il comando AFTER 60 per consentire il completamento delle query correnti
brendan,

Ciao @brendan, cosa succede se il rollback impiega più di 60 secondi? grazie
user3583912

11
Se si ripristina un database, le transazioni aperte saranno persi se si ROLLBACK IMMEDIATEo ROLLBACK AFTER 60. L'unico modo per salvare tali dati è eseguire un altro backup dopo il rollback. Ma stai ripristinando da un backup diverso. Allora, qual è il punto di attesa? Mi sto perdendo qualcosa?
Dave Mason,

@Dason, sono curioso anche di questa domanda. L'uso di single_user con modalità rollback impedisce nuove connessioni durante il tempo di attesa? In tal caso, mi chiedo se sia un modo più pulito / bello per consentire almeno di completare le azioni di sola lettura piuttosto che terminarle bruscamente?
Jason

43

Questo codice ha funzionato per me, uccide tutte le connessioni esistenti di un database. Tutto quello che devi fare è cambiare la riga Set @dbname = 'databaseName' in modo che abbia il nome del tuo database.

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

dopo questo sono stato in grado di ripristinarlo


1
Questo è stato l'approccio più veloce (SingleUserMode * 20 = 60s, Kill * 20 = 5s).
Karson,

Non ha funzionato per me. Il database è ancora in uso. Uso SQL Server 2008.
Marek Bar,

Ho scoperto che eseguire quel codice più volte, una dopo l'altra, EVENTUALMENTE farà il trucco. A volte qualcosa si intrufola tra KILL e il ripristino. E a volte devi eseguire l'uccisione POI il ripristino uno dopo l'altro.
John Waclawski,

Dipende interamente dall'aggressività dell'applicazione che prova a riconnettersi. Coppia di utenti pigri? Funziona alla grande. App server ad alto volume che si riconnette in meno di un secondo? Non così tanto.
BradC,

5

Prova questo:

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

Il riavvio del server SQL disconnetterà gli utenti. Il modo più semplice che ho trovato - buono anche se vuoi portare il server offline.

Ma per qualche ragione molto strana l'opzione 'Take Offline' non lo fa in modo affidabile e può bloccare o confondere la console di gestione. Riavvio quindi esecuzione offline

A volte questa è un'opzione - se per esempio hai fermato un server web che è la fonte delle connessioni.


+1. La risposta accettata non funzionerà per SQL Express (ad esempio in un ambiente di sviluppo) perché SQL Express non ha Activity Monitor
Matt Frear,

1
@MattFrear: questo non è vero! Almeno nel 2008 R2 Express vedo un pulsante della barra degli strumenti e una voce del menu contestuale sul nodo del server.
Stephan,

4
Il riavvio di un intero server SQL interromperà le connessioni a tutti i database. Un server potrebbe supportare molti database, ma ora è necessario ripristinarne solo uno.
Ross Presser,

3
Questo è assolutamente il modo peggiore per interrompere le connessioni a 1 database. Soprattutto se hai molti altri database ancora utilizzati da altri utenti. Consiglio vivamente CONTRO di usare questo metodo. È al 100%, overkill totale !!
John Waclawski,

@JohnWaclawski Non conosco il peggio, ma sicuramente il più pigro - è per questo che ho detto a volte. In ogni caso, non risparmia davvero tempo rispetto ad altri metodi
Simon_Weaver,

3

Ho riscontrato questo problema durante l'automazione di un processo di ripristino in SQL Server 2008. Il mio approccio (riuscito) era una combinazione di due delle risposte fornite.

Innanzitutto, corro attraverso tutte le connessioni di detto database e li uccido.

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

Quindi, ho impostato il database in modalità single_user

ALTER DATABASE dbName SET SINGLE_USER

Quindi, eseguo il ripristino ...

RESTORE DATABASE and whatnot

Uccidi di nuovo le connessioni

(same query as above)

E reimpostare il database su multi_user.

ALTER DATABASE dbName SET MULTI_USER

In questo modo, mi assicuro che non ci siano connessioni che trattengono il database prima di impostare la modalità singola, poiché la prima si bloccherà se ci sono.


2

Nessuno di questi funzionava per me, non è stato possibile eliminare o disconnettere gli utenti attuali. Inoltre, non è stato possibile visualizzare alcuna connessione attiva al DB. Il riavvio di SQL Server (tasto destro e selezionare Riavvia) mi ha permesso di farlo.


2

Per aggiungere consigli già forniti, se si dispone di un'app Web in esecuzione su IIS che utilizza il DB, potrebbe essere necessario arrestare (non riciclare) il pool di app per l'app durante il ripristino, quindi riavviare. L'arresto del pool di app interrompe le connessioni http attive e non consente più, il che potrebbe altrimenti consentire l'attivazione di processi che si collegano e quindi bloccare il database. Questo è un problema noto, ad esempio con Umbraco Content Management System durante il ripristino del suo database


1

Nessuna delle precedenti ha funzionato per me. Il mio database non ha mostrato alcuna connessione attiva utilizzando Activity Monitor o sp_who. Alla fine ho dovuto:

  • Fare clic con il tasto destro del mouse sul nodo del database
  • Seleziona "Stacca ..."
  • Seleziona la casella "Rilascia connessioni"
  • Ricollegare

Non è la soluzione più elegante ma funziona e non richiede il riavvio di SQL Server (non è un'opzione per me, poiché il server DB ha ospitato un sacco di altri database)


Questo è eccessivo. Usa il codice KILL sopra. Funziona su centinaia di lavori di ripristino per me.
John Waclawski,

Il database con cui stavo lavorando non ucciderebbe tutto, tuttavia, potrebbe essere stato un problema con la loro configurazione. Sono d'accordo che è molto più semplice in generale.
Brent Wagoner,

0

Preferisco fare così

modifica database impostato offline con rollback immediato

e quindi ripristinare il database. dopo di che,

modifica database impostato online con rollback immediato

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.