При администрировании старых, но до сих пор активно используемых систем на платформе 1С:Предприятие 7.7 в связке с СУБД MS SQL Server 2000 системные администраторы часто сталкиваются с проблемой неконтролируемого роста файлов баз данных и резервных копий. Типичная ситуация: после выполнения процедуры «Тестирование и исправление» (ТИС) в конфигураторе 1С реальный объем данных уменьшается, однако физические файлы базы данных .mdf и файлы резервных копии .bak на диске продолжают занимать огромное пространство.
В этой статье мы подробно разберем, почему так происходит, как правильно освободить дисковое пространство на сервере без потери производительности СУБД, а также как настроить оптимальную и безопасную стратегию резервного копирования, чтобы избежать колоссальных нагрузок на дисковую подсистему ввода-вывода (I/O).
Рассмотрим причину странного поведения SQL Server, когда физический файл резервной копии весит 14 Гб, но при попытке восстановить базу в окне мастера восстановления отображается размер всего в 1 Гб. Здесь работают два ключевых механизма MS SQL Server:
.bak). Если в файле уже хранился старый бэкап размером 14 Гб, то новый бэкап просто добавился внутрь него. При восстановлении SQL Server считывает заголовки и предлагает выбрать конкретную резервную копию. Вы выбираете последнюю копию (сделанную после ТИС), и СУБД показывает её реальный логический размер — 1 Гб. Однако на диске файл продолжает хранить все предыдущие копии..mdf в бэкап не попадает. Процедура «Тестирование и исправление» в 1С 7.7 удаляет множество временных таблиц, старых индексов и очищает таблицы итогов перед их пересчетом. В результате объем реальных данных сократился до 1 Гб, что и зафиксировал новый бэкап-сет.Чтобы физический файл бэкапа занимал на диске ровно столько, сколько весят актуальные данные, необходимо перезаписывать файл бэкапа при каждом копировании. Для этого в SQL-скрипте бэкапа нужно использовать параметр WITH INIT. Рассмотрим пример правильного скрипта резервного копирования:
BACKUP DATABASE [Trade_Base]
TO DISK = 'D:\Backup\Trade_Base.bak'
WITH INIT, STATS = 10;
Параметр WITH INIT указывает СУБД полностью перезаписать целевой файл бэкапа, удалив из него все старые бэкап-сеты. Также хорошей практикой является формирование уникального имени файла для каждого бэкапа с добавлением текущей даты и времени (например, с помощью bat-файла или шага в SQL Server Agent).
После удаления «мусора» с помощью ТИС внутри файла базы данных .mdf образовалось 13 Гб пустого пространства. Однако операционная система этого не видит, так как SQL Server не возвращает освободившееся место автоматически, резервируя его под будущие транзакции базы данных 1С 7.7. Чтобы вернуть это место операционной системе, нам необходимо выполнить операцию сжатия (Shrink).
Выполнить сжатие можно двумя способами: через графический интерфейс Enterprise Manager или с помощью T-SQL команд. Рассмотрим самый надежный способ — использование T-SQL команд.
Перед сжатием нам необходимо узнать логические имена файлов базы данных. Для этого выполним процедуру:
EXEC sp_helpdb 'Trade_Base';
В результате мы получим таблицу, в которой будут указаны логические имена файлов (столбец Name). Обычно файл данных имеет имя вида Trade_Data, а файл лога транзакций — Trade_Log.
Теперь мы можем выполнить сжатие конкретного файла данных до желаемого размера (например, сожмем его, оставив небольшой запас свободного места):
-- Переводим базу в контекст нашей базы данных
USE [Trade_Base];
GO
-- Сжимаем файл данных (указываем логическое имя файла и целевой размер в Мегабайтах)
DBCC SHRINKFILE (Trade_Data, 1500);
GO
Также можно выполнить сжатие всей базы данных целиком, указав процент свободного места, которое нужно оставить СУБД для оперативной работы:
DBCC SHRINKDATABASE (Trade_Base, 10);
GO
Здесь цифра 10 означает, что СУБД сожмет базу данных максимально, но оставит 10% свободного пространства в файлах про запас, чтобы при создании новых документов СУБД не тратила ресурсы на немедленное расширение файлов.
Важное предупреждение: Операция сжатия (Shrink) физически перемещает страницы данных из конца файла в свободные слоты в начале файла. Этот процесс полностью разрушает физический порядок страниц, вызывая катастрофическую фрагментацию индексов (уровень фрагментации может достигать 95-99%).
Если сразу после выполнения сжатия запустить пользователей в 1С 7.7, система начнет работать критически медленно. Проведение документов, построение отчетов и поиск номенклатуры будут вызывать огромные задержки. Поэтому сразу после завершения Shrink необходимо выполнить переиндексацию всех таблиц базы данных!
В MS SQL Server 2000 для переиндексации используется команда DBCC DBREINDEX. Поскольку таблиц в базе 1С 7.7 очень много, выполнять команду для каждой таблицы вручную нецелесообразно. Напишем и запустим скрипт-курсор, который автоматически переиндексирует все таблицы в нашей базе данных:
USE [Trade_Base];
GO
DECLARE @TableName VARCHAR(255);
DECLARE TableCursor CURSOR FOR
SELECT table_name
FROM information_schema.tables
WHERE table_type = 'BASE TABLE';
OPEN TableCursor;
FETCH NEXT FROM TableCursor INTO @TableName;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Выполняется переиндексация таблицы: ' + @TableName;
DBCC DBREINDEX(@TableName);
FETCH NEXT FROM TableCursor INTO @TableName;
END;
CLOSE TableCursor;
DEALLOCATE TableCursor;
GO
Этот скрипт последовательно пройдет по всем таблицам базы данных 1С 7.7 (включая таблицы справочников, документов и регистров накопления) и перестроит для них индексы с нуля. Это полностью устранит фрагментацию, вызванную сжатием, и значительно ускорит работу всей системы.
Проанализируем текущую схему резервного копирования, описанную автором темы: в базе установлена модель восстановления FULL, при этом каждый час выполняется полный бэкап (FULL backup) всей базы данных размером 14 Гб.
Такая схема является грубой ошибкой администрирования по следующим причинам:
FULL теряется, если не делать регулярные бэкапы журнала транзакций (лог-файла .ldf). В модели FULL лог транзакций будет расти бесконечно, пока не займет все дисковое пространство, так как он очищается только после бэкапа самого лога.Разберем два правильных варианта настройки резервного копирования в зависимости от требований бизнеса к сохранности данных.
Этот вариант идеально подходит, если бизнес готов к потере данных за несколько рабочих часов в случае серьезной аварии (например, если операторы могут при необходимости заново внести документы за текущий день по бумажным носителям).
При использовании модели SIMPLE журнал транзакций автоматически очищается при каждом контрольном событии (checkpoint), что исключает его бесконтрольный рост. Нам больше не нужно регулярно сжимать лог-файл вручную.
Для настройки этого варианта выполним следующие действия:
WITH INIT или сохраняться в новый файл с уникальной датой в имени.Запрос для перевода базы данных в простую модель восстановления на SQL Server 2000:
ALTER DATABASE [Trade_Base] SET RECOVERY SIMPLE;
GO
Данный вариант необходим, если бизнес требует минимизации потерь данных вплоть до нескольких минут (Point-in-Time Recovery) — например, при высокой интенсивности продаж на оптовых складах.
Для настройки правильной работы модели FULL выполним следующие шаги:
Преимущество бэкапа лога заключается в том, что он сохраняет только изменения, записанные в лог-файл за последний час. Такой бэкап выполняется мгновенно (доли секунды), практически не создает нагрузки на сервер и весит всего несколько мегабайт. При этом бэкап лога автоматически помечает обработанные транзакции как неактивные, что позволяет SQL Server повторно использовать пространство внутри файла .ldf, останавливая его рост.
Пример SQL-команды для бэкапа журнала транзакций:
BACKUP LOG [Trade_Base]
TO DISK = 'D:\Backup\Trade_Base_Log.trn'
WITH INIT;
GO
В случае сбоя диска мы сможем восстановить базу данных на любой момент времени, последовательно восстановив последний ночной полный бэкап, а затем цепочку ежечасных бэкапов журнала транзакций.
Для наведения порядка в обслуживании базы данных 1С 7.7 на MS SQL Server 2000 выполним комплекс работ по следующему чек-листу:
DBCC SHRINKFILE, освободив неиспользуемое дисковое пространство.DBCC DBREINDEX для восстановления производительности СУБД.SIMPLE (если нет жестких требований к ежеминутной сохранности транзакций).WITH INIT и дневные разностные бэкапы, полностью отказавшись от неэффективной схемы ежечасных полных резервных копий.Выполнение этих шагов позволит вам навсегда решить проблему нехватки дискового пространства, ускорит работу базы данных 1С 7.7 и гарантирует надежную защиту корпоративной информации от сбоев.