SQL Server: база данных застряла в состоянии «Восстановление»

564

Я сделал резервную копию базы данных:

BACKUP DATABASE MyDatabase
TO DISK = 'MyDatabase.bak'
WITH INIT --overwrite existing

А потом попытался восстановить его:

RESTORE DATABASE MyDatabase
   FROM DISK = 'MyDatabase.bak'
   WITH REPLACE --force restore over specified database

И теперь база данных застряла в состоянии восстановления.

Некоторые считают, что это потому, что в резервной копии не было файла журнала, и его нужно было перенести, используя:

RESTORE DATABASE MyDatabase
WITH RECOVERY 

Кроме того, конечно, не получается:

Msg 4333, Level 16, State 1, Line 1
The database cannot be recovered because the log was not restored.
Msg 3013, Level 16, State 1, Line 1
RESTORE DATABASE is terminating abnormally.

И именно то, что вы хотите в катастрофической ситуации, это восстановление, которое не будет работать.


Резервная копия содержит данные и файл журнала:

RESTORE FILELISTONLY 
FROM DISK = 'MyDatabase.bak'

Logical Name    PhysicalName
=============   ===============
MyDatabase    C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\MyDatabase.mdf
MyDatabase_log  C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\MyDatabase_log.LDF
Ян Бойд
источник
3
У меня была та же самая проблема, и все решения потерпели неудачу. Интересно, что я подключился к серверу SQL напрямую и ввел DROP DATABASE dbкоманду через SSMS, и она работала (ранее я использовал SSMS с другого компьютера для выдачи команд). Я предполагаю, что другие решения работали бы также.
Салман А

Ответы:

437

Вам необходимо использовать эту WITH RECOVERYопцию с RESTOREкомандой вашей базы данных , чтобы перевести вашу базу данных в оперативный режим как часть процесса восстановления.

Это, конечно, только в том случае, если вы не собираетесь восстанавливать какие-либо резервные копии журнала транзакций, т. Е. Вы хотите только восстановить резервную копию базы данных и затем иметь доступ к базе данных.

Ваша команда должна выглядеть так,

RESTORE DATABASE MyDatabase
   FROM DISK = 'MyDatabase.bak'
   WITH REPLACE,RECOVERY

Вы можете добиться большего успеха при использовании мастера восстановления базы данных в SQL Server Management Studio. Таким образом, вы можете выбрать конкретные местоположения файлов, параметр перезаписи и параметр WITH Recovery.

Джон Сансом
источник
3
Мне никогда не приходилось использовать оператор восстановления при выполнении того, что он делает. С ЗАМЕНЫ должно хватить.
Сэм
8
Да, я использовал NORECOVERY, но процесс восстановления зависает. Используя WITH RECOVERY, ЗАМЕНИТЕ, что процесс больше не зависает
Junior Mayhé
Это решило мою проблему. У нас был сбой SAN во время восстановления, и это было быстрое и чистое решение.
Зарегистрированный пользователь
У меня была похожая проблема сегодня с базой данных SQL Server 2005. В моем случае мне пришлось добавить «RESTART» в предложение WITH, чтобы решить эту проблему. Он выдавал мне сообщение об ошибке, в котором говорилось, что предыдущая операция не удалась.
XpiritO
3
@FistOfFury Если предыдущая операция восстановления в той же базе данных находится в состоянии ожидания / ожидания, тогда да. Простая остановка / отмена процесса восстановления должна иметь тот же эффект.
Джон Сэнсом
692

У меня была такая ситуация при восстановлении базы данных до экземпляра SQL Server 2005 Standard Edition с использованием Symantec Backup Exec 11d. После завершения задания восстановления база данных оставалась в состоянии «Восстановление». У меня не было проблем с дисковым пространством - база данных просто не вышла из состояния «Восстановление».

Я запустил следующий запрос к экземпляру SQL Server и обнаружил, что база данных сразу стала пригодной для использования:

