Восстановление MSSQL на момент времени: Point-in-Time Recovery через STOPAT
Необходимость точечного отката базы данных на конкретную секунду возникает в следующих аварийных ситуациях:
- Ошибочное выполнение оператором команд
DROP TABLE,TRUNCATEили неконтролируемогоDELETEбез условия WHERE; - Сбой некорректно написанной регламентной обработки 1С, разрушившей проводки или остатки регистров;
- Внедрение деструктивного релиза конфигурации, повредившего метаданные в определенный момент времени.
1. Ключевые условия для работы Point-in-Time Recovery
Восстановление на момент времени возможно только при соблюдении следующих факторов:
- База находится в модели восстановления
FULLилиBULK_LOGGED; - Цепочка файлов журнала транзакций (Log Chain) непрерывна и не содержит пропусков;
- Снят финальный 'хвостовой' лог транзакций (Tail-Log Backup).
2. Создание резервной копии заключительного фрагмента журнала (Tail-Log)
Если база данных еще доступна или переведена в состояние SUSPECT, снимите остаток журнала без усечения:
USE [master];
GO
BACKUP LOG [ERP_1C]
TO DISK = N'E:\Backup\TailLog_ERP_1C.trn'
WITH NORECOVERY, NO_TRUNCATE, CHECKSUM;
GO3. Скрипт восстановления с директивой STOPAT
Предположим, инцидент с повреждением данных произошел в 14:35:10. Восстанавливаем состояние базы на 14:34:00:
-- 1. Восстановление Full бэкапа
RESTORE DATABASE [ERP_1C]
FROM DISK = N'E:\Backup\ERP_1C_Full.bak'
WITH NORECOVERY, REPLACE;
-- 2. Восстановление последнего Diff (если он был сделан до 14:34:00)
RESTORE DATABASE [ERP_1C]
FROM DISK = N'E:\Backup\ERP_1C_Diff.bak'
WITH NORECOVERY;
-- 3. Накат промежуточных Transaction Logs
RESTORE LOG [ERP_1C]
FROM DISK = N'E:\Backup\Log\ERP_1C_Log_1400.trn'
WITH NORECOVERY;
-- 4. Восстановление финального лога с указанием точной временной метки
RESTORE LOG [ERP_1C]
FROM DISK = N'E:\Backup\TailLog_ERP_1C.trn'
WITH RECOVERY, STOPAT = '2024-11-20T14:34:00';
GO4. Проверка консистентности восстановленной базы
ALTER DATABASE [ERP_1C] SET MULTI_USER;
DBCC CHECKDB ([ERP_1C]) WITH NO_INFOMSGS; Частые вопросы (FAQ)
Что делать, если точное время аварии неизвестно?
Восстановите резервную копию журнала транзакций с опцией STANDBY = 'E:\Backup\Rollback.undo'. Это переведет базу в режим Read-Only, позволяя выполнять SELECT запросы для визуального контроля данных между последовательными шагами накатки логов.
Можно ли выполнить STOPAT при модели восстановления SIMPLE?
Нет. В простой модели восстановления (Simple) журнал транзакций автоматически усекается, что делает сохранение промежуточных транзакций невозможным. Доступно только восстановление последнего Full/Diff бэкапа целиком.
Как найти точное время ошибочной транзакции в логе?
Используйте недокументированную системную функцию fn_dblog() или fn_dump_dblog() для анализа операций LOP_DELETE_ROWS / LOP_DROP_TABLE, либо воспользуйтесь утилитой анализа транзакционных логов (ApexSQL Log / Redgate SQL Log Rescue).
Что означает ошибка 'The log or data file is corrupted' при создании Tail-Log?
Если поврежден сам файл журнала LDF, используйте опцию BACKUP LOG ... WITH CONTINUE_AFTER_ERROR, NORECOVERY, чтобы спасти уцелевшие записи перед аварийным восстановлением.