Як вигнати користувачів із бази даних SQL Server 2008?


22

Нам потрібно зробити відновлення, а не може, тому що підключені інші користувачі. Ми думали, що ми відключили кожен процес, але, мабуть, ні.

Як ми можемо зі студії менеджменту запустити всіх інших, щоб ми могли зробити це резервне копіювання?

Відповіді:


25

Є два способи зробити це:

  1. Клацніть правою кнопкою миші на базі даних в Провіднику об’єктів, перейдіть до Завдання> Від'єднати. Установіть прапорець Drop Connections.

  2. Встановіть базу даних на однокористувацький режим, як зазначено тут :

    -- 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

Не зрозумів, що у мене так багато коментарів, хаха. Маріан вірна, не потрібно запускати фактичний загін, просто дістаньте сценарій, щоб вбити користувачів. @NickChammas Так, це робить його читанням лише заважає користувачам знову підключатися. Коли ви встановите його на багатокористувацького, ви можете виконати відновлення. Також імена db є з шаблону, і такі теги, як '<Ім'я бази даних, ім'я системи>>, повинні бути замінені за допомогою Ctrl + Shift + M. У не шаблонованому сценарії dbname не матиме лапок навколо них.
Віль

43

Я завжди використовую таке:

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;

Іноді це може зайняти деякий час, а іноді заблоковано, тому що ви його працюєте, і у вас є активне з'єднання з базою даних . Перевірте інші вікна запитів, які можуть мати той самий контекст бази даних - це може включати відкриті діалоги, Провідник об'єктів, IntelliSense, тривалі завдання тощо.

Коли я закінчую внесення змін у конфігурацію цієї бази даних, я просто:

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

Хоча іноді, що мені потрібно зробити з цією базою даних, вимагає, щоб база даних була в Інтернеті, тому іноді мені доводиться залишати її в режимі однокористувача і робити це:

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

Тепер я можу внести зміни, а тоді, коли я буду готовий до того, щоб інші користувачі підключились, просто:

ALTER DATABASE [dbname] SET MULTI_USER;

2

Я зазвичай встановлюю базу даних в single_user, а потім затримую затримку, а потім повертаю базу даних у багатокористувацьку як нижче:

-- 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'

Насправді, "встановлювати мультикористувач" не потрібно, оскільки у вас є один сценарій (транзакція) з оператором відновлення. Відновлення з відновленням допоможе повернути базу даних у багатокористувацький режим.
Svein Terje Gaup

1

Жоден із варіантів, описаних вище, не працював для мене, оскільки сервер забився декількома спробами віддаленого з'єднання.

Коли я закрив певний порт бази даних на брандмауері Windows, нормальний Alter .. Set Multi_User працював у першій спробі.


-1

Наступне насправді вбиває всі зв’язки. Досить корисно в тих випадках, коли налаштування одного режиму користувача не вдається

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)

1
Це не працює, тому sysprocessesщо не завжди враховуються всі сеанси, які можуть містити блокування в цій базі даних (подумайте про простий сценарій, коли запит виконується в контексті бази даних А, але приєднується до таблиці в А та таблиці в Б) .
Аарон Бертран

-1

Ви можете використовувати скрипт нижче для того, щоб видалити всіх, або змінити для конкретної БД.

Все, що можна вбити, буде! Однак SPID служби 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

-3

Я використовую цей код:

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

Але я можу побачити, що приклад ЄДИННОГО ВИКОРИСТАННЯ набирає менше.


3
Також повернення бази даних в Інтернеті означає, що інші користувачі можуть знову підключитися перед початком відновлення.
Аарон Бертран
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.