Помилка. Не вдалось отримати ексклюзивний доступ, оскільки база даних використовується


119

Насправді я намагаюся зробити сценарій (на Sql Server 2008), щоб відновити одну базу даних з одного резервного файла. Я зробив наступний код, і я отримую помилку -

Msg 3101, Level 16, State 1, Line 3
Exclusive access could not be obtained because 
the database is in use.
Msg 3013, Level 16, State 1, Line 3
RESTORE DATABASE is terminating abnormally.

Як виправити цю проблему?

IF DB_ID('AdventureWorksDW') IS NOT NULL 
BEGIN 
RESTORE DATABASE [AdventureWorksDW] 
FILE = N'AdventureWorksDW_Data' 
FROM  
DISK = N'C:\Program Files\Microsoft SQL Server\
MSSQL10_50.SS2008\MSSQL\Backup\AdventureWorksDW.bak' 
WITH  FILE = 1, 
MOVE N'AdventureWorksDW_Data' 
TO N'C:\Program Files\Microsoft SQL Server\
MSSQL10_50.SS2008\MSSQL\DATA\AdventureWorksDW.mdf', 
MOVE N'AdventureWorksDW_Log'  
TO N'C:\Program Files\Microsoft SQL Server\
MSSQL10_50.SS2008\MSSQL\DATA\AdventureWorksDW_0.LDF', 
NOUNLOAD,  STATS = 10 
END

Якщо я можу змусити це працювати, можливо, я можу зробити надійний сценарій для відновлення декількох баз даних з однієї папки. Я не зміг знайти жодного надійного коду в мережі. Мій код може бути надійним, оскільки його генерує сам SS.
Steam

Відповіді:


106

Я припускаю, що якщо ви відновлюєте db, то вам не буде важливо жодних існуючих транзакцій на цьому db. Правильно? Якщо так, то це повинно працювати для вас:

USE master
GO

ALTER DATABASE AdventureWorksDW
SET SINGLE_USER
--This rolls back all uncommitted transactions in the db.
WITH ROLLBACK IMMEDIATE
GO

RESTORE DATABASE AdventureWorksDW
FROM ...
...
GO

Тепер ще один додатковий предмет, про який слід знати. Після встановлення db в єдиний користувацький режим, хтось інший може спробувати підключитися до db. Якщо вони досягнуть успіху, ви не зможете продовжити відновлення. Це гонка! Моя пропозиція - запустити всі три заяви одночасно.


всі три виписки в транзакції.
Steam

1
Мій SSMS переходить у режим не реагування, коли я намагаюся отримати доступ до цієї бази даних пригод.
Steam

2
Він насправді означає USE master, ні USER master.
асинхрон

7
Просто додайте ALTER DATABASE [AdventureWorksDW] SET MULTI_USERв кінці, щоб переконатися, що база даних повернулася в звичайний режим для декількох користувачів.
gnaanaa

1
@gnaanaa: Якщо резервна копія БД була в SINGLE_USERрежимі резервного копіювання, вона буде в SINGLE_USERрежимі відновлення резервної копії. Якщо він був у MULTI_USERрежимі резервного копіювання, він буде в MULTI_USERрежимі його відновлення. Ви чудово зазначаєте: це, безумовно, варто перевірити після завершення відновлення. Ви також можете запустити RESTORE HEADERONLY на носії для резервного копіювання та перевірити IsSingleUserабо зробити біт- розумну математику на Flagsстовпці.
Дейв Мейсон

236
  1. Встановіть шлях відновлення файлу.
  2. Натисніть "Параметри" зліва.
  3. Зніміть прапорець "Візьміть резервну копію хвостового журналу перед відновленням"
  4. Поставте прапорець "Закрити існуючі з'єднання з базою даних". введіть тут опис зображення
  5. Натисніть кнопку ОК.

16
У моєму випадку цей прапорець був зацьованим. Однак я почав заново і зміг встановити прапорець перед тим, як вибрати джерело для відновлення. Вибравши файл резервного копіювання, параметр знову був затьмарений сірим, але поле все ще було встановлено, і відновлення працювало.
phansen

3
Кудо, що врятувало мене від введення SQL. Єдиний метод GUI серед усіх відповідей.
Ліонет Чен

Я сподіваюся, що це спрацювало б для мене, як і інші. Але для мене прапорець завжди залишався затьмареним. Андрій Karchueuski в відповідь нижче нижче, працював для мене.
Devraj Gadhavi

11
Також мені довелося зняти прапорець "Зробити резервну копію хвоста перед тим, як відновити", перш ніж я зміг відновити.
Хілл

3
"Зробіть резервну копію хвостового журналу перед відновленням", це також потрібно зняти з поля. Спасибі
jedu

50

виконати цей запит перед відновленням бази даних:

alter database [YourDBName] 
set offline with rollback immediate

і цей після відновлення:

  alter database [YourDBName] 
  set online

Я перейшов на цей метод через SINGLE_USER після того, як підключення експериментальної програми перемогло відновлення мого запиту та наступний виклик MULTI_USER. Не вдалося отримати ексклюзивний доступ і старий db залишився в режимі SINGLE_USER.
Smörgåsbord

3
це працювало для мене. і він автоматично з’являється в Інтернеті після відновлення.
Dileep

3
Це працює, і це дозволяє уникнути перегонів у прийнятій відповіді.
Скотт Вітлок

1
Дякую, Андрію.
Ердоган

11

Для мене рішення таке:

  1. Поставте прапорець Перезаписати існуючу базу даних (З ЗАМОВЛЕННЯМ) на вкладці "Опції" зліва.

  2. Зніміть прапорець біля всіх інших параметрів.

  3. Виберіть джерело та цільову базу даних.

  4. Натисніть ОК.

Це воно.


1
Працював і для мене. Я також повинен був зняти прапорець "Зробити резервну копію хвостового журналу перед відновленням".
юва

7

Використовуйте наступний скрипт, щоб знайти та знищити всі відкриті підключення до бази даних перед відновленням бази даних.

declare @sql as varchar(20), @spid as int

select @spid = min(spid)  from master..sysprocesses  where dbid = db_id('<database_name>') 
and spid != @@spid    

while (@spid is not null)
begin
    print 'Killing process ' + cast(@spid as varchar) + ' ...'
    set @sql = 'kill ' + cast(@spid as varchar)
    exec (@sql)

    select 
        @spid = min(spid)  
    from 
        master..sysprocesses  
    where 
        dbid = db_id('<database_name>') 
        and spid != @@spid
end 

print 'Process completed...'

Сподіваюсь, це допоможе ...


3

Я думаю, вам просто потрібно встановити db в режимі одного користувача, перш ніж намагатися відновити, як нижче, просто переконайтеся, що ви використовуєте master

USE master
GO
ALTER DATABASE AdventureWorksDW
SET SINGLE_USER

2

Я щойно перезапустив послугу sqlexpress, а потім відновлення завершено штрафом


що я можу сказати про downvote ... для мене це спрацювало!
BabaNew

1
У OP виникли проблеми зі сценарієм відновлення, оскільки він не врахував факту, що його БД, можливо, вже використовується. Рішення полягало в тому, щоб оновити його сценарій відповідними командами, що дозволило йому ексклюзивно отримати доступ до БД. Хоча перезапуск послуги, можливо, працював для вас, це не було відповідним рішенням його проблеми.
PL

1
Use Master
alter database databasename set offline with rollback immediate;

--Do Actual Restore
RESTORE DATABASE databasename
FROM DISK = 'path of bak file'
WITH MOVE 'datafile_data' TO 'D:\newDATA\data.mdf',
MOVE 'logfile_Log' TO 'D:\newDATA\DATA_log.ldf',replace

alter database databasename set online with rollback immediate;
GO

1

Рішення 1: Перезапустіть служби SQL та спробуйте відновити БД Рішення 2: Перезапустіть систему / сервер та спробуйте відновити БД Рішення 3: Відновіть поточну БД, Видаліть поточну / цільову БД та спробуйте відновити БД.


1

Налаштування БД в режимі однокористування для мене не працювало, але переведення його в офлайн-режим та повернення його назад в Інтернеті спрацювало. Він знаходиться в меню правої кнопки миші в БД, під завданням.

Обов’язково поставте в діалоговому вікні опцію "Скасувати всі активні з'єднання".


0

Ось як я роблю відновлення бази даних від виробництва до розробки:

ПРИМІТКА: Я роблю це через роботу SSAS, щоб щодня підштовхувати виробничу базу даних до розробки:

Крок 1. Видаліть резервну копію попереднього дня в розробці:

declare @sql varchar(1024);

set @sql = 'DEL C:\ProdAEandAEXdataBACKUP\AE11.bak'
exec master..xp_cmdshell @sql

Крок 2. Копіювання виробничої бази даних:

declare @cmdstring varchar(1000)
set @cmdstring = 'copy \\Share\SQLDBBackup\AE11.bak C:\ProdAEandAEXdataBACKUP'
exec master..xp_cmdshell @cmdstring 

Крок 3: Відновлення за допомогою запуску сценарію .sql

SQLCMD -E -S dev-erpdata1 -b -i "C:\ProdAEandAEXdataBACKUP\AE11_Restore.sql"

Код, що знаходиться у файлі AE11_Restore.sql:

RESTORE DATABASE AE11
FROM DISK = N'C:\ProdAEandAEXdataBACKUP\AE11.bak'
WITH MOVE 'AE11' TO 'E:\SQL_DATA\AE11.mdf',
MOVE 'AE11_log' TO 'D:\SQL_LOGS\AE11.ldf',
RECOVERY;

0

Я отримав цю помилку, коли не було достатньо місця на диску для відновлення Db. Прибирання деякого простору вирішило це.


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