Что делать, если базы данных SQL Server находятся в режиме 'In Recovery'?

Системный администратор IT и автоматизация бизнеса
← На главную

Когда базы данных SQL Server переходят в состояние "In Recovery" (восстановление), это может вызывать беспокойство, особенно если причина не сразу ясна. Важно понимать, что в большинстве случаев это является нормальным и ожидаемым процессом, который SQL Server запускает для обеспечения согласованности данных после различных событий, таких как запуск экземпляра сервера, восстановление базы данных из резервной копии или неожиданное завершение работы системы. В рамках этого руководства мы подробно разберем, почему возникает этот режим, как его диагностировать и какие шаги предпринять для устранения проблемы.

Введение: Что такое режим "In Recovery"?

Режим "In Recovery" означает, что SQL Server активно выполняет внутренние операции для возвращения базы данных в согласованное состояние. Этот процесс имеет решающее значение для целостности данных и гарантирует, что все зафиксированные транзакции применены, а незафиксированные — отменены. Процесс восстановления состоит из трех основных фаз:

  1. Фаза анализа: На этом этапе SQL Server сканирует журнал транзакций, чтобы определить точку сбоя и выяснить, какие транзакции нужно повторить (redo) и какие откатить (undo).
  2. Фаза повтора (Redo): SQL Server повторно применяет все зафиксированные транзакции из журнала, которые были выполнены, но еще не были записаны в файлы данных. Это доводит базу данных до состояния на момент сбоя.
  3. Фаза отката (Undo): Затем SQL Server откатывает все незавершенные транзакции, которые были активны во время сбоя. Это гарантирует, что база данных находится в согласованном состоянии, как если бы эти транзакции никогда не начинались.

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

Когда база данных SQL Server переходит в режим "In Recovery"? Распространенные причины

Мы выясним основные причины, по которым база данных может оказаться в режиме "In Recovery" или "Recovery Pending". Понимание этих причин поможет нам правильно диагностировать и устранить проблему.

  1. Внезапное завершение работы или сбой: Это одна из наиболее частых причин. Если SQL Server или операционная система неожиданно выключаются (например, из-за сбоя питания, принудительной перезагрузки), SQL Server запускает процесс восстановления при следующем старте, чтобы восстановить целостность данных. Если это произошло во время интенсивной рабочей нагрузки или больших транзакций, процесс может занять значительное время.
  2. Большие незавершенные транзакции: Базы данных, которые обрабатывали очень большие транзакции или длительные запросы в момент сбоя, будут требовать больше времени для фаз отката и повтора, поскольку им предстоит обработать большой объем изменений.
  3. Повреждение файлов базы данных: Если основные файлы данных (.mdf) или файлы журнала транзакций (.ldf) были повреждены, это может помешать успешному завершению процесса восстановления. SQL Server может пытаться восстановиться, но не сможет из-за нечитаемых данных.
  4. Незавершенные операции восстановления: Если база данных была восстановлена из резервной копии с опцией NORECOVERY (что часто делается при применении нескольких файлов журнала транзакций), она останется в режиме восстановления до тех пор, пока не будет применена команда RESTORE DATABASE ... WITH RECOVERY;.
  5. Проблемы с журналом транзакций:
    • Переполненные журналы транзакций: Если журнал транзакций переполняется из-за неправильного управления (например, отсутствие регулярного резервного копирования журнала в модели полного восстановления), SQL Server не может записывать новые транзакции, что может остановить или замедлить процесс восстановления.
    • Большое количество виртуальных файлов журнала (VLF): Чрезмерное количество VLF в журнале транзакций может значительно замедлить фазу анализа и весь процесс восстановления. Это часто является следствием неконтролируемого роста журнала.
  6. Ограничения ресурсов: Недостаток системных ресурсов, таких как процессор, оперативная память или пропускная способность дискового ввода-вывода (I/O), может замедлить или даже остановить процесс восстановления. Мы должны убедиться, что сервер обладает достаточными ресурсами.
  7. Отсутствие или недоступность файла журнала транзакций: База данных может перейти в состояние "Recovery Pending" (ожидание восстановления), если SQL Server не может найти или получить доступ к файлу журнала транзакций или если у учетной записи службы SQL Server недостаточно прав доступа к файлам базы данных. Это также может произойти, если диск, на котором расположены файлы базы данных (например, сетевое хранилище), становится недоступным при запуске SQL Server.

Как мы можем контролировать процесс восстановления?

Для эффективного устранения проблем важно уметь отслеживать статус и прогресс восстановления. Рассмотрим основные инструменты и методы:

  1. Журналы ошибок SQL Server: Это наш первый и главный источник информации. Мы должны тщательно проверять журналы ошибок SQL Server на наличие любых сообщений, связанных с восстановлением, ожиданием, откатом или повреждением. Они часто содержат ценные подсказки о причинах и ходе процесса.
  2. SQL Server Management Studio (SSMS): В SSMS мы можем увидеть текущий статус базы данных в обозревателе объектов. Хотя SSMS не всегда показывает детальный прогресс восстановления в реальном времени, он быстро сообщит нам, если база данных находится в состоянии "In Recovery".
  3. Динамические административные представления (DMV): Эти представления предоставляют наиболее подробную информацию о внутренних процессах SQL Server. Мы можем выполнить следующий запрос, чтобы увидеть активные команды, включая 'DB STARTUP', а также процент выполнения и предполагаемое время завершения:
    
    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 не всегда могут быть абсолютно точными, особенно на ранних стадиях восстановления, но они дают общее представление.

  4. Расширенные события (Extended Events) или флаги трассировки (Trace Flags): Для получения более детальной информации о процессе восстановления мы можем использовать расширенные события или включить определенные флаги трассировки (например, 3605 и 3608), которые могут записывать информацию о шагах восстановления в журнал ошибок SQL Server или в лог расширенных событий. Это обычно используется в случаях, когда требуется глубокий анализ.
  5. Мониторинг PVS при ускоренном восстановлении баз данных (ADR): Если в наших базах данных используется ускоренное восстановление баз данных (Accelerated Database Recovery - ADR), мы можем использовать sys.dm_tran_persistent_version_store_stats для мониторинга размера Persistent Version Store (PVS). Большой PVS может указывать на проблемы с очисткой версий и влиять на производительность восстановления.

Что предпринять, если базы данных оказались в режиме "In Recovery"? Пошаговое руководство

Теперь, когда мы понимаем причины и методы мониторинга, рассмотрим конкретные шаги, которые мы можем предпринять для решения проблемы.

1. Не паникуем и наблюдаем (ожидаем)

Как мы уже упоминали, режим "In Recovery" часто является нормальным процессом. Если SQL Server перешел в этот режим после неожиданной перезагрузки или сбоя, и вы видите, что процесс активно идет (например, в sys.dm_exec_requests), то наилучшей стратегией часто является ожидание. Прерывание процесса восстановления (например, путем принудительной перезагрузки сервера) может привести к тому, что он начнется заново, только увеличивая время простоя. Если мы наблюдаем прогресс и нет явных ошибок в логах, дадим SQL Server завершить свою работу.

2. Проверяем журналы ошибок SQL Server

Это критически важный первый шаг. Внимательно изучим журнал ошибок SQL Server. Ищем сообщения, которые могут указывать на причину задержки или сбоя восстановления. Это могут быть ошибки ввода-вывода, сообщения о повреждении файлов, нехватке памяти или другие системные ошибки. Например, сообщения типа "I/O error", "corruption", "memory pressure" могут дать нам направление для дальнейшей диагностики.

3. Мониторим ресурсы сервера

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

  1. Дисковое пространство: Убедимся, что на дисках, где расположены файлы базы данных (MDF, LDF) и системные базы данных, достаточно свободного места. Переполнение диска может остановить процесс восстановления.
  2. Дисковый ввод-вывод (I/O): Проверим утилизацию дисков. Высокая задержка или низкая пропускная способность могут значительно замедлить процесс восстановления.
  3. Процессор (CPU): Если процессор перегружен, это также может затянуть восстановление.
  4. Оперативная память (RAM): Недостаток памяти может привести к избыточному использованию файла подкачки, что замедлит все операции.

4. Проверяем права доступа к файлам БД

Если база данных находится в состоянии "Recovery Pending" (ожидание восстановления) или "In Recovery" без видимого прогресса, мы должны проверить права доступа для учетной записи службы SQL Server к файлам базы данных. Учетная запись должна иметь полные права на чтение и запись к каталогам, где хранятся файлы .mdf и .ldf. Проверим, не менялись ли эти права недавно.

5. Используем команду 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 принудительно отключает текущие соединения.

6. Рассматриваем отсоединение и присоединение базы данных (Detach/Attach)

В некоторых случаях, особенно когда база данных находится в состоянии "Recovery Pending" из-за проблем с доступностью файлов (например, после временной недоступности сетевого хранилища), отсоединение и повторное присоединение базы данных может помочь. Этот метод работает, если файлы базы данных не повреждены. Мы должны быть крайне осторожны при использовании этого метода, так как некорректное выполнение может привести к потере данных:

  1. Переведем базу данных в автономный режим (Offline) или остановим SQL Server.
  2. В SSMS, щелкнем правой кнопкой мыши на базе данных, выберем "Tasks" -> "Detach". Убедимся, что мы не устанавливаем флажок "Delete connections", если только не уверены в этом.
  3. После отсоединения, снова щелкнем правой кнопкой мыши на "Databases" в SSMS, выберем "Attach". Укажем путь к файлу .mdf. SQL Server попытается повторно присоединить базу данных и запустит процесс восстановления, если это необходимо.

7. Применяем режим EMERGENCY и DBCC CHECKDB (как крайняя мера)

Если все вышеперечисленные методы не помогают и мы подозреваем серьезное повреждение файлов, мы можем попытаться использовать режим EMERGENCY для диагностики и ремонта. Этот метод следует применять с крайней осторожностью, так как опция ремонта может привести к потере данных. Всегда делайте резервную копию файлов базы данных, прежде чем использовать REPAIR_ALLOW_DATA_LOSS!

  1. Переведем базу данных в режим EMERGENCY:
    
    ALTER DATABASE [Имя_Базы_Данных] SET EMERGENCY;
    GO
    
    В этом режиме база данных становится доступной только для чтения администраторам и отключается ведение журнала транзакций, что позволяет нам выполнять ремонт.
  2. Выполним проверку целостности базы данных:
    
    DBCC CHECKDB ([Имя_Базы_Данных]) WITH NO_INFOMSGS;
    GO
    
    Это поможет нам выявить степень повреждений.
  3. Если DBCC CHECKDB сообщает о серьезных ошибках, попробуем ремонт (только если нет актуальной резервной копии и готовы к потере данных):
    
    ALTER DATABASE [Имя_Базы_Данных] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    GO
    DBCC CHECKDB ([Имя_Базы_Данных], REPAIR_ALLOW_DATA_LOSS) WITH ALL_ERRORMSGS;
    GO
    
  4. После ремонта переведем базу данных обратно в многопользовательский режим:
    
    ALTER DATABASE [Имя_Базы_Данных] SET MULTI_USER;
    GO
    

8. Восстановление из резервной копии

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

9. Управление журналом транзакций

Для предотвращения будущих проблем, связанных с журналом транзакций, мы должны правильно управлять его ростом. Регулярно выполняем резервное копирование журналов транзакций (в моделях полного или массового протоколирования) и следим за размером виртуальных файлов журнала (VLF). Большое количество VLF может значительно увеличить время восстановления.

Отличие "In Recovery" от "Recovery Pending"

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

Заключение

Режим "In Recovery" в SQL Server – это, как правило, индикатор того, что система выполняет важную работу по обеспечению целостности данных. В большинстве случаев достаточно просто подождать. Однако, если процесс затягивается или база данных переходит в состояние "Recovery Pending", нам необходимо активно диагностировать проблему, используя журналы ошибок, мониторинг ресурсов и специфические команды SQL Server. Всегда помним о важности регулярного резервного копирования как о последней и самой надежной линии защиты от потери данных.

← На главную