Почему файлы в УТ 11.4 снова хранятся в одной таблице и как решить проблемы с их переносом в тома

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

В современных редакциях конфигураций, базирующихся на Библиотеке стандартных подсистем (БСП) версии 2.4 и выше (например, УТ 11.4, ERP 2.4, КА 2.4), разработчики и администраторы часто сталкиваются с изменением логики хранения присоединенных файлов. Если раньше файлы «размазывались» по множеству справочников, то теперь мы наблюдаем их концентрацию в единых таблицах. Рассмотрим подробнее, зачем это было сделано, как теперь устроена архитектура и почему типовые механизмы переноса файлов на диск иногда дают сбой.

Архитектура хранения: разделение метаданных и двоичных данных

Проанализируем ситуацию: в старых версиях БСП для каждого объекта-владельца (например, справочник ДоговорыКонтрагентов) создавался отдельный справочник ДоговорыКонтрагентовПрисоединенныеФайлы, где в реквизите типа ХранилищеЗначения лежали сами данные. Теперь же архитектура стала гибридной.

Разберем, из чего она состоит:

  1. Справочники присоединенных файлов: Они по-прежнему создаются для каждого типа объекта-владельца. Однако теперь они играют роль исключительно хранилищ метаданных. Здесь фиксируется имя файла, автор, дата создания, ссылка на владельца и статус (где именно лежит файл — в базе или в томе). Самих двоичных данных в этих справочниках обычно нет.
  2. Регистр сведений ДвоичныеДанныеФайлов (или ПрисоединенныеФайлы в промежуточных версиях): Именно здесь теперь сосредоточены все BLOB-объекты (двоичные данные), если не включено хранение в томах на диске. Запись в регистре связана с элементом справочника присоединенных файлов.

Зачем это нужно? В первую очередь для оптимизации работы SQL-сервера. Когда данные файла лежат в той же таблице, что и его описание, любое обновление описания (например, изменение комментария или статуса) заставляет SQL-сервер перезаписывать всю огромную строку таблицы, включая тяжелые двоичные данные. Вынесение данных в отдельный регистр делает таблицу справочника «легкой», ускоряя чтение списка файлов и их модификацию.

Почему справочников присоединенных файлов всё еще много?

Может возникнуть логичный вопрос: если данные всё равно лежат в одном регистре, зачем плодить десятки справочников типа ЗаказКлиентаПрисоединенныеФайлы? Ответ кроется в механизме RLS (ограничение доступа на уровне записей).

Выясним причину: если бы метаданные всех файлов (сканы паспортов сотрудников, секретные спецификации номенклатуры, счета) лежали в одной таблице, системе пришлось бы при каждом запросе строить сложнейшие соединения для проверки прав пользователя на объект-владелец. Разделение справочников позволяет:

Разберемся с механизмом «Очистка ненужных файлов»

Часто возникает непонимание: что именно удаляет эта регламентная операция? Проанализируем алгоритм работы подсистемы очистки. Она ищет следующие категории данных:

Проблема некорректного переноса файлов в тома

Рассмотрим ситуацию, описанную многими разработчиками: в базе 12 Гб файлов, а типовая обработка «Перенос файлов в тома» видит лишь 20-30 Мб. Почему так происходит? Посмотрим на пример кода и логику работы БСП.

Проанализируем основные причины «невидимости» файлов для обработки:

  1. Определяемые типы: Обработка ориентируется на ОпределяемыйТип.ПрисоединенныйФайл. Если при разработке или кастомизации новый справочник файлов не был включен в этот тип, система его просто проигнорирует.
  2. Тип хранения в карточке: Обработка проверяет реквизит ТипХраненияФайла. Если из-за сбоя или некорректного импорта данных в карточке стоит «В томах на диске», но файла там нет (он фактически остался в базе), обработка его не тронет.
  3. Ошибки в запросах БСП: В некоторых версиях (например, 11.3, 11.4) типовой код функции РазмерВерсийВБазе() или механизмов выборки данных содержит логические ошибки при использовании ОБЪЕДИНИТЬ ВСЕ в цикле.

Посмотрим на пример функции, которая может работать некорректно в некоторых релизах из-за специфики обхода метаданных:


&НаСервере
Функция РазмерВерсийВБазе()
    УстановитьПривилегированныйРежим(Истина);
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |    ЕСТЬNULL(СУММА(ВерсииФайлов.Размер), 0) КАК Размер
    |ИЗ
    |    Справочник.ВерсииФайлов КАК ВерсииФайлов
    |ГДЕ
    |    ВерсииФайлов.ТипХраненияФайла = Значение(Перечисление.ТипыХраненияФайлов.ВИнформационнойБазе)";
    
    Для Каждого ТипСправочника Из Метаданные.ОпределяемыеТипы.ПрисоединенныйФайл.Тип.Типы() Цикл
        ПолноеИмяСправочника = Метаданные.НайтиПоТипу(ТипСправочника).ПолноеИмя();
        Если ПолноеИмяСправочника <> "Справочник.Файлы" И ПолноеИмяСправочника <> "Справочник.ВерсииФайлов" Тогда
            Запрос.Текст = Запрос.Текст + 
            "
            |ОБЪЕДИНИТЬ ВСЕ
            |
            |ВЫБРАТЬ
            |    ЕСТЬNULL(СУММА(ВерсииФайлов.Размер), 0) КАК Размер
            |ИЗ
            |    " + ПолноеИмяСправочника + " КАК ВерсииФайлов
            |ГДЕ
            |    ВерсииФайлов.ТипХраненияФайла = ЗНАЧЕНИЕ(Перечисление.ТипыХраненияФайлов.ВИнформационнойБазе)";
        КонецЕсли;
    КонецЦикла;
    
    Результат = Запрос.Выполнить();
    // Ошибка может быть здесь: если результат содержит много строк (по одной на справочник),
    // а код выбирает только первую строку через Выборка.Следующий()
    Выборка = Результат.Выбрать();
    ОбщийРазмер = 0;
    Пока Выборка.Следующий() Цикл
        ОбщийРазмер = ОбщийРазмер + Выборка.Размер;
    КонецЦикла;
    Возврат ОбщийРазмер;
КонецФункции

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

Рекомендации по безопасному переносу

Если вы столкнулись с тем, что типовая обработка не видит файлы, выполните следующие шаги:

  1. Проверьте 64-битность сервера: Если у вас 32-разрядный сервер 1С, при попытке переноса файла размером более 120 Мб процесс может аварийно завершиться из-за нехватки памяти. Для работы с большими объемами BLOB-данных настоятельно рекомендуется 64-битный rphost.
  2. Доработайте запрос выбора данных: Убедитесь, что алгоритм учитывает все справочники из определяемого типа ПрисоединенныйФайл и корректно суммирует их данные, а не берет только первую запись.
  3. Синхронизация статусов: Перед переносом стоит запустить проверку целостности, которая сопоставит наличие записей в регистре ДвоичныеДанныеФайлов с реквизитом ТипХраненияФайла в справочниках метаданных.

Таким образом, переход к единому регистру хранения двоичных данных — это осознанный шаг разработчиков 1С для повышения производительности SQL-запросов и упрощения управления версиями. Несмотря на возможные «детские болезни» типовых обработок переноса, данная архитектура является более современной и эффективной для высоконагруженных систем.

← На главную