Свёртка базы 1С: как до начала работ узнать, что она уменьшит, а что нет
Разговор про свёртку обычно начинается с размера. База перевалила за терабайт, бэкап не помещается в ночь, и звучит предложение свернуть, оставив последние три года. Потом неделя подготовки и ночное окно, и только после проверки остатков видно, сколько освободилось.
Освободиться может мало. Типовая свёртка режет по дате документы и движения регистров. Если основной вес базы лежит в объектах, у которых даты нет или у которых свой механизм очистки, неделя уходит на результат куда скромнее ожидаемого.
Две большие базы и где в них лежал вес
Розничная сеть, 4,2 ТБ. Для базы такого размера первое объяснение всегда одно: накопилась история. Разбор по объектам показал другое. 3,85 ТБ занимал служебный кэш ограничения доступа на уровне записей (RLS) из БСП, больше всего в нём весила история версий шаблонов ограничения. К периоду документов этот кэш не привязан, и срез по годам не убрал бы из него ни строки. Разбор проекта вместе с тремя отброшенными гипотезами лежит в статье 3,85 ТБ мёртвого кэша.
Крупная сеть ломбардов, 2,3 ТБ. Здесь база за одно ночное окно ушла с 2 341 до 573 ГБ, минус 75 %. Свёртка шла своей схемой: на таком объёме типовая обработка в окно не помещалась (разбор). На момент разбора той же базы 451 ГБ и 113,7 млн строк занимали версии объектов. У версий свой срок хранения и своё регламентное задание очистки. Задание годами закрывалось без ошибок примерно за две минуты и удаляло ноль строк: срок хранения стоял "бессрочно", и граница удаления получалась 01.01.0001. Как такие вещи ищутся в чужой базе, описано в статье про протокол чистки.
В обоих случаях ответ на вопрос "что даст свёртка, а что нет" можно было получить до начала работ.
У каких объектов есть дата
Мы пересчитали состав типовой конфигурации Управление торговлей (УТ) 11.5.22.67: 281 документ, 101 регистр накопления и 806 регистров сведений. Из 806 регистров у 729 нет ни периода, ни регистратора, это непериодические регистры с независимой записью. Ещё в УТ 486 справочников. Свёртка по периоду всех их не режет. У части из них есть своя дата и своя очистка, как у версий объектов: регистр без периода, измерения "Объект" и "НомерВерсии", дата лежит в реквизите "ДатаВерсии".
Это количество объектов, а не их вес. Сколько из 729 регистров весят что-то заметное, зависит от базы, и проверять это надо на своей.
Отсюда правило оценки. У объекта с датой свёртка освобождает примерно ту долю его места, какую составляют записи старше границы. У объекта без даты она не освобождает ничего, его чистят своими средствами или не чистят вовсе.
Как прикинуть самому
Размер объекта платформа отдаёт методом ПолучитьРазмерДанныхБазыДанных, число записей по годам считает обычный запрос. Функция ниже берёт полное имя объекта, сама определяет, по какому полю его резать, и для объекта без даты возвращает Неопределено. Запускать её надо на сервере и под пользователем с полными правами: при ограничении доступа на уровне записей запрос посчитает только видимые строки или упадёт по правам.
// Оценка того, сколько места освободит свёртка у одного объекта. // ПолноеИмя - "Документ.РеализацияТоваровУслуг", "РегистрНакопления.ТоварыНаСкладах" и т.п. // ГраницаСреза - записи раньше этой даты считаем уходящими. // Возвращает Неопределено, если у объекта нет даты, по которой режет свёртка. Функция ОценкаСвертки(ПолноеИмя, ГраницаСреза) Экспорт ОбъектМД = Метаданные.НайтиПоПолномуИмени(ПолноеИмя); Если ОбъектМД = Неопределено Тогда Возврат Неопределено; КонецЕсли; // Документы режем по дате, движения регистров по периоду. // Непериодические регистры сведений, справочники и регистры расчёта сюда не попадают. Если Метаданные.Документы.Содержит(ОбъектМД) Тогда ПолеДаты = "Дата"; ИначеЕсли Метаданные.РегистрыНакопления.Содержит(ОбъектМД) Или Метаданные.РегистрыБухгалтерии.Содержит(ОбъектМД) Или Метаданные.РегистрыСведений.Содержит(ОбъектМД) И ОбъектМД.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда ПолеДаты = "Период"; Иначе Возврат Неопределено; КонецЕсли; // Размер в байтах, вместе с табличными частями и индексами объекта. ИменаОбъектов = Новый Массив; ИменаОбъектов.Добавить(ПолноеИмя); Размер = ПолучитьРазмерДанныхБазыДанных(, ИменаОбъектов); // Старые записи считаем по точной дате границы, а разбивку по годам // выгружаем отдельно: по ней видно, сколько лет истории лежит в объекте. Запрос = Новый Запрос; Запрос.УстановитьПараметр("Граница", ГраницаСреза); Запрос.Текст = СтрШаблон( "ВЫБРАТЬ | ГОД(Т.%2) КАК Год, | КОЛИЧЕСТВО(*) КАК Записей, | СУММА(ВЫБОР КОГДА Т.%2 < &Граница ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) КАК Старых |ИЗ | %1 КАК Т |СГРУППИРОВАТЬ ПО | ГОД(Т.%2) |УПОРЯДОЧИТЬ ПО | Год", ПолноеИмя, ПолеДаты); ПоГодам = Запрос.Выполнить().Выгрузить(); Всего = ПоГодам.Итог("Записей"); Старых = ПоГодам.Итог("Старых"); Результат = Новый Структура; Результат.Вставить("Размер", Размер); Результат.Вставить("Записей", Всего); Результат.Вставить("Старых", Старых); Результат.Вставить("Уйдет", ?(Всего = 0, 0, Размер * Старых / Всего)); Результат.Вставить("ПоГодам", ПоГодам); Возврат Результат; КонецФункции
Функцию мы прогнали на тестовой УТ 11.5.22.67. На регистре остатков товаров, периодическом регистре цен и документе реализации она отдала размер, число записей и долю старых. На версиях объектов и справочнике номенклатуры вернула Неопределено, как и задумано. Цифр с той базы не привожу: истории в ней меньше года, и оценка свёртки там ничего не говорит.
Группировка по году на регистре с сотнями миллионов строк читает его целиком. На боевой базе такой запрос лучше гонять ночью или на копии.
Где цифра функции расходится с жизнью:
- Это пропорция по числу записей. Если старые документы короче новых (раньше вели меньше строк в табличной части), освободится меньше, чем показывает доля.
- У периодического регистра сведений срез последних остаётся. Свёртка сохраняет актуальное значение на дату среза, поэтому по таким регистрам оценка завышена.
- Итоги и индексы входят в размер. Пропорционально числу движений они не уменьшаются, так что у регистров с большими итогами ошибка тоже вверх.
- Объекты без даты функция не считает. Их размер берётся тем же
ПолучитьРазмерДанныхБазыДанныхи честно записывается в "не уйдёт". - Место освобождается внутри базы. На MS SQL файл данных без сжатия не уменьшится, на PostgreSQL место останется внутри таблиц до полной очистки.
Разбивка по годам полезна и сама по себе. Для версий объектов её строят тем же запросом, только группируют по реквизиту ДатаВерсии. Если записи лежат на годы дольше настроенного срока хранения, механизм очистки не работает, как у версий в базе ломбардов. По состоянию регламентного задания этого не увидеть, по годам видно сразу.
Если объектов сотни
Сводку по всей конфигурации даёт цикл по метаданным. Справочники в него включены специально: они попадут в таблицу с нулём в колонке "Уйдет", и их вес будет виден рядом со всем остальным.
// Сводка: сколько весит каждый объект и сколько из этого уйдёт при свёртке. // Срез "текущий год и два прошлых". ГраницаСреза = Дата(Год(ТекущаяДатаСеанса()) - 2, 1, 1); Сводка = Новый ТаблицаЗначений; Сводка.Колонки.Добавить("Объект"); Сводка.Колонки.Добавить("Размер"); Сводка.Колонки.Добавить("Уйдет"); Коллекции = Новый Массив; Коллекции.Добавить(Метаданные.Документы); Коллекции.Добавить(Метаданные.РегистрыНакопления); Коллекции.Добавить(Метаданные.РегистрыБухгалтерии); Коллекции.Добавить(Метаданные.РегистрыСведений); Коллекции.Добавить(Метаданные.Справочники); Для Каждого Коллекция Из Коллекции Цикл Для Каждого ОбъектМД Из Коллекция Цикл ПолноеИмя = ОбъектМД.ПолноеИмя(); Строка = Сводка.Добавить(); Строка.Объект = ПолноеИмя; Оценка = ОценкаСвертки(ПолноеИмя, ГраницаСреза); Если Оценка = Неопределено Тогда // Объект без даты: весит, но свёрткой не уменьшится. ИменаОбъектов = Новый Массив; ИменаОбъектов.Добавить(ПолноеИмя); Строка.Размер = ПолучитьРазмерДанныхБазыДанных(, ИменаОбъектов); Строка.Уйдет = 0; Иначе Строка.Размер = Оценка.Размер; Строка.Уйдет = Оценка.Уйдет; КонецЕсли; КонецЦикла; КонецЦикла; Сводка.Сортировать("Размер Убыв");
Итог колонки "Уйдет" против итога колонки "Размер" и есть ответ на вопрос из начала статьи. Первые двадцать строк по размеру показывают, где лежит вес. Если наверху окажутся версии объектов или регистры без периода, сначала разбираться надо с ними, а свёртку планировать потом.
На большой базе этот цикл идёт часами: каждый регистр читается целиком. Поэтому мы собрали то же самое в бесплатную обработку Калькулятор свёртки базы 1С. Размеры и число записей по годам она берёт из статистики сервера СУБД, сводит их по объектам 1С и считает потенциал при срезе "текущий год и два прошлых". В отчёт попадают и настройки сервера: резервное копирование, память, параллелизм. Нужны клиент-серверная база на MS SQL Server или PostgreSQL, платформа 8.3.20 и новее, пользователь 1С с правами администратора и логин СУБД с правом на чтение (для MS SQL роль db_datareader и право VIEW SERVER STATE). Данные базы обработка не меняет. На сервис расчёта уходят только агрегаты: размеры, настройки, число записей по годам. Отчёт готов через 15-45 минут.
Если давать логин СУБД обработке не хочется, начать можно с Карты объёмов. Она читает метаданные и формирует скрипт, который вы отдаёте администратору. По результату видно топ объектов по записям, включая кэши прав и версии.
Другие наши инструменты:
- Чек-ап СУБД под 1С - сорок с лишним проверок настроек SQL Server с вердиктом по каждой. Окно под свёртку задаёт сервер, его стоит проверить заранее.
- Аудит паролей СУБД - у каких баз кластера 1С пароль SQL достаётся из файла настроек кластера и какие пароли слабые. Логин для калькулятора лучше заводить после этой проверки.
- Выгрузка метаданных для нейросети (LLM) - дерево конфигурации в Markdown или JSON для чат-модели, если незнакомую базу перед свёрткой будете разбирать вместе с ней.
Вопрос к тем, кто уже сворачивал: сколько лет истории вы оставили и кто это решил? Мне интересно, чаще ли это налоговые сроки или всё-таки размер диска.
Вступайте в нашу телеграмм-группу Инфостарт
Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.