Когда базы данных SQL Server переходят в состояние "In Recovery" (восстановление), это может вызывать беспокойство, особенно если причина не сразу ясна. Важно понимать, что в большинстве случаев это является нормальным и ожидаемым процессом, который SQL Server запускает для обеспечения согласованности данных после различных событий, таких как запуск экземпляра сервера, восстановление базы данных из резервной копии или неожиданное завершение работы системы. В рамках этого руководства мы подробно разберем, почему возникает этот режим, как его диагностировать и какие шаги предпринять для устранения проблемы.
Режим "In Recovery" означает, что SQL Server активно выполняет внутренние операции для возвращения базы данных в согласованное состояние. Этот процесс имеет решающее значение для целостности данных и гарантирует, что все зафиксированные транзакции применены, а незафиксированные — отменены. Процесс восстановления состоит из трех основных фаз:
Продолжительность этих фаз может варьироваться от нескольких секунд до нескольких часов, в зависимости от размера базы данных, количества активных транзакций и ресурсов сервера.
Мы выясним основные причины, по которым база данных может оказаться в режиме "In Recovery" или "Recovery Pending". Понимание этих причин поможет нам правильно диагностировать и устранить проблему.
.mdf) или файлы журнала транзакций (.ldf) были повреждены, это может помешать успешному завершению процесса восстановления. SQL Server может пытаться восстановиться, но не сможет из-за нечитаемых данных.NORECOVERY (что часто делается при применении нескольких файлов журнала транзакций), она останется в режиме восстановления до тех пор, пока не будет применена команда RESTORE DATABASE ... WITH RECOVERY;.Для эффективного устранения проблем важно уметь отслеживать статус и прогресс восстановления. Рассмотрим основные инструменты и методы:
SELECT
session_id,
command,
status,
start_time,
percent_complete,
estimated_completion_time,
cpu_time,
total_elapsed_time,
reads,
writes,
logical_reads,
wait_type,
wait_time,
wait_resource
FROM
sys.dm_exec_requests
WHERE
command = 'DB STARTUP'
OR command LIKE 'DBCC%';
Обратите внимание, что значения percent_complete и estimated_completion_time не всегда могут быть абсолютно точными, особенно на ранних стадиях восстановления, но они дают общее представление.
sys.dm_tran_persistent_version_store_stats для мониторинга размера Persistent Version Store (PVS). Большой PVS может указывать на проблемы с очисткой версий и влиять на производительность восстановления.Теперь, когда мы понимаем причины и методы мониторинга, рассмотрим конкретные шаги, которые мы можем предпринять для решения проблемы.
Как мы уже упоминали, режим "In Recovery" часто является нормальным процессом. Если SQL Server перешел в этот режим после неожиданной перезагрузки или сбоя, и вы видите, что процесс активно идет (например, в sys.dm_exec_requests), то наилучшей стратегией часто является ожидание. Прерывание процесса восстановления (например, путем принудительной перезагрузки сервера) может привести к тому, что он начнется заново, только увеличивая время простоя. Если мы наблюдаем прогресс и нет явных ошибок в логах, дадим SQL Server завершить свою работу.
Это критически важный первый шаг. Внимательно изучим журнал ошибок SQL Server. Ищем сообщения, которые могут указывать на причину задержки или сбоя восстановления. Это могут быть ошибки ввода-вывода, сообщения о повреждении файлов, нехватке памяти или другие системные ошибки. Например, сообщения типа "I/O error", "corruption", "memory pressure" могут дать нам направление для дальнейшей диагностики.
Параллельно с проверкой логов, мы должны убедиться, что сервер обладает достаточными ресурсами. Используем системные мониторы производительности, чтобы проверить:
Если база данных находится в состоянии "Recovery Pending" (ожидание восстановления) или "In Recovery" без видимого прогресса, мы должны проверить права доступа для учетной записи службы SQL Server к файлам базы данных. Учетная запись должна иметь полные права на чтение и запись к каталогам, где хранятся файлы .mdf и .ldf. Проверим, не менялись ли эти права недавно.
RESTORE DATABASE ... WITH RECOVERY;Если база данных оказалась в режиме "In Recovery" из-за того, что ранее была восстановлена с опцией NORECOVERY (например, при подготовке к применению дополнительных файлов журнала транзакций), нам нужно завершить процесс восстановления. Для этого выполним следующую команду:
ALTER DATABASE [Имя_Базы_Данных] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
RESTORE DATABASE [Имя_Базы_Данных] WITH RECOVERY;
GO
ALTER DATABASE [Имя_Базы_Данных] SET MULTI_USER;
GO
Замените [Имя_Базы_Данных] на фактическое имя вашей базы. Опция SINGLE_USER необходима, чтобы другие пользователи не подключались к базе данных во время завершения восстановления, а ROLLBACK IMMEDIATE принудительно отключает текущие соединения.
В некоторых случаях, особенно когда база данных находится в состоянии "Recovery Pending" из-за проблем с доступностью файлов (например, после временной недоступности сетевого хранилища), отсоединение и повторное присоединение базы данных может помочь. Этот метод работает, если файлы базы данных не повреждены. Мы должны быть крайне осторожны при использовании этого метода, так как некорректное выполнение может привести к потере данных:
.mdf. SQL Server попытается повторно присоединить базу данных и запустит процесс восстановления, если это необходимо.EMERGENCY и DBCC CHECKDB (как крайняя мера)Если все вышеперечисленные методы не помогают и мы подозреваем серьезное повреждение файлов, мы можем попытаться использовать режим EMERGENCY для диагностики и ремонта. Этот метод следует применять с крайней осторожностью, так как опция ремонта может привести к потере данных. Всегда делайте резервную копию файлов базы данных, прежде чем использовать REPAIR_ALLOW_DATA_LOSS!
EMERGENCY:
ALTER DATABASE [Имя_Базы_Данных] SET EMERGENCY;
GO
DBCC CHECKDB ([Имя_Базы_Данных]) WITH NO_INFOMSGS;
GO
DBCC CHECKDB сообщает о серьезных ошибках, попробуем ремонт (только если нет актуальной резервной копии и готовы к потере данных):
ALTER DATABASE [Имя_Базы_Данных] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
DBCC CHECKDB ([Имя_Базы_Данных], REPAIR_ALLOW_DATA_LOSS) WITH ALL_ERRORMSGS;
GO
ALTER DATABASE [Имя_Базы_Данных] SET MULTI_USER;
GO
Если ни один из методов не работает или повреждения слишком серьезны, восстановление из последней известной хорошей резервной копии является самым надежным и рекомендуемым решением. Это гарантирует целостность данных, хотя может привести к потере данных, внесенных после создания последней резервной копии. Всегда поддерживайте актуальные и проверенные резервные копии!
Для предотвращения будущих проблем, связанных с журналом транзакций, мы должны правильно управлять его ростом. Регулярно выполняем резервное копирование журналов транзакций (в моделях полного или массового протоколирования) и следим за размером виртуальных файлов журнала (VLF). Большое количество VLF может значительно увеличить время восстановления.
Важно различать эти два состояния, так как они указывают на разные стадии проблемы и требуют разных подходов к устранению:
Режим "In Recovery" в SQL Server – это, как правило, индикатор того, что система выполняет важную работу по обеспечению целостности данных. В большинстве случаев достаточно просто подождать. Однако, если процесс затягивается или база данных переходит в состояние "Recovery Pending", нам необходимо активно диагностировать проблему, используя журналы ошибок, мониторинг ресурсов и специфические команды SQL Server. Всегда помним о важности регулярного резервного копирования как о последней и самой надежной линии защиты от потери данных.