RESTORE DATABASE <database name> WITH RECOVERY
Эван Андерсон
источник
4
У нас была БД, застрявшая в восстановлении на 2 часа. Мы запустили эту команду с другой машины против мастера, и это исправило нас. Спасибо!
Пит
11
+1, с гочей. Когда я запустил это, я получил сообщение об ошибке, в котором говорилось, что база данных уже полностью восстановлена. Но он все еще показывался как находящийся в состоянии «в восстановлении» Поэтому я щелкнул его правой кнопкой мыши в Management Studio, нажал «Обновить», и он вернулся в нормальное состояние.
dario_ramos
2
Я восстановил с помощью мастера Mng Studio, ввел имя новой базы данных, но по ошибке оставил имена файлов такими же, как и у существующей базы данных. Я получил ошибку «восстановление не удалось, но журнал успешно завершен», и база данных, прикрепленная к этим файлам, застряла в состоянии восстановления. Эта команда, кажется, восстановила базу данных до ее предыдущего состояния.
Крис
3
Это сработало. Я пытался восстановить резервную копию в сторонней базе данных, но моя основная база данных почему-то перешла в состояние восстановления. Это фактически восстановило мою БД. Огромное спасибо!
Аравинд
2
По умолчанию некоторые мастера восстановления SSMS оставляют исходную БД в состоянии восстановления, так что вы можете продолжать восстанавливать различные резервные копии или журналы без страха перед пользователями, и эта команда является правильным способом вернуть БД в нормальное состояние, как только вы закончите.
Тим Ленер
102

Вот как вы это делаете:

  1. Остановить службу (MSSQLSERVER);
  2. Переименуйте или удалите файлы базы данных и журнала (C: \ Program Files \ Microsoft SQL Server \ MSSQL.1 \ MSSQL \ Data ...) или там, где у вас есть файлы;
  3. Запустить сервис (MSSQLSERVER);
  4. Удалить базу данных с проблемой;
  5. Восстановите базу данных снова.
Типу Делакаблу
источник
Типу, спасибо за это. У меня была похожая проблема с оригинальным постером, но она была вызвана тем, что серверу не хватило места на диске во время восстановления, и поэтому вызвала постоянное состояние восстановления.
Паук
8
Почему бы просто не удалить базу данных? Таким образом, вам не нужно останавливать службу.
ErikE
8
@ErikE Для меня SQL-сервер сказал, что он не может отбросить базу данных в процессе восстановления, даже если это не было на самом деле восстановление ....
Эрик Филипс
@ErikPhilips В этом случае, я полагаю, кто-то вернулся к остановке службы. Интересно, происходит ли это каждый раз или только в определенных случаях проблемы с зависанием-восстановлением.
ErikE
5
В моем случае достаточно было сбросить базу данных, которая висела в состоянии «Восстановление ...» с помощью команды SQL drop database <dbname>в окне запроса. Затем я щелкнул правой кнопкой мыши на Базы данных и выбрал Обновить, который удалил запись в Management Studio. После этого я сделал новое восстановление, которое работало нормально ( обратите внимание, что его отключение не работало, перезапуск службы SQL не работал, перезагрузка сервера также не работала).
Мэтт
84

У меня был похожий инцидент с остановкой вторичного сервера доставки журналов. После команды удалить сервер из доставки журналов и остановить доставку журналов с основного сервера база данных на дополнительном сервере застряла в состоянии восстановления после команды

RESTORE DATABASE <database name> WITH RECOVERY

База сообщений:

RESTORE DATABASE успешно обработал 0 страниц за 18,530 секунд (0,000 МБ / с).

База данных была пригодна для использования снова после этих 18 секунд.

Hans
источник
6
Особенно полезно, когда вы уже восстановили базу данных, но забыли опцию
RECOVERY
2
Это было все, что мне нужно, чтобы заставить его выйти из состояния «Восстановление» после восстановления резервной копии этой базы данных с другим именем БД. Огромное спасибо.
Шон
81

У меня была похожая проблема с восстановлением с помощью SQL Management Studio. Я попытался восстановить резервную копию базы данных на новую с другим именем. Сначала это не удалось, и после исправления имен файлов новой базы данных оно было успешно выполнено - в любом случае описываемая мной проблема повторялась, даже если я понял это правильно с первого раза. Таким образом, после восстановления исходная база данных осталась с (Восстановление ...) рядом с ее именем. Учитывая ответы на форуме выше (Bhusan's), я попытался запустить в редакторе запросов на стороне следующее:

RESTORE DATABASE "[NAME_OF_DATABASE_STUCK_IN_RESTORING_STATE]"

что решило проблему. Сначала у меня были проблемы из-за имени базы данных, содержащей специальные символы. Я решил эту проблему, добавив двойные кавычки - одинарные кавычки не сработали бы с ошибкой «Неверный синтаксис рядом ...».

Это было минимальное решение, которое я пытался решить (застрявшая база данных в восстановленном состоянии), и я надеюсь, что она может быть применена к другим случаям.

Деметрис Лептос
источник
2
Работал отлично - без необходимости сносить его снова и снова. 3 Dbs 80+ Гб каждый занимает некоторое время! Спасибо!
Кристер
1
Я почти сделал это на производственной среде. Я попробовал это на местном сначала, закончил в той же самой ситуации и нашел Ваш комментарий. Извлеченный урок: используйте сценарии и не доверяйте SSMS в важных ситуациях.
Мариуш
1
Я получил эту проблему при восстановлении резервной копии файла только для копирования базы данных в новую базу данных. Исходная база данных показала ошибку. Это решение сработало, и я получил ответ «RESTORE DATABASE успешно обработал 0 страниц за 0,263 секунды (0,000 МБ / с)». Таким образом, кажется, что SQL Server был просто сбит с толку о состоянии базы данных.
Р.
1
Работал для меня, но только когда я удалил двойные кавычки - у меня просто был [MY_DB_NAME] в качестве параметра.
StackOverflowUser
34

ОК, у меня похожая проблема, и точно так же, как это было в случае с Pauk, она была вызвана тем, что серверу не хватило места на диске при восстановлении, и, таким образом, вызвала постоянное состояние восстановления. Как завершить это состояние без остановки служб SQL Server?

Я нашел решение :)

Drop database *dbname*
ErikE
источник
29

Параметр WITH RECOVERY используется по умолчанию при выполнении команд RESTORE DATABASE / RESTORE LOG. Если вы застряли в процессе «восстановления», вы можете вернуть базу данных в оперативное состояние, выполнив:

RESTORE DATABASE YourDB WITH RECOVERY
GO

Если требуется восстановление нескольких файлов, для команд CLI требуются WITH NORECOVERY и WITH RECOVERY соответственно - только последний файл в команде должен иметь WITH RECOVERY для возврата базы данных в оперативный режим:

RESTORE DATABASE YourDB FROM DISK = 'Z:\YourDB.bak'
WITH NORECOVERY
GO
RESTORE LOG YourDB FROM DISK = 'Z:\YourDB.trn'
WITH RECOVERY
GO

Вы также можете использовать мастер SQL Server Management Studio:

введите описание изображения здесь

Существует также процесс виртуального восстановления, но вам придется использовать сторонние решения. Обычно вы можете использовать резервную копию базы данных в качестве онлайн-базы данных. ApexSQL и Idera имеют свои собственные решения. Обзор SQL Hammer об ApexSQL Restore . Виртуальное восстановление является хорошим решением, если вы имеете дело с большим количеством резервных копий. Процесс восстановления намного быстрее, а также может сэкономить много места на диске. Вы можете посмотреть на инфографику здесь для сравнения.

Марко Крстич
источник
23

Это может быть довольно очевидно, но это сбило меня с толку только сейчас:

Если вы делаете резервную копию хвостового журнала, эта проблема также может быть вызвана проверкой этой опции в мастере восстановления SSMS - «Оставить исходную базу данных в состоянии восстановления (WITH NORECOVERY)»

введите описание изображения здесь

TrailJon
источник
7
Если вы находитесь в этом состоянии, то вам лучше всего: 1. Щелкните правой кнопкой мыши базу данных, перейдите в Задачи-> Восстановить-> Журналы транзакций 2. Найдите файл резервной копии, который использовался для резервного копирования Tail Log 3. Восстановите резервное копирование Восстановление должно завершиться успешно и вернуть базу данных в оперативный режим.
Райан Гросс
16

Я понял, почему.

Если клиент, выдавший RESTORE DATABASE команду, отключится во время восстановления, восстановление застрянет.

Странно, что сервер, когда ему приказывают восстановить базу данных посредством клиентского соединения, не завершит восстановление, пока клиент не будет оставаться на связи все время.

Ян Бойд
источник
10
Все команды SQL требуют, чтобы клиент оставался на связи все время.
Мрденни
2
@mrdenny: я бы предположил, что изменения отменяются, когда клиент отключается.
Ян Бойд
У меня та же проблема при запуске этой команды с драйвером PHP PDO от Microsoft. Однако, при работе с Microsoft SQL Server, студия управления сервером Это работает просто отлично. Интересно, как сделать так, чтобы мое приложение php постоянно подключалось?
Channa Ly
Случилось и здесь, БД зависла в восстановлении / однопользовательском режиме после возможного разрыва соединения. Убил всех остальных SPID из нового сеанса, но все еще застрял. Был в состоянии отбросить базу данных в качестве решения.
Crokusek
10

этот действительно работал:

http://social.msdn.microsoft.com/Forums/en/sqldatabaseengine/thread/8dd1b91d-3e14-4486-abe6-e3a550bfe457

У меня была ситуация, когда моя база данных показала состояние восстановления, и я не мог выполнить какие-либо запросы и не мог соединиться с нашим программным обеспечением.

Что я сделал, чтобы выйти из этой ситуации:

  1. Остановите все службы, связанные с SQL, из служб Windows.

  2. Я открыл папку DATA, в которой файлы Ldf и Mdf находятся в каталоге SQL, обычно это выглядит так: «C: \ Program Files *********** \ MSSQL \ DATA

  3. Затем я скопировал файлы базы данных Ldf и Mdf: [имя базы данных] .mdf и [имя базы данных] _log.ldf

Я скопировал оба этих файла в другую папку.

  1. Затем я снова запустил все службы, связанные с SQL (на шаге 1), из служб Windows.

  2. Запустил мою студию MS SQL Management с обычным логином.

  3. Щелкните правой кнопкой мыши на базе данных виновника и нажмите DELETE (чтобы удалить базу данных вообще).

  4. Все файлы LDF и MDF, относящиеся к этой базе данных, были взяты из папки DATA (упомянутой в шаге 2).

  5. Создана новая база данных с тем же именем (то же имя, которое я удалил на шаге 6 - база данных преступников).

  6. Затем [имя базы данных] -> щелкните правой кнопкой мыши -> задачи -> отключить.

  7. Затем я скопировал оба файла (из шага 3) обратно в папку DATA (шаг 2).

  8. [имя базы данных] -> щелчок правой кнопкой мыши -> задачи -> Подключить к сети.

Амин Абухилал
источник
Это сработало и для меня. На шаге 10 я решил перезаписать существующие файлы.
Divi Perdomo
8

У меня есть . в моем имени базы данных, и запрос не работал из-за этого (говоря неправильный синтаксис рядом с '.') Тогда я понял, что мне нужна скобка для имени:

RESTORE DATABASE [My.DB.Name] WITH RECOVERY
Ашкан Сироус
источник
5

В моем случае было достаточно отбросить базу данных, которая висела в состоянии «Восстановление ...» с помощью команды SQL

 drop database <dbname> 

в окне запроса.

Затем я щелкнул правой кнопкой мыши на Базы данных и выбрал Обновить, который удалил запись в Management Studio. После этого я сделал новое восстановление, которое работало нормально (обратите внимание, что его отключение не работало, перезапуск службы SQL не работал, перезагрузка сервера также не работала).

Matt
источник
3

У меня была эта проблема, когда я также получил ошибку TCP в журнале событий ...

Сбросьте БД с помощью sql или щелкните правой кнопкой мыши на ней в диспетчере «Удалить» и восстановите снова.

Я действительно начал делать это по умолчанию. Сценарий сброса БД, воссоздать и затем восстановить.

ZeusT
источник
3

По умолчанию каждый RESTORE DATABASEпоставляется с RECOVERYнастройкой. Параметры 'NORECOVERY', в основном, говорят SQL Server, что база данных ожидает больше файлов восстановления (это может быть файл DIFF и LOG и, если возможно, файл резервной копии). Опции 'RECOVERY' завершают все транзакции и позволяют базе данных быть готовой к выполнению транзакций.

Так:

  1. если ваша база данных настроена на модель восстановления SIMPLE , вы можете выполнить полное восстановление с NORECOVERYопцией, только если у вас есть резервная копия DIFF . В базе данных модели восстановления SIMPLE не допускается резервное копирование LOG .
  2. В противном случае, если ваша база данных настроена с моделью восстановления FULL или BULK-LOGGED , вы можете выполнить полное восстановление, а затем NORECOVERYпараметр, а затем выполнить DIFF. последующим NORECOVERYи, наконец, выполнить восстановление LOG с RECOVERYпараметром.

Помните, что последний запрос на восстановление должен иметь RECOVERYвариант . Это может быть явный способ или нет. В терминах T-SQL ситуация:

1.

 USE [master]
    GO
    RESTORE DATABASE Database_name 
    FROM DISK = N'\\path_of_backup_file.bak WITH FILE = 1, [REPLACE],NOUNLOAD, 
    RECOVERY -- This option could be omitted.
    GO

Параметр WITH REPLACE следует использовать с осторожностью, так как это может привести к потере данных

Или, если вы выполняете полное и DIFF резервное копирование, вы можете использовать это

   USE [master]
    GO
    RESTORE DATABASE Database_name
      FROM DISK = N'\\path_of_backup_file.bak' WITH FILE = 1, 
       NOUNLOAD,NORECOVERY
    GO
    RESTORE DATABASE Database_name
      FROM DISK =N'\\path_of_**diff**backup_file.bak' WITH FILE = 1, 
     NOUNLOAD, RECOVERY
    GO

 2. USE [master]
    GO
   -- Perform a Tail-Log backup, if possible. 
   BACKUP LOG Database_name
   GO
   -- Restoring a FULL backup
   RESTORE DATABASE Database_name
    FROM DISK = N'\\path_of_backup_file.bak' WITH FILE = 1, 
     NOUNLOAD,NORECOVERY
  GO 
  -- Restore the last DIFF backup
  RESTORE DATABASE Database_name
    FROM DISK = N'\\path_of_DIFF_backup_file.bak' WITH FILE = 1,
     NORECOVERY,NOUNLOAD
  GO
  -- Restore a Log backup
  RESTORE LOG Database_name
    FROM DISK = N'path_of_LOG_backup_file.trn' WITH FILE = 2,
    RECOVERY, NOUNLOAD
  GO

Конечно, вы можете выполнить восстановление с опцией STATS = 10 который указывает SQL Server сообщать о завершении каждых 10%.

Если вы предпочитаете, вы можете наблюдать за процессом или восстановить в режиме реального времени на основе запроса. Следующим образом:

USE[master]
GO
SELECT session_id AS SPID, command, a.text AS Query, start_time, percent_complete, dateadd(second,estimated_completion_time/1000, getdate()) as estimated_completion_time 
    FROM sys.dm_exec_requests r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) a 
        WHERE r.command in ('BACKUP DATABASE','RESTORE DATABASE')
GO

Надеюсь, это поможет.

BMDaemon
источник
2

Также может быть проблема удаления зависшей базы данных, если снимок включен. Для меня это сработало:

  1. Сначала я последовал типу Делакаблу (читай несколько постов)
  2. Запустите команду: drop database [ваша база данных], которая выдаст вам ошибку с сообщением имени базы данных снимков
  3. выполните команду: drop database [база данных моментальных снимков], а затем снова введите команду в шаге 2.
Сообщество
источник
1

У меня есть дело MyDbName (Восстановление ...) из-за лицензионного лимита SQL Express.

В файле журнала я нашел это:

Не удалось создать CREATE DATABASE или ALTER DATABASE, потому что результирующий совокупный размер базы данных превысил бы ваш лицензионный лимит в 10240 МБ на базу данных.

Поэтому, если вы пытаетесь восстановить большую базу данных, вам нужно, например, переключить свой сервер SQL Express на версию для разработчиков .

Дмитрий Павлов
источник
Это была база данных TFS, и клиент TFS уже сказал мне: База данных заполнена.
cskwg
1

Подобная проблема возникла при восстановлении базы данных с помощью студии управления SQL-сервером, и она застряла в режиме восстановления. После нескольких часов отслеживания проблем у меня сработал следующий запрос. Следующий запрос восстанавливает базу данных из существующей резервной копии в предыдущее состояние. Я считаю, подвох заключается в том, что файлы .mdf и .log находятся в одном каталоге.

RESTORE DATABASE aqua_lc_availability
FROM DISK = 'path to .bak file'
WITH RECOVERY
Ujjwal
источник
0
  1. Давайте сначала проверим и запустим службу агента SQL.
  2. Используя следующий T-SQL:

    ВЫБЕРИТЕ имя файла ОТ master.sys.sysaltfiles ГДЕ dbid = DB_ID ('db_name');

  3. Постоянное использование T-SQL:

    RESTORE DATABASE FROM DISK = 'DB_path' С RESTART, ЗАМЕНИТЬ;

Надеюсь, это поможет!

Трунг Нгуен
источник
0

Все варианты с RECOVERY не работали для меня.

Что было сделать, чтобы сделать полное восстановление из Management Studio.

USE [master]
RESTORE DATABASE Sales_SSD
FROM  DISK = N'D:\databaseBackups02\Daily_Sales_20150309_0941.bak' 
WITH  FILE = 1,  
MOVE N'Sales_Data' TO N'C:\Data\SSD\Sales.mdf',  
MOVE N'Sales_Log' TO N'C:\Data\SSD\Sales_1.ldf',  
NOUNLOAD,  REPLACE,  STATS = 5
earthling42
источник
0

У меня была та же проблема ... хотя я не знаю, почему моя база данных столкнулась с этой проблемой, поскольку мой диск не был заполнен ... Это как будто он был поврежден или что-то в этом роде. Я перепробовал все вышеперечисленное, но ни один из них не сработал полностью, особенно мне показалось, что предложение остановить службу и удалить файлы mdf и ldf сработает ... но все равно зависло при восстановлении?

В итоге я решил эту проблему, удалив файлы, как уже упоминалось, но вместо того, чтобы пытаться восстановить БД снова, я скопировал свежие файлы .mdf и .ldf и прикрепил их с помощью мастера подключения переднего плана. Облегчение, это сработало !!

Потребовалось НАВСЕГДА копировать новые файлы, когда я использую виртуальную машину ... поэтому копирование и вставка с использованием буфера обмена заняли примерно час, поэтому я бы рекомендовал это только в качестве последней попытки.

Энтони Григгс
источник
0

Что исправило это для меня

  1. остановка экземпляра
  2. создание резервной копии файлов .mdf и .ldf в папке данных
  3. Перезапустите экземпляр
  4. удалить базу данных застрял восстановление
  5. поместите файлы .mdf и .ldf обратно в папку данных
  6. Присоедините экземпляр к файлам .mdf и .ldf
ChadJPetersen
источник
0
RESTORE DATABASE {DatabaseName}
   FROM DISK = '{databasename}.bak'
   WITH REPLACE, RECOVERY
Рони Баруа
источник
Пожалуйста, укажите на дополнительное понимание, которое дает этот ответ по сравнению со старым, принятым и высоко оцененным ответом. Это помогло бы избежать впечатления о том, что вы просто скопировали его в надежде получить репутацию. Кроме того, ответы только на код (что является основным видимым отличием) здесь не ценятся, потому что они создают неправильное впечатление, что StackOverflow - это бесплатный сервис для написания кода,
Yunnosch
Я исправил форматирование, чтобы сделать сходство со старым ответом более очевидным. Но вы можете научиться делать это здесь stackoverflow.com/editing-help на случай, если вы попытаетесь сделать более легко читаемые ответы в будущем.
Yunnosch
0

Используйте следующую команду, чтобы решить эту проблему

RESTORE DATABASE [DatabaseName] WITH RECOVERY
Сумант Сингх
источник