Как уменьшить размер базы данных MS SQL Server 2000 и настроить бэкапы для 1С 7.7

Системный администратор 1С v7.7 Управленческий учет Торговля и дистрибуция
← На главную

При администрировании старых, но до сих пор активно используемых систем на платформе 1С:Предприятие 7.7 в связке с СУБД MS SQL Server 2000 системные администраторы часто сталкиваются с проблемой неконтролируемого роста файлов баз данных и резервных копий. Типичная ситуация: после выполнения процедуры «Тестирование и исправление» (ТИС) в конфигураторе 1С реальный объем данных уменьшается, однако физические файлы базы данных .mdf и файлы резервных копии .bak на диске продолжают занимать огромное пространство.

В этой статье мы подробно разберем, почему так происходит, как правильно освободить дисковое пространство на сервере без потери производительности СУБД, а также как настроить оптимальную и безопасную стратегию резервного копирования, чтобы избежать колоссальных нагрузок на дисковую подсистему ввода-вывода (I/O).

Почему размер файла бэкапа (.bak) не уменьшается, хотя при восстановлении показывается 1 Гб?

Рассмотрим причину странного поведения SQL Server, когда физический файл резервной копии весит 14 Гб, но при попытке восстановить базу в окне мастера восстановления отображается размер всего в 1 Гб. Здесь работают два ключевых механизма MS SQL Server:

  1. Режим дозаписи в файл (Append) по умолчанию: В СУБД MS SQL Server при создании резервной копии в уже существующий файл на диске новые данные по умолчанию записываются в конец этого файла (создаются так называемые бэкап-сеты внутри одного физического файла .bak). Если в файле уже хранился старый бэкап размером 14 Гб, то новый бэкап просто добавился внутрь него. При восстановлении SQL Server считывает заголовки и предлагает выбрать конкретную резервную копию. Вы выбираете последнюю копию (сделанную после ТИС), и СУБД показывает её реальный логический размер — 1 Гб. Однако на диске файл продолжает хранить все предыдущие копии.
  2. Особенности резервного копирования SQL Server: Файл бэкапа СУБД содержит только фактически занятые страницы данных. Пустое, зарезервированное место внутри файла базы данных .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) на сервере

После удаления «мусора» с помощью ТИС внутри файла базы данных .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!

Важное предупреждение: Операция сжатия (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 Гб.

Такая схема является грубой ошибкой администрирования по следующим причинам:

Разберем два правильных варианта настройки резервного копирования в зависимости от требований бизнеса к сохранности данных.

Вариант А: Перевод базы в простую модель восстановления (SIMPLE)

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

При использовании модели SIMPLE журнал транзакций автоматически очищается при каждом контрольном событии (checkpoint), что исключает его бесконтрольный рост. Нам больше не нужно регулярно сжимать лог-файл вручную.

Для настройки этого варианта выполним следующие действия:

  1. Откроем свойства базы данных в SQL Server Enterprise Manager (или выполним SQL-запрос) и переведем модель восстановления в SIMPLE.
  2. Настроим расписание резервного копирования (через Maintenance Plans в SQL Server или планировщик задач Windows):
    • Полный бэкап (FULL) — 1 раз в сутки (ночью, во внерабочее время). Этот бэкап обязательно должен перезаписывать файл с использованием WITH INIT или сохраняться в новый файл с уникальной датой в имени.
    • Разностный бэкап (DIFFERENTIAL) — 2-3 раза в течение рабочего дня (например, в 12:00 и в 16:00). Разностный бэкап содержит только изменения, произошедшие с момента последнего полного бэкапа. Он выполняется за считанные секунды и весит очень мало.

Запрос для перевода базы данных в простую модель восстановления на SQL Server 2000:


ALTER DATABASE [Trade_Base] SET RECOVERY SIMPLE;
GO

Вариант Б: Правильная настройка полной модели восстановления (FULL)

Данный вариант необходим, если бизнес требует минимизации потерь данных вплоть до нескольких минут (Point-in-Time Recovery) — например, при высокой интенсивности продаж на оптовых складах.

Для настройки правильной работы модели FULL выполним следующие шаги:

  1. Оставим модель восстановления базы в режиме FULL.
  2. Настроим полный бэкап (FULL) только один раз в сутки (ночью). Это снимет дневную нагрузку с дисковой подсистемы.
  3. Вместо ежечасных полных бэкапов настроим ежечасный (или каждые 15-30 минут) бэкап журнала транзакций (BACKUP LOG).

Преимущество бэкапа лога заключается в том, что он сохраняет только изменения, записанные в лог-файл за последний час. Такой бэкап выполняется мгновенно (доли секунды), практически не создает нагрузки на сервер и весит всего несколько мегабайт. При этом бэкап лога автоматически помечает обработанные транзакции как неактивные, что позволяет 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 выполним комплекс работ по следующему чек-листу:

  1. Выполним резервное копирование базы данных.
  2. Проведем процедуру «Тестирование и исправление» в конфигураторе 1С 7.7 для удаления неактуальных данных и очистки временных таблиц.
  3. Выполним сжатие файла данных базы с помощью команды DBCC SHRINKFILE, освободив неиспользуемое дисковое пространство.
  4. Обязательно запустим полную переиндексацию базы данных с помощью скрипта-курсора с командой DBCC DBREINDEX для восстановления производительности СУБД.
  5. Переведем базу данных в модель восстановления SIMPLE (если нет жестких требований к ежеминутной сохранности транзакций).
  6. Настроим ежедневный ночной полный бэкап с параметром WITH INIT и дневные разностные бэкапы, полностью отказавшись от неэффективной схемы ежечасных полных резервных копий.

Выполнение этих шагов позволит вам навсегда решить проблему нехватки дискового пространства, ускорит работу базы данных 1С 7.7 и гарантирует надежную защиту корпоративной информации от сбоев.

← На главную