Як відновити резервну копію, як відключити всі активні з'єднання?


166

Мій SQL Server 2005 не відновлює резервну копію через активні з'єднання. Як я можу це змусити?


Ви завжди хочете знищити всі з'єднання з базою даних, які ви хочете "відновити"? Або будуть випадки, коли ви не хочете вбивати існуючі зв’язки? Крім того, чи потрібно турбуватися про об'єднання з'єднань?
Філіп Келлі

Відповіді:


177

Студія управління SQL Server 2005

Коли ви клацніть правою кнопкою миші на базі даних і натисніть, Tasksа потім натисніть Detach Database, вона відкриє діалогове вікно з активними з'єднаннями.

Зняти екран

Натиснувши на гіперпосилання в розділі "Повідомлення", ви можете перервати активні з'єднання.

Потім ви можете вбити ці з'єднання, не відриваючи базу даних.

Більше інформації тут .

Студія управління SQL Server 2008

Інтерфейс змінився для студії управління SQL Server 2008, ось етапи (через: Тім Леун )

  1. Клацніть правою кнопкою миші сервер у Провіднику об’єктів та виберіть "Монітор активності".
  2. Коли це відкриється, розгорніть групу «Процеси».
  3. Тепер скористайтеся спадним меню, щоб відфільтрувати результати за назвою бази даних.
  4. Відключіть з'єднання з сервером, вибравши правою кнопкою миші опцію "Убити процес".

21
Якщо у вас є та сама проблема, що і в @Ryan, це, мабуть, ви використовуєте Management Studio 2008 (або вище), а не Management Studio 2005. Щоб зробити те ж саме в Management Studio 2008, клацніть правою кнопкою миші ваш сервер в Object Провідник і виберіть "Монітор активності". Коли це відкриється, розгорніть групу «Процеси». Тепер скористайтеся спадним меню, щоб відфільтрувати результати за назвою бази даних. Тепер ви можете перервати свої з'єднання, вибравши правою кнопкою миші опцію "Убити процес".
Тім Леун

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, він може бути доречним лише для ROLLBACK після конкретного затримки, тим самим надаючи запитам користувача можливість завершити природним шляхом.
Джон Сансон

2
Хороший момент, оновлений до відкату, щоб включити команду ПІСЛЯ 60, щоб дозволити завершення поточних запитів
бренда

Привіт @brendan, що робити, якщо відкат займає більше 60 секунд? спасибі
користувач3583912

11
При відновленні бази даних, відкриті транзакції будуть втрачені ви ROLLBACK IMMEDIATEабо ROLLBACK AFTER 60. Єдиний спосіб зберегти ці дані - це зробити ще одну резервну копію після відкату. Але ви відновите з іншого резервного копіювання. Отже, який сенс чекати? Я щось пропускаю?
Дейв Мейсон

@DMason, мені цікаво і це питання. Чи запобігає використання однокористувача з режимом відкату нові з'єднання під час очікування? Якщо так, то мені цікаво, чи це більш чистий / приємний спосіб принаймні завершити дії лише для читання, а не швидко їх закінчити?
Джейсон

43

Цей код працював на мене, він вбиває всі існуючі підключення бази даних. Все, що вам потрібно зробити, це змінити рядок Set @dbname = '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 = 60s, Kill * 20 = 5s).
Карсон

Мені це не вийшло. База даних все ще використовується. Я використовую SQL Server 2008.
Marek Bar

Я знайшов запуск цього коду кілька разів, один за іншим, НАДАЄ ТЕПЛО. Іноді щось пробирається між вашим KILL і відновленням. І іноді вам доводиться запускати функцію вбивства ТА відновлення один за одним.
Джон Вацлавський

Цілком залежить від агресивності програми, яка намагається знову підключитися. Пара ледачих користувачів? Чудово працює. Сервер додатків із великим обсягом, який знову підключається за секунду? Не так багато.
BradC

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 немає монітора активності
Matt Frear

1
@MattFrear: Це неправда! Принаймні, у 2008 році R2 Express я бачу кнопку панелі інструментів та запис контекстного меню на вузлі сервера.
Стефан

4
Перезапуск цілого SQL-сервера призведе до руйнування підключень до всіх баз даних. Сервер може підтримувати безліч баз даних, але зараз його потрібно відновити.
Росс Пресер

3
Це абсолютно найгірший спосіб знищити з'єднання до 1 бази даних. Особливо, якщо у вас є багато інших баз даних, які все ще використовуються іншими користувачами. Я настійно раджу ПРОТИ використовувати цей метод. Це 100%, загальний перевибір !!
Джон Вацлавський

@JohnWaclawski Я не знаю про найгірше, але, безумовно, ледачий - саме тому я говорив іноді. Це дійсно не економить жодного часу над іншими методами
Simon_Weaver

3

Я зіткнувся з цією проблемою, коли автоматизував процес відновлення в SQL Server 2008. Мій (успішний) підхід був поєднанням двох наданих відповідей.

По-перше, я перебігаю всі з'єднання зазначеної бази даних і вбиваю їх.

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

Потім я встановив базу даних в режим однокористувача

ALTER DATABASE dbName SET SINGLE_USER

Потім я запускаю відновлення ...

RESTORE DATABASE and whatnot

Знову вбийте з'єднання

(same query as above)

І поверніть базу даних на багатокористувацьку.

ALTER DATABASE dbName SET MULTI_USER

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


2

Жодне з них не працювало для мене, не могло видалити або відключити поточних користувачів. Також не вдалося побачити жодні активні з'єднання з БД. Перезапуск SQL Server (Клацніть правою кнопкою миші та виберіть Перезапустити) дозволив мені це зробити.


2

Щоб додати до вже наданих порад, якщо у вас є веб-додаток, що працює через IIS, який використовує БД, вам також може знадобитися зупинити (не переробляти) пул додатків під час відновлення, а потім перезапустити. Припинення пулу додатків виключає активні з’єднання http і не дозволяє більше, що в іншому випадку може призвести до запуску процесів, що підключаються до і тим самим блокують базу даних. Це відома проблема, наприклад, із системою управління вмістом Umbraco при відновленні бази даних


1

Ніщо з перерахованого вище не працювало для мене. У моїй базі даних не було показано жодних активних з'єднань за допомогою Monitor Monitor або sp_who. Я в кінцевому рахунку повинен був:

  • Клацніть правою кнопкою миші вузол бази даних
  • Виберіть "Очистити ..."
  • Поставте прапорець "Скасувати з'єднання"
  • Повторне з'єднання

Це не найелегантніше рішення, але воно працює, і воно не вимагає перезавантаження SQL Server (не для мене варіант, оскільки на сервері БД розміщена купа інших баз даних)


Це загальний перевитрата. Використовуйте код KILL вище. Працює над сотнями робіт з відновлення.
Джон Вацлавський

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

0

Я вважаю за краще робити так,

змінити набір баз даних офлайн з негайним відкатом

а потім відновіть вашу базу даних. після того,

змінити базу даних в Інтернеті з негайним відкатом

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