Как удалить неиспользуемые изображения номенклатуры и уменьшить физический размер базы данных в 1С:УПП и УТ

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При ведении учета в конфигурациях 1С:Управление производственным предприятием (УПП) ред. 1.3 или 1С:Управление торговлей (УТ) ред. 10.3 пользователи часто сталкиваются с критическим ростом объема информационной базы. Основным «виновником» этого процесса обычно становятся графические файлы — изображения номенклатуры, сканы сертификатов и прикрепленные файлы документов. Когда наступает момент оптимизации базы (например, при удалении старых позиций номенклатуры или свертке базы), обычное удаление ссылочных объектов не приводит к уменьшению дискового пространства. Выясним, почему это происходит, как программно очистить хранилище и какими методами можно вернуть дисковое пространство операционной системе.

Архитектура хранения картинок в конфигурациях на обычных формах

Для начала проанализируем, как именно платформа 1С хранит файлы в типовых конфигурациях прошлых поколений. В отличие от современных конфигураций на базе БСП (Библиотеки стандартных подсистем), где файлы могут сразу записываться в тома на диске, в УПП 1.3 и УТ 10.3 по умолчанию используется справочник ХранилищеДополнительнойИнформации.

Рассмотрим структуру этого справочника:

Важная особенность платформы: при установке пометки удаления на элемент номенклатуры или при его непосредственном удалении связанные элементы справочника ХранилищеДополнительнойИнформации автоматически не удаляются и даже не помечаются на удаление. Связанные картинки остаются «сиротами» внутри базы данных, продолжая занимать гигабайты свободного пространства. Чтобы решить эту проблему, нам потребуется комплексный подход: программный поиск и маркировка элементов, окончательное удаление и физическая оптимизация таблиц СУБД.

Шаг 1. Программный поиск и пометка на удаление «лишних» картинок

Проводить ручную очистку базы, содержащей десятки тысяч позиций номенклатуры, невозможно. Нам необходимо написать обработку, которая автоматизирует этот процесс. Рассмотрим два возможных сценария очистки в зависимости от текущего состояния базы данных.

Сценарий А: Номенклатура помечена на удаление, но еще физически присутствует в базе

Если мы готовимся к штатному удалению позиций номенклатуры, нам нужно предварительно найти все прикрепленные к ним изображения и также пометить их на удаление. Разберем код внешней обработки, которая решает эту задачу:


Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	Хранилище.Ссылка КАК Ссылка
|ИЗ
|	Справочник.ХранилищеДополнительнойИнформации КАК Хранилище
|ГДЕ
|	Хранилище.Объект.ПометкаУдаления = ИСТИНА";

РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
	Выборка = РезультатЗапроса.Выбрать();
	Пока Выборка.Следующий() Цикл
		ОбъектКартинки = Выборка.Ссылка.ПолучитьОбъект();
		ОбъектКартинки.УстановитьПометкуУдаления(Истина);
	КонецЦикла;
	Сообщить("Связанные изображения успешно помечены на удаление.");
Иначе
	Сообщить("Не найдено изображений, привязанных к помеченной на удаление номенклатуре.");
КонецЕсли;

Сценарий Б: Номенклатура была удалена напрямую (образовались «битые ссылки»)

Если номенклатуру удалили без контроля ссылочной целостности (например, обработкой «Непосредственное удаление» или в результате некорректного обмена данными), то в поле Объект справочника хранилища останется так называемая «битая ссылка» (в интерфейсе она выглядит как <Объект не найден...>).

Попытка обратиться через точку к реквизитам такого объекта вызовет ошибку, но мы можем использовать встроенный язык запросов 1С и специальное свойство ЕСТЬ NULL для поиска таких записей. Проанализируем пример кода:


Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	Хранилище.Ссылка КАК Ссылка
|ИЗ
|	Справочник.ХранилищеДополнительнойИнформации КАК Хранилище
|ГДЕ
|	Хранилище.Объект.Ссылка ЕСТЬ NULL 
|	И НЕ Хранилище.Объект = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)";

РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
	Выборка = РезультатЗапроса.Выбрать();
	НачатьТранзакцию();
	Попытка
		Пока Выборка.Следующий() Цикл
			// Поскольку владелец физически отсутствует, данные элементы можно удалить непосредственно
			ОбъектКартинки = Выборка.Ссылка.ПолучитьОбъект();
			ОбъектКартинки.Удалить();
		КонецЦикла;
		ЗафиксироватьТранзакцию();
		Сообщить("Успешно удалены 'осиротевшие' элементы хранилища.");
	Исключение
		ОтменитьТранзакцию();
		Сообщить("Ошибка при удалении: " + ОписаниеОшибки());
	КонецПопытки;
КонецЕсли;

Шаг 2. Окончательное удаление объектов из базы данных

Для элементов, которые мы пометили на удаление в первом сценарии, необходимо запустить штатную процедуру системы. Перейдем в меню Операции -> Удаление помеченных объектов. Рекомендуется использовать монопольный режим работы, чтобы избежать взаимных блокировок таблиц другими пользователями.

После успешного завершения операции записи о картинках исчезнут из справочника ХранилищеДополнительнойИнформации. Однако, если мы посмотрим на физический размер файла базы данных (1Cv8.1CD для файлового варианта или файлы .mdf / .ldf на SQL-сервере), мы увидим, что размер базы не уменьшился ни на один байт. Выясним причину этого явления.

Шаг 3. Физическое сжатие базы данных и освобождение дискового пространства

Любая современная СУБД (включая встроенный движок файловой версии 1С) оптимизирована для быстрой записи новых данных. Когда объект удаляется, СУБД физически не стирает его с диска и не уменьшает размер файла, чтобы не тратить ресурсы процессора на перезапись секторов. СУБД просто помечает страницы данных, где хранился объект, как «пустые» и доступные для записи новой информации в будущем.

Если нам необходимо вернуть освобожденное место операционной системе прямо сейчас, мы должны запустить процедуру физического сжатия базы данных. Метод сжатия зависит от используемого варианта работы.

Вариант 1. Файловая база данных (.1CD)

Для сжатия файловой базы данных у нас есть три основных инструмента:

  1. Тестирование и исправление в конфигураторе. Запустим Конфигуратор, откроем меню Администрирование -> Тестирование и исправление. Установим флажок на пункте Сжатие таблиц информационной базы и нажмем кнопку «Выполнить». Платформа перегруппирует записи и обрежет неиспользуемые хвосты файла базы.
  2. Утилита chdbfl.exe. Этот инструмент находится в папке bin установленной платформы 1С. Закроем все сеансы с базой, запустим утилиту, укажем путь к файлу базы данных и запустим проверку с исправлением ошибок. Помимо исправления ошибок, утилита автоматически выполняет физическое сжатие файла.
  3. Выгрузка и загрузка файла резервной копии (.dt). Это наиболее надежный способ полной пересборки файловой базы. Выполним выгрузку базы через меню Администрирование -> Выгрузить информационную базу. Затем создадим абсолютно новую пустую файловую базу и загрузим туда полученный файл .dt. В процессе загрузки платформа сформирует файл 1Cv8.1CD заново, полностью исключив из него пустоты и фрагментированные области.

Вариант 2. Клиент-серверная база на Microsoft SQL Server

На SQL-сервере удаление терабайтов картинок приводит к образованию пустого пространства внутри основного файла данных (.mdf). Чтобы вернуть это место операционной системе, администратор СУБД должен выполнить процедуру сжатия (Shrink):

  1. Откроем SQL Server Management Studio (SSMS).
  2. Кликнем правой кнопкой мыши по нужной базе данных, перейдем в раздел Tasks (Задачи) -> Shrink (Сжать) -> Files (Файлы).
  3. В выпадающем списке выберем тип файла Data (Данные). В поле «Action» выберем вариант реорганизации страниц перед освобождением неиспользуемого места и укажем желаемый минимальный размер файла.
  4. Нажмем кнопку «ОК».

Также можно воспользоваться прямой SQL-командой в окне запроса:


DBCC SHRINKFILE (Имя_Файла_Данных, Целевой_Размер_В_Мегабайтах);

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

В СУБД PostgreSQL при удалении строк СУБД создает так называемые «мертвые кортежи» (dead tuples). Обычная фоновая очистка (Autovacuum) освобождает это место для новых записей внутри самой базы, но не уменьшает размер файлов на жестком диске. Чтобы уменьшить размер базы в Postgres, необходимо выполнить ресурсоемкую операцию:

  1. Подключимся к базе данных через консоль psql или графическую утилиту pgAdmin.
  2. Выполним команду полного вакуумирования:
    
    VACUUM FULL;
    

Важное предупреждение: команда VACUUM FULL полностью блокирует таблицы базы данных на чтение и запись. В зависимости от объема базы данных эта процедура может занять значительное время (от нескольких часов до суток), поэтому выполнять ее следует строго во время технологического окна (например, в выходные дни).

Отрицательные последствия сжатия баз данных

Рассмотрим, почему операцией сжатия базы данных (Shrink / VACUUM FULL) не стоит злоупотреблять без острой необходимости. Любое физическое сжатие таблиц на уровне СУБД несет в себе скрытые риски:

Современное архитектурное решение: переход на тома хранения файлов

Хранить графические файлы и тяжелые сканы документов непосредственно в таблицах СУБД — это устаревшая практика, которая существенно усложняет администрирование информационной системы. База данных раздувается до огромных размеров, бэкапы делаются долго, а затраты на дорогостоящие производительные SSD-диски для СУБД растут.

Рекомендуется пересмотреть архитектуру хранения файлов в вашей компании:

  1. Внедрите механизм Хранения файлов в томах на диске. Для старых конфигураций типа УПП 1.3 на профильных ресурсах есть готовые доработки и расширения. Они позволяют перенаправить поток сохранения файлов из базы данных в сетевые папки или облачные объектные хранилища (например, S3-совместимые).
  2. Напишите или воспользуйтесь готовой обработкой, которая извлечет все двоичные данные из реквизита Хранилище справочника ХранилищеДополнительнойИнформации, запишет их в файлы на диске, а в базе данных заменит тяжелые двоичные данные на простые текстовые пути к этим файлам.

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

← На главную