Чистим раздувшиеся реквизиты ХранилищеЗначения в базе 1С 8.3
Содержание
Очистить хранилище
значений в 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 год вместо «бессрочно».
- Для справочников и документов, где история не нужна, выключите хранение версий.
- Запустите удаление устаревших версий из той же формы настроек.
- Проверьте, что регламентное задание очистки версий включено:
Администрирование → Обслуживание → Регламентные операции → Регламентные и фоновые задания.
Первый запуск на большой базе может идти несколько часов. Делайте его вечером: задание грузит сервер, но работать пользователям не мешает.
Способ 2. Перенести присоединённые файлы в тома
Если основной объём дают файлы, их не удаляют, а выносят из базы на диск. В той же группе Администрирование → Общие настройки найдите настройки работы с файлами и выберите хранение в томах на диске.
- Создайте каталог на файловом сервере. В клиент-серверной базе путь должен быть сетевым (
\\server\1c_files\buh) и доступен пользователю, от имени которого работает сервер 1С. - Добавьте том в справочник томов хранения файлов, укажите путь и максимальный размер.
- Переключите способ хранения на «в томах на диске».
- Запустите перенос уже существующих файлов из базы в тома (команда есть в списке томов).
Каталог томов нужно включить в резервное копирование отдельно. Выгрузка .dt файлы из томов не содержит.
Способ 3. Очистить настройки пользователей
Для конфигураций на БСП есть форма Администрирование → Настройки пользователей и прав → Настройки пользователей. В ней можно выбрать пользователя и удалить его настройки отчётов, внешнего вида и прочие.
Если пользователей много или нужно почистить всех разом, используйте метод менеджера хранилища. Пример удаляет все системные настройки одного пользователя:
ХранилищеСистемныхНастроек.Удалить(Неопределено, Неопределено, "Иванов");
Первые два параметра Неопределено означают «все ключи объекта и все ключи настроек». Тот же метод Удалить есть у ХранилищеОбщихНастроек и ХранилищеНастроекДанныхФорм. Пользователь после этого увидит формы с настройками по умолчанию.
Способ 4. Очистить реквизит своей обработкой
Для доработанных реквизитов типа ХранилищеЗначения штатной очистки нет. Нужна обработка, которая перезапишет значение пустым хранилищем.
Есть ограничение платформы: поле типа ХранилищеЗначения нельзя использовать в условиях запроса. Отобрать «только заполненные» запросом не получится, придётся проверять каждый объект в коде.
Пример для справочника Номенклатура и реквизита ДопДанные (замените имена на свои):
&НаСервере
Процедура ОчиститьХранилищеНаСервере()
Выборка = Справочники.Номенклатура.Выбрать();
Очищено = 0;
Пока Выборка.Следующий() Цикл
Объект = Выборка.ПолучитьОбъект();
Если Объект.ДопДанные.Получить() = Неопределено Тогда
Продолжить;
КонецЕсли;
Объект.ДопДанные = Новый ХранилищеЗначения(Неопределено);
Объект.ОбменДанными.Загрузка = Истина;
Объект.Записать();
Очищено = Очищено + 1;
КонецЦикла;
Сообщить("Очищено объектов: " + Формат(Очищено, "ЧГ=0"));
КонецПроцедуры
Что важно в этом коде:
- 🔒
ОбменДанными.Загрузка = Истинаотключает обработчикиПередЗаписью, проверки и подписки. Это ускоряет запись и не меняет другие данные, но в базе с обменами объект может не попасть в регистрацию изменений. - ⏱ Обработка идёт объект за объектом, без общей транзакции. Если её прервать, часть объектов останется неочищенной — просто запустите ещё раз.
- 👤 Запускайте под пользователем с полными правами, лучше в нерабочее время: каждый объект блокируется на время записи.
Для регистра сведений логика та же, только через набор записей: прочитать набор по отбору, заменить значение ресурса, записать набор.
Способ 5. Удаление строк в СУБД — не делайте так
Команды DELETE или UPDATE по таблицам 1С из SQL-консоли обходят платформу. Ссылки в других объектах повиснут, кэш сервера 1С покажет старые данные, а в базе с обменом данные не уйдут в узлы. Если речь о рабочей базе, этот вариант не рассматривается.
Почему база не уменьшилась после очистки
Это главный сюрприз. Очистили 15 ГБ версий, а файл базы остался прежнего размера. Так и должно быть: СУБД помечает освободившиеся страницы как свободные, но не возвращает их операционной системе.
Что делать в каждом варианте:
| Тип базы | Как вернуть место |
|---|---|
| Файловая | Конфигуратор → Администрирование → Тестирование и исправление, флажок «Сжатие таблиц информационной базы» |
| MS SQL Server | Перестроение индексов, затем DBCC SHRINKFILE для файла данных |
| PostgreSQL | VACUUM 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, хранилище значений ни при чём.
Автоматизация: чтобы хранилище не разрасталось снова
Разовая очистка через полгода вернёт базу в прежний размер, если не поменять настройки. Что стоит автоматизировать:
- Срок хранения версий. В настройках версионирования оставьте разумный срок и проверьте, что регламентное задание очистки устаревших версий включено и выполняется (в списке регламентных заданий видна дата последнего запуска).
- Хранение новых файлов в томах. После переноса не возвращайте способ хранения «в базе». Новые файлы сразу пойдут на диск.
- Своё регламентное задание. Для доработанных реквизитов добавьте в расширение конфигурации регламентное задание, которое по расписанию очищает данные старше N месяцев. Расширение не снимает конфигурацию с поддержки.
- Обслуживание СУБД. В 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перестаёт быть полным. - ❌ Очистка реквизита в базе с РИБ без учёта обмена. При
ОбменДанными.Загрузка = Истинаизменение может не уйти в подчинённые узлы, и там данные останутся. Чистите в каждом узле или регистрируйте изменения явно.