Jak wykopać użytkowników z bazy danych SQL Server 2008?

22

Musimy wykonać przywracanie i nie możemy, ponieważ inni użytkownicy są połączeni. Myśleliśmy, że odłączyliśmy każdy proces, ale najwyraźniej nie.

Jak możemy, z Management Studio, wykopać wszystkich innych, abyśmy mogli wykonać tę kopię zapasową?

Daniel Williams
źródło

Odpowiedzi:

25

Można to zrobić na dwa sposoby:

  1. Kliknij bazę danych prawym przyciskiem myszy w Eksploratorze obiektów i wybierz Zadania> Odłącz. Zaznacz pole wyboru Drop Connections.

  2. Ustaw bazę danych w tryb pojedynczego użytkownika, jak opisano tutaj :

    -- hit Ctrl+Shift+M in SSMS to fill in the template parameter
    USE master;
    GO
    
    ALTER DATABASE N'<Database Name, sysname,>'
    SET SINGLE_USER
    WITH ROLLBACK IMMEDIATE;
    GO
    
    ALTER DATABASE N'<Database Name, sysname,>'
    SET READ_ONLY;
    GO
    
    ALTER DATABASE N'<Database Name, sysname,>'
    SET MULTI_USER;
    GO
Wil
źródło
Nie zdawałem sobie sprawy, że mam tak wiele komentarzy lol. Marian ma rację, nie trzeba uruchamiać rzeczywistego odłączania, wystarczy, że skrypt zabije użytkowników. @NickChammas Tak, ustawienie tylko do odczytu uniemożliwia użytkownikom ponowne połączenie. Po ustawieniu wielu użytkowników możesz przywrócić. Również nazwy db pochodzą z szablonu i jako takie znaczniki, takie jak „<Nazwa bazy danych, nazwa systemowa>”, mają być zastąpione przez użycie Ctrl + Shift + M. W skrypcie bez szablonów nazwy dbnames nie miałyby wokół nich cudzysłowów.
Wil
43

Zawsze używam następujących:

USE master; -- get out of dbname myself
GO
-- kick all other users out:
ALTER DATABASE [dbname] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
-- prevent sessions from re-establishing connection:
ALTER DATABASE [dbname] SET OFFLINE;

Czasami może to chwilę potrwać, a czasem jest blokowane, ponieważ to Ty go uruchamiasz i masz aktywne połączenie z bazą danych . Sprawdź inne okna zapytań, które mogą mieć ten sam kontekst bazy danych - może to obejmować otwarte okna dialogowe, Eksplorator obiektów, IntelliSense, długotrwałe zadania itp.

Kiedy skończę wprowadzać zmiany w konfiguracji tej bazy danych, po prostu:

ALTER DATABASE [dbname] SET ONLINE;
ALTER DATABASE [dbname] SET MULTI_USER;

Chociaż czasami rzeczą, którą muszę zrobić z tą bazą danych, jest jej potrzeba, aby baza była w trybie online, więc czasami muszę pozostawić ją w trybie pojedynczego użytkownika i zrobić to:

ALTER DATABASE [dbname] SET ONLINE;
GO
USE [dbname];

Teraz mogę wprowadzić zmiany, a kiedy będę gotowy na połączenie z innymi użytkownikami, po prostu:

ALTER DATABASE [dbname] SET MULTI_USER;
Aaron Bertrand
źródło
2

Zwykle ustawiam bazę danych w trybie single_user, a następnie czekam na opóźnienie, a następnie ustawiam bazę danych z powrotem dla wielu użytkowników, jak poniżej:

-- to kill all connections for particular db ... otherwise the restore will fail as exclusive lock cannot be obtained for the db being restored.

    alter database db_name
    set single_user with rollback immediate
    waitfor delay '00:00:05'  -- wait for 5 secs
    alter database db_name
    set multi_user
    restore database db_name from disk = 'D:\restore\db_name.bak'
    with replace, stats = 10, recovery -- if you want to recover your database online
    -- optional if you dont have the same directory/file structure
    move 'datafile logical name' to 'E:\data\physical_name.mdf',
    move 'logfile logical name' to 'F:\log\physical_name_log.ldf'
Kin Shah
źródło
W rzeczywistości nie trzeba „ustawiać wielu użytkowników”, ponieważ uruchamiany jest pojedynczy skrypt (transakcja) z instrukcją przywracania. Przywracanie z odzyskiwaniem zajmie się przywróceniem bazy danych do trybu wielu użytkowników.
Svein Terje Gaup,
1

Żadna z powyższych opcji nie działała dla mnie, ponieważ serwer został utrudniony przez wiele prób zdalnego połączenia.

Kiedy zamknąłem konkretny port bazy danych w zaporze systemu Windows, normalny Alter .. Zestaw Multi_User działał w ramach pierwszej próby.

olafk
źródło
-1

Poniższe faktycznie zabija wszystkie połączenia. Całkiem przydatne w przypadkach, w których nie działa ustawienie trybu pojedynczego użytkownika

declare @execSql varchar(1000), @databaseName varchar(100)
-- Set the database name for which to kill the connections
set @databaseName = 'databasename'
set @execSql = '' 
select  @execSql = @execSql + 'kill ' + convert(char(10), spid) + ' '
from    master.dbo.sysprocesses
where   db_name(dbid) = @databaseName
     and
     DBID <> 0
     and
     spid <> @@spid
exec(@execSql)
Betty
źródło
1
To nie działa, ponieważ sysprocessesnie zawsze uwzględnia wszystkie sesje, które mogą zawierać blokady w tej bazie danych (pomyśl o prostym scenariuszu, w którym zapytanie jest uruchamiane w kontekście bazy danych A, ale dołącza do tabeli w A i tabeli w B) .
Aaron Bertrand
-1

Możesz użyć poniższego skryptu, aby nuke wszystkich lub zmodyfikować dla konkretnej bazy danych.

Wszystko, co można zabić, będzie! Nie będzie to miało wpływu na identyfikatory SPID usługi SQL.

Drop table #who

go 

Create table #who(  [spid] int,
                    [ECID] int,
                    [Status] varchar(100),
                    [Loginname] varchar(200),
                    [Hostname] varchar(200),
                    [blk] bit,
                    dbname varchar(200),
                    cmd varchar(1000),
                    requestID int
                  )

go

Insert into #who (Spid, ECID, Status, Loginname, hostname,blk, dbname, cmd, requestid)
exec sp_who

Declare cursKillUsers Cursor for Select 'Kill ' + cast(spid as varchar(100)) + ';' [SQL] from #who where dbname like '%'
Declare @sql varchar(200)
Open cursKillUsers
Fetch next from cursKillUsers into @sql
While @@fetch_status = 0 
begin

    print @sql
    Exec (@sql)
    Fetch next from cursKillUsers into @sql

end

close cursKillUsers
deallocate cursKillUsers
BITSYSUK
źródło
-3

Używam tego kodu:

ALTER DATABASE [Dbname] set offline with rollback immediate
GO
ALTER DATABASE [Dbname] set online
GO

Ale widzę, że przykład POJEDYNCZY UŻYTKOWNIK jest mniej do pisania.

Paul Els
źródło
3
Również przywrócenie bazy danych do trybu online oznacza, że ​​inni użytkownicy mogą połączyć się ponownie przed rozpoczęciem przywracania.
Aaron Bertrand