Чистим раздувшиеся реквизиты ХранилищеЗначения в базе 1С 8.3

· 11 мин

Содержание

Очистить хранилище значений в 1С можно тремя путями: штатной обработкой конфигурации (удаление устаревших версий объектов, перенос файлов в тома, очистка настроек пользователей), своей обработкой, которая записывает в реквизит пустое Новый ХранилищеЗначения(Неопределено), и прямым удалением строк служебных таблиц. Первый путь безопасен, второй требует копии базы, третий почти всегда ломает учёт. После любого из них место на диске освобождается только после сжатия таблиц СУБД.

Тип ХранилищеЗначения — это «контейнер», в который 1С 8.3 кладёт произвольное значение в сериализованном виде: картинку, файл, табличный документ, структуру. Сами данные лежат в базе как двоичный поток. Поэтому несколько таких реквизитов с файлами по 5–10 МБ легко превращают базу в 20 ГБ при реальном объёме учёта в 2 ГБ.

Откуда в базе 1С берутся тяжёлые хранилища значений

Реквизит типа ХранилищеЗначения не ограничен по размеру. Платформа не следит, что в него кладут: хоть скан на 30 МБ, хоть выгрузку целого отчёта. Именно поэтому такие поля растут незаметно.

Типовые источники в конфигурациях на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11):

  • 📎 Присоединённые файлы. Сканы договоров, фото товаров, вложения писем. Если включено хранение файлов в информационной базе, каждый файл ложится в служебный регистр двоичных данных.
  • 🕘 Версии объектов. При включённом версионировании каждое изменение документа сохраняет полную копию объекта. Документ, который правили 200 раз, хранит 200 копий.
  • ⚙️ Настройки пользователей. Варианты отчётов, настройки форм, сохранённые отборы. Обычно небольшие, но при сотне пользователей набегает заметный объём.
  • 📨 Электронные документы и письма. Входящие и исходящие пакеты ЭДО, вложения во взаимодействиях.
  • 🧩 Доработки. Самописные реквизиты «Фото», «Файл», «ДанныеОбмена», куда разработчик когда-то начал складывать выгрузки.

В платформе есть и системные хранилища: ХранилищеОбщихНастроек, ХранилищеСистемныхНастроек, ХранилищеНастроекДанныхФорм, ХранилищеВариантовОтчетов. Они тоже хранят данные в сериализованном виде, и чистить их приходится по тем же правилам.

Как узнать, сколько места занимает хранилище значений

Чистить вслепую бессмысленно. Сначала найдите две-три таблицы, которые дают основной объём. Обычно это 80–90% лишнего веса.

Клиент-серверная база на MS SQL Server

Запрос в SQL Server Management Studio к базе 1С покажет 20 самых крупных таблиц:

SELECT TOP 20
    t.name AS table_name,
    SUM(a.total_pages) * 8 / 1024 AS size_mb
FROM sys.tables t
JOIN sys.partitions p ON t.object_id = p.object_id
JOIN sys.allocation_units a ON p.partition_id = a.container_id
GROUP BY t.name
ORDER BY size_mb DESC;

Клиент-серверная база на PostgreSQL

SELECT relname AS table_name,
       pg_size_pretty(pg_total_relation_size(relid)) AS total_size
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC
LIMIT 20;

Как сопоставить таблицу СУБД с объектом 1С

Имена вида _InfoRg12345 или _Reference87 ничего не говорят. Соответствие даёт метод ПолучитьСтруктуруХраненияБазыДанных(). Его можно выполнить в любой консоли кода на сервере:

Структура = ПолучитьСтруктуруХраненияБазыДанных();
Для Каждого Строка Из Структура Цикл
    Если Строка.ИмяТаблицыХранения = "_InfoRg12345" Тогда
        Сообщить(Строка.Метаданные + " / " + Строка.Назначение);
    КонецЕсли;
КонецЦикла;

Подставьте имя таблицы из результата SQL-запроса. На выходе получите, например, РегистрСведений.ВерсииОбъектов / Основная.

На платформе 8.3.15 и новее есть ещё метод ПолучитьРазмерДанныхБазыДанных(). Он возвращает размер данных по указанным объектам метаданных прямо из встроенного языка и работает и в файловой базе. Состав параметров смотрите в синтаксис-помощнике своей версии платформы.

В файловой базе без кода размер по таблицам не увидеть. Ориентир — размер файла 1Cv8.1CD до и после очистки.

Способы очистить хранилище значений: от безопасного к радикальному

СпособКогда подходитРиск
Штатная очистка версий объектовРаздут регистр версийНизкий: теряется только история правок
Перенос файлов в тома на дискеРаздут регистр двоичных данных файловНизкий, но нужен доступный всем серверам каталог
Очистка настроек пользователейРаздуты системные хранилища настроекНизкий: пользователи теряют свои настройки форм
Своя обработка очистки реквизитаДоработанный реквизит с ненужными даннымиСредний: обход проверок, нужна копия
Удаление строк в СУБД напрямуюНикогда для рабочей базыВысокий: нарушение целостности

Перед любым способом сделайте резервную копию: выгрузку .dt или бэкап средствами СУБД. Очищенное содержимое хранилища назад не вернуть.

Способ 1. Удалить устаревшие версии объектов

В конфигурациях на БСП версионирование настраивается в Администрирование → Общие настройки, в группе про историю изменений. Там задаются объекты, для которых хранятся версии, и срок хранения.

Порядок действий:

  1. Откройте настройки версионирования и задайте срок хранения, например 1 год вместо «бессрочно».
  2. Для справочников и документов, где история не нужна, выключите хранение версий.
  3. Запустите удаление устаревших версий из той же формы настроек.
  4. Проверьте, что регламентное задание очистки версий включено: Администрирование → Обслуживание → Регламентные операции → Регламентные и фоновые задания.

Первый запуск на большой базе может идти несколько часов. Делайте его вечером: задание грузит сервер, но работать пользователям не мешает.

Способ 2. Перенести присоединённые файлы в тома

Если основной объём дают файлы, их не удаляют, а выносят из базы на диск. В той же группе Администрирование → Общие настройки найдите настройки работы с файлами и выберите хранение в томах на диске.

  1. Создайте каталог на файловом сервере. В клиент-серверной базе путь должен быть сетевым (\\server\1c_files\buh) и доступен пользователю, от имени которого работает сервер 1С.
  2. Добавьте том в справочник томов хранения файлов, укажите путь и максимальный размер.
  3. Переключите способ хранения на «в томах на диске».
  4. Запустите перенос уже существующих файлов из базы в тома (команда есть в списке томов).

Каталог томов нужно включить в резервное копирование отдельно. Выгрузка .dt файлы из томов не содержит.

Способ 3. Очистить настройки пользователей

Для конфигураций на БСП есть форма Администрирование → Настройки пользователей и прав → Настройки пользователей. В ней можно выбрать пользователя и удалить его настройки отчётов, внешнего вида и прочие.

Если пользователей много или нужно почистить всех разом, используйте метод менеджера хранилища. Пример удаляет все системные настройки одного пользователя:

ХранилищеСистемныхНастроек.Удалить(Неопределено, Неопределено, "Иванов");

Первые два параметра Неопределено означают «все ключи объекта и все ключи настроек». Тот же метод Удалить есть у ХранилищеОбщихНастроек и ХранилищеНастроекДанныхФорм. Пользователь после этого увидит формы с настройками по умолчанию.

Способ 4. Очистить реквизит своей обработкой

Для доработанных реквизитов типа ХранилищеЗначения штатной очистки нет. Нужна обработка, которая перезапишет значение пустым хранилищем.

Есть ограничение платформы: поле типа ХранилищеЗначения нельзя использовать в условиях запроса. Отобрать «только заполненные» запросом не получится, придётся проверять каждый объект в коде.

Пример для справочника Номенклатура и реквизита ДопДанные (замените имена на свои):

&НаСервере
Процедура ОчиститьХранилищеНаСервере()

    Выборка = Справочники.Номенклатура.Выбрать();
    Очищено = 0;

    Пока Выборка.Следующий() Цикл
        Объект = Выборка.ПолучитьОбъект();
        Если Объект.ДопДанные.Получить() = Неопределено Тогда
            Продолжить;
        КонецЕсли;

        Объект.ДопДанные = Новый ХранилищеЗначения(Неопределено);
        Объект.ОбменДанными.Загрузка = Истина;
        Объект.Записать();
        Очищено = Очищено + 1;
    КонецЦикла;

    Сообщить("Очищено объектов: " + Формат(Очищено, "ЧГ=0"));

КонецПроцедуры

Что важно в этом коде:

  • 🔒 ОбменДанными.Загрузка = Истина отключает обработчики ПередЗаписью, проверки и подписки. Это ускоряет запись и не меняет другие данные, но в базе с обменами объект может не попасть в регистрацию изменений.
  • ⏱ Обработка идёт объект за объектом, без общей транзакции. Если её прервать, часть объектов останется неочищенной — просто запустите ещё раз.
  • 👤 Запускайте под пользователем с полными правами, лучше в нерабочее время: каждый объект блокируется на время записи.

Для регистра сведений логика та же, только через набор записей: прочитать набор по отбору, заменить значение ресурса, записать набор.

Способ 5. Удаление строк в СУБД — не делайте так

Команды DELETE или UPDATE по таблицам 1С из SQL-консоли обходят платформу. Ссылки в других объектах повиснут, кэш сервера 1С покажет старые данные, а в базе с обменом данные не уйдут в узлы. Если речь о рабочей базе, этот вариант не рассматривается.

Перед очисткой хранилища значений
Выполнено: 0 / 5

Почему база не уменьшилась после очистки

Это главный сюрприз. Очистили 15 ГБ версий, а файл базы остался прежнего размера. Так и должно быть: СУБД помечает освободившиеся страницы как свободные, но не возвращает их операционной системе.

Что делать в каждом варианте:

Тип базыКак вернуть место
ФайловаяКонфигуратор → Администрирование → Тестирование и исправление, флажок «Сжатие таблиц информационной базы»
MS SQL ServerПерестроение индексов, затем DBCC SHRINKFILE для файла данных
PostgreSQLVACUUM FULL по раздутым таблицам
ЛюбаяВыгрузить базу в .dt и загрузить обратно

«Тестирование и исправление» в файловой базе и VACUUM FULL в PostgreSQL блокируют таблицы. Все пользователи должны выйти из базы, иначе их сеансы оборвутся или процедура не начнётся. Запускайте после окончания рабочего дня.

Для MS SQL Server пример сжатия файла данных до 30 ГБ (имя логического файла смотрите в свойствах базы):

USE buh_base;
DBCC SHRINKFILE (N'buh_base', 30720);

После SHRINKFILE индексы сильно фрагментируются. Сразу перестройте их планом обслуживания, иначе 1С начнёт работать медленнее, чем до очистки.

Когда чистить хранилище значений бесполезно

Бывает, что база растёт, а реквизиты-хранилища тут ни при чём. Проверьте эти варианты до того, как писать обработку:

  • 📜 Журнал регистрации. Он лежит не в базе, а в каталоге 1Cv8Log рядом с файлами базы или на сервере в каталоге кластера. Его размер настраивается в Конфигураторе: Администрирование → Настройка журнала регистрации.
  • 🔄 Таблицы регистрации изменений планов обмена. Если узел обмена давно не синхронизировался, изменения копятся миллионами строк. Решение — удалить неактуальный узел или снять регистрацию, а не трогать хранилища.
  • 📊 Итоги и движения регистров. Большая база за 10 лет учёта — это нормально. Тут помогает свёртка базы, а не очистка реквизитов.
  • 💾 Журнал транзакций MS SQL (.ldf). При модели восстановления Full без регулярного бэкапа журнала файл .ldf растёт бесконечно. Это настройка СУБД, а не 1С.
  • 🗂 Временные файлы сервера и кэш клиента. Они вообще не входят в размер базы.

Если по результатам SQL-запроса из второго раздела самыми тяжёлыми оказались таблицы регистров накопления или _ReferenceChngR/_DocumentChngR, хранилище значений ни при чём.

Автоматизация: чтобы хранилище не разрасталось снова

Разовая очистка через полгода вернёт базу в прежний размер, если не поменять настройки. Что стоит автоматизировать:

  1. Срок хранения версий. В настройках версионирования оставьте разумный срок и проверьте, что регламентное задание очистки устаревших версий включено и выполняется (в списке регламентных заданий видна дата последнего запуска).
  2. Хранение новых файлов в томах. После переноса не возвращайте способ хранения «в базе». Новые файлы сразу пойдут на диск.
  3. Своё регламентное задание. Для доработанных реквизитов добавьте в расширение конфигурации регламентное задание, которое по расписанию очищает данные старше N месяцев. Расширение не снимает конфигурацию с поддержки.
  4. Обслуживание СУБД. В MS SQL — план с перестроением индексов раз в неделю. В PostgreSQL достаточно включённого autovacuum; VACUUM FULL нужен только после разовой массовой очистки.

Для фонового запуска своей обработки из командной строки годится режим предприятия с параметром /Execute:

"C:\Program Files\1cv8\8.3.24.1548\bin\1cv8.exe" ENTERPRISE /S"srv1c\buh" /N"Robot" /P"пароль" /Execute"D:\obr\ClearStorage.epf" /DisableStartupMessages

Путь к платформе и номер версии подставьте свои. Пароль в bat-файле лучше не хранить: заведите отдельного пользователя с минимальными правами на эти объекты или используйте аутентификацию ОС.

Как уменьшить хранилище значений без удаления данных

Иногда данные нужны, но в меньшем объёме. Варианты:

  • 🗜 Сжатие при записи. Конструктор принимает второй параметр: Новый ХранилищеЗначения(Данные, Новый СжатиеДанных(9)). Уровень 9 — максимальное сжатие. Для текстов, XML и табличных документов выигрыш бывает в 5–10 раз, для JPEG и PDF почти нулевой.
  • 🖼 Уменьшение картинок до записи. Фото товара на 8 МБ для карточки не нужно, хватит 200–300 КБ. Сжимайте изображения до загрузки в 1С.
  • 🔗 Хранение ссылки вместо файла. Для больших вложений в доработках храните в реквизите путь к файлу на файловом сервере, а не сам файл.
  • 📦 Архивная база. Старые периоды со всей историей вынесите в отдельную копию базы «только для чтения», а в рабочей сверните остатки.

Перепаковать уже записанные данные можно той же обработкой из способа 4: прочитать значение через Получить() и записать заново с Новый СжатиеДанных(9). Это долго, но не теряет ни одного файла.

Ошибки, из-за которых очистка оборачивается проблемой

  • ❌ Очистка без проверки размера. Неделя работы над обработкой ради таблицы на 300 МБ, когда 40 ГБ занимает регистрация изменений давно отключённого узла.
  • ❌ Очистка в рабочее время. Перенос файлов в тома и удаление версий на крупной базе дают нагрузку, а сжатие таблиц выгоняет всех пользователей.
  • ❌ Тома на локальном диске сервера в кластере из нескольких серверов. Файлы окажутся доступны только с одного рабочего сервера, на остальных пользователи увидят ошибку открытия файла.
  • ❌ Забыли про копии томов. После переноса файлов бэкап .dt перестаёт быть полным.
  • ❌ Очистка реквизита в базе с РИБ без учёта обмена. При ОбменДанными.Загрузка = Истина изменение может не уйти в подчинённые узлы, и там данные останутся. Чистите в каждом узле или регистрируйте изменения явно.

Частые вопросы

Можно ли очистить хранилище значений в типовой конфигурации без программиста?
Да, если раздуты версии объектов, файлы или настройки пользователей. Для них в БСП есть штатные формы в разделе «Администрирование». Код нужен только для доработанных реквизитов.
Сколько места освобождает удаление версий объектов?
Зависит от числа правок документов. В базах, где версионирование годами работало без срока хранения, регистр версий нередко занимает треть и больше от размера базы.
Почему нельзя отобрать запросом только заполненные хранилища?
Поле типа ХранилищеЗначения не участвует в условиях и сравнениях запроса. Проверять заполненность приходится в коде, через метод Получить() у каждого объекта.
Снимет ли расширение с регламентным заданием конфигурацию с поддержки?
Нет. Расширение подключается поверх конфигурации и не меняет её, поэтому обновления ставятся как обычно.
Нужно ли пересчитывать итоги после очистки?
Нет. Итоги регистров не зависят от содержимого реквизитов-хранилищ. Достаточно сжатия таблиц, чтобы вернуть место на диске.