При администрировании и свертке крупных информационных баз 1С:Предприятие специалисты часто сталкиваются с парадоксальной ситуацией: после удаления большей части документов или выделения одной организации в отдельную базу размер файла данных практически не уменьшается. Даже если в базе остается всего несколько проведенных документов, ее объем может исчисляться гигабайтами. Попытки запустить стандартное тестирование и исправление (ТиИ), сжатие таблиц или пересчет итогов в Конфигураторе часто не приносят желаемого результата.
В этой статье мы подробно разберем, почему возникают так называемые «фантомные» записи в таблицах остатков и итогов регистров накопления и бухгалтерии, выясним причины бессилия стандартных механизмов платформы и рассмотрим эффективные методы очистки базы данных как с помощью прямых SQL-запросов, так и исключительно штатными средствами встроенного языка 1С.
Для того чтобы понять суть проблемы, давайте проанализируем, как платформа 1С работает с регистрами накопления остатков (например, РегистрНакопления.ЗатратыПриУСН) и регистрами бухгалтерии. Данные в СУБД для таких объектов разделены на две основные физические таблицы:
_AccumRg12345) — здесь хранятся детальные записи, создаваемые документами (регистраторами). Каждая строка привязана к конкретному документу и периоду._AccumRgT12345) — в ней хранятся рассчитанные остатки в разрезе измерений на начало каждого месяца, а также текущие итоги.Когда мы распроводим документы, корректируем записи или переносим данные, платформа пересчитывает итоги. Однако оптимизированные алгоритмы СУБД и самой платформы 1С устроены так, что при обнулении остатков строки из таблицы итогов физически удаляются далеко не всегда. Вместо удаления платформа часто просто записывает нулевые значения в поля ресурсов. Со временем, особенно в базах с высокой интенсивностью транзакций и коротким жизненным циклом записей (например, когда резервы или затраты быстро закрываются в ноль), объем таких пустых строк начинает лавинообразно расти. В запущенных случаях таблицы итогов могут на 90–95% состоять из неактуального «мусора».
Ситуация усугубляется, если в базе происходят сбои, приводящие к появлению записей с некорректными (битыми) датами (например, периоды вида "86.75.762" или даты, выходящие за пределы диапазона СУБД MS SQL — ранее 01.01.1753 года). Такие записи полностью нарушают логику расчета итогов платформы: стандартный пересчет просто пропускает их, и они остаются «висеть» в таблицах СУБД навсегда.
Многие администраторы рассчитывают на то, что запуск полного цикла ТиИ с флагами «Реструктуризация таблиц» и «Пересчет итогов» решит проблему. Но на практике этого не происходит по следующим причинам:
Tool_1CD) стандартные утилиты вроде chdbfl.exe рапортуют об отсутствии ошибок, поскольку проверяют только логическую целостность объектов, а не физическое выравнивание страниц СУБД.Давайте подробно рассмотрим, как решить эту проблему различными методами.
Самый простой, быстрый и абсолютно легальный способ полностью очистить таблицы итогов на уровне СУБД без использования стороннего софта — это управление использованием итогов через встроенный язык 1С.
Когда мы отключаем использование итогов для регистра, платформа 1С физически выполняет операцию TRUNCATE TABLE (или ее аналог) для соответствующей таблицы итогов в СУБД. Все фантомные записи, включая строки с битыми датами и нарушенной структурой, уничтожаются. При последующем включении итогов платформа заново создает чистую таблицу и рассчитывает остатки исключительно на основании реально существующих документов в таблице движений.
Давайте разберем по шагам, как это реализовать:
// Отключение использования итогов для полной очистки физической таблицы
ИмяРегистра = "ЗатратыПриУСН"; // Замените на имя вашего регистра накопления
Регистр = РегистрыНакопления[ИмяРегистра];
Попытка
Регистр.УстановитьИспользованиеИтогов(Ложь);
Сообщить("Использование итогов для регистра " + ИмяРегистра + " успешно ОТКЛЮЧЕНО. Таблица итогов очищена.");
Исключение
Сообщить("Не удалось отключить итоги: " + ОписаниеОшибки());
КонецПопытки;
Shrink (сжатие) базы данных в SQL Server Management Studio (SSMS), чтобы вернуть освобожденное дисковое пространство операционной системе.
// Включение итогов и их автоматический чистый пересчет
Попытка
Регистр.УстановитьИспользованиеИтогов(Истина);
Сообщить("Использование итогов для регистра " + ИмяРегистра + " успешно ВКЛЮЧЕНО. Произведен чистый пересчет.");
Исключение
Сообщить("Не удалось включить итоги: " + ОписаниеОшибки());
КонецПопытки;
Этот метод гарантированно избавляет базу от фантомных записей в конкретном регистре без риска повредить ссылочную целостность данных.
Если база данных работает под управлением Microsoft SQL Server или PostgreSQL, а проблемных таблиц много и вы хотите провести комплексную профилактику всей базы данных (особенно после глобальной свертки), можно прибегнуть к прямому очищению служебных таблиц и таблиц итогов через СУБД.
Важно: Перед выполнением любых операций напрямую в СУБД обязательно сделайте резервную копию базы данных (бэкап) и монопольно отключите всех пользователей!
Давайте проанализируем SQL-скрипт, который автоматически находит и формирует команды полной очистки (TRUNCATE TABLE) для всех таблиц итогов регистров накопления, бухгалтерии, таблиц регистрации изменений планов обмена, а также системных настроек и истории работы пользователей, которые часто раздувают базу:
-- Скрипт генерации команд очистки итогов и служебных таблиц для MS SQL Server
-- Выполните этот запрос, скопируйте полученный результат и запустите его как новый запрос
-- 1. Очистка таблиц итогов регистров накопления
SELECT 'TRUNCATE TABLE ' + name + ';' AS SQL_Command FROM sys.tables WHERE name LIKE '_AccumRgT%'
UNION ALL
-- 2. Очистка таблиц итогов регистров бухгалтерии (по счету)
SELECT 'TRUNCATE TABLE ' + name + ';' FROM sys.tables WHERE name LIKE '_AccRgAT%'
UNION ALL
-- 3. Очистка таблиц оборотов между счетами регистров бухгалтерии
SELECT 'TRUNCATE TABLE ' + name + ';' FROM sys.tables WHERE name LIKE '_AccRgCT%'
UNION ALL
-- 4. Очистка таблиц регистрации изменений для планов обмена (если обмены не активны)
SELECT 'TRUNCATE TABLE ' + name + ';' FROM sys.tables WHERE name LIKE '%ChngR%'
UNION ALL
-- 5. Очистка истории работы пользователей
SELECT 'TRUNCATE TABLE ' + name + ';' FROM sys.tables WHERE name LIKE '%UsersWorkHistory%'
UNION ALL
-- 6. Очистка системных настроек (пользовательские настройки форм и окон)
SELECT 'TRUNCATE TABLE ' + name + ';' FROM sys.tables WHERE name LIKE '%SystemSettings%'
UNION ALL
-- 7. Очистка настроек вариантов отчетов
SELECT 'TRUNCATE TABLE ' + name + ';' FROM sys.tables WHERE name LIKE '%RepVarSettings%'
UNION ALL
-- 8. Очистка общих настроек системы
SELECT 'TRUNCATE TABLE ' + name + ';' FROM sys.tables WHERE name LIKE '%CommonSettings%'
UNION ALL
-- 9. Очистка сохраненных настроек данных форм
SELECT 'TRUNCATE TABLE ' + name + ';' FROM sys.tables WHERE name LIKE '%FrmDtSettings%'
UNION ALL
-- 10. Очистка кэша динамических списков
SELECT 'TRUNCATE TABLE ' + name + ';' FROM sys.tables WHERE name LIKE '%DynListSettings%';
После выполнения сгенерированных команд таблицы итогов станут абсолютно пустыми, а база данных существенно уменьшится в объеме.
Обязательный шаг после очистки через SQL: Сразу после выполнения скрипта необходимо зайти в Конфигуратор 1С и запустить Тестирование и исправление с единственным выбранным пунктом — «Пересчет итогов». Платформа просканирует все таблицы движений и воссоздаст актуальные и чистые итоги без «мусора».
Если ваша база является файловой (формат .1CD), и сторонняя утилита Tool_1CD выдает ошибку несоответствия длины таблицы и записи, это свидетельствует о низкоуровневом повреждении структуры заголовков страниц СУБД 1С.
Обычная утилита chdbfl.exe часто бессильна в этом случае. Для исправления ситуации воспользуемся штатной консольной утилитой конвертации баз данных CNVDBFL.EXE, которая поставляется вместе с платформой 1С и находится в каталоге установленной версии платформы (например, C:\Program Files\1cv8\8.3.X.XXXX\bin\).
Давайте выполним реструктуризацию и выравнивание физической разметки базы данных, попутно увеличив размер страницы данных до 64 Кб (это также повысит производительность файловой базы):
"C:\Program Files\1cv8\8.3.22.1709\bin\cnvdbfl.exe" -c -f 8.3.8 -p 64k "D:\1C_Bases\MyBase\1Cv8.1CD"
Параметры утилиты:
-c — режим конвертации базы данных.-f 8.3.8 — формат версии файла базы данных (поддерживающий новые оптимизации).-p 64k — размер страницы базы данных (по умолчанию используется 4k, увеличение до 64k решает проблему ограничений размера таблиц и выравнивает структуру записей).После завершения процесса конвертации физическая структура файла будет полностью перестроена. Ошибка «длина таблицы не кратна длине записи» исчезнет, а утилита Tool_1CD и штатные механизмы тестирования смогут корректно работать с базой.
Если в вашей базе присутствуют записи с некорректными периодами (например, системные сбои записали период с нечитаемыми символами или некорректным годом), их необходимо удалить непосредственно через встроенный язык 1С. Поскольку стандартный отбор по конкретной некорректной дате в коде написать сложно, мы можем применить отбор по диапазону дат, выходящих за рамки здравого смысла.
Рассмотрим пример программного поиска и очистки таких записей:
// Создаем запрос для поиска движений с некорректными датами
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Регистр.Регистратор КАК Регистратор
|ИЗ
| РегистрНакопления.ЗатратыПриУСН КАК Регистр
|ГДЕ
| Регистр.Период < ДАТАВРЕМЯ(1753, 1, 1)
| ИЛИ Регистр.Период > ДАТАВРЕМЯ(3999, 12, 31)";
Результат = Запрос.Выполнить();
Если Не Результат.Пустой() Тогда
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
// Для каждого битого регистратора очищаем набор записей
Набор = РегистрыНакопления.ЗатратыПриУСН.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(Выборка.Регистратор);
Попытка
// Записываем пустой набор записей с флагом замещения, уничтожая битые строки
Набор.Записать(Истина);
Сообщить("Успешно удалены некорректные движения для документа: " + СокрЛП(Выборка.Регистратор));
Исключение
Сообщить("Ошибка очистки движений для " + СокрЛП(Выборка.Регистратор) + ": " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
Иначе
Сообщить("Записей с некорректными датами в регистре не обнаружено.");
КонецЕсли;
Данный скрипт эффективно находит документы, движения которых содержат сбойные даты, и перезаписывает их движения пустым набором, что автоматически убирает эти записи из таблиц итогов СУБД при последующем пересчете.
Для эффективного и безопасного удаления «фантомных» записей в таблицах итогов 1С мы рекомендуем придерживаться следующего алгоритма:
УстановитьИспользованиеИтогов(Ложь)). Это самый безопасный метод, не требующий монопольного доступа к серверу СУБД и написания сложных SQL-запросов.CNVDBFL.EXE с изменением размера страницы до 64 Кб.Применение этих методик позволит вам содержать базы данных 1С в чистоте, существенно сократить время на создание резервных копий и повысить общую скорость работы системы.