Как решить проблему критического роста файла 1SBLOB.dbf до предела 2 Гб в 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При работе с файловыми базами данных формата DBF в платформе 1С:Предприятие 7.7 администраторы и разработчики часто сталкиваются с фундаментальным ограничением СУБД CodeBase. Максимальный физический размер любого файла таблицы (с расширением .dbf) или файла индексов (.cdx) составляет ровно 2 Гб (2 147 483 647 байт). Превышение этого лимита приводит к аварийному завершению работы системы, ошибкам записи и фатальным сбоям СУБД.

Особенно уязвимым к росту является файл 1SBLOB.dbf. В этой таблице хранятся так называемые «длинные строки» — реквизиты справочников и документов с типом «Строка неограниченной длины». Из-за специфики хранения информации в формате DBF, где данные режутся на фиксированные блоки, этот файл может раздуваться со стремительной скоростью. В этой статье мы подробно разберем, как проанализировать структуру 1SBLOB.dbf, выявить конкретные объекты-виновники роста, корректно очистить базу и перевести ресурсоемкие модули (такие как Контур.EDI) на внешнее хранилище.

Выясняем причину: почему растет 1SBLOB.dbf?

Для начала проанализируем внутреннее устройство таблицы 1SBLOB.dbf. Каждая длинная строка в системе 1С 7.7 нарезается небольшими блоками по 80 символов. Физически в файле базы данных запись состоит из следующих полей:

  1. FIELDID — идентификатор реквизита (длина 4 символа).
  2. OBJID — уникальный идентификатор объекта-владельца строки (справочника или документа, длина 9 символов).
  3. BLOCKNO — порядковый номер блока (числовое поле).
  4. BLOCK — непосредственно текстовое содержимое блока (80 символов).

Каждая физическая запись в файле занимает около 97 байт. Если пользователь сохраняет длинный текст (например, XML-пакет обмена EDI или лог выгрузки Меркурия), система создает десятки и сотни таких блоков. Ситуация усложняется тем, что при перезаписи или очистке реквизитов старые блоки в файле 1SBLOB.dbf не удаляются физически, а лишь помечаются как неиспользуемые. Без регулярного сжатия таблицы файл стремительно приближается к критическому порогу.

Диагностика: быстрый поиск объектов-виновников с помощью 1С++ и 1SQLite

Если база данных уже находится в критическом состоянии, нам необходим быстрый инструмент для анализа. Запускать стандартный перебор всех объектов метаданных штатными средствами 1С крайне неэффективно — на больших базах это может занять несколько дней. Намного правильнее использовать возможности внешних компонент 1cpp.dll и 1sqlite.dll для прямого выполнения SQL-запроса к DBF-таблицам прямо в оперативной памяти.

Рассмотрим готовый эффективный алгоритм, который за несколько секунд проанализирует структуру 1SBLOB.dbf, сопоставит физические идентификаторы полей FIELDID с объектами метаданных 1С и выведет долю вклада каждого реквизита в общий объем файла:


Процедура Сформировать()
    тз = СоздатьОбъект("ТаблицаЗначений");
    тз.НоваяКолонка("Ид", "Число");
    тз.НоваяКолонка("Представление", "Строка");
    
    мдв = СоздатьОбъект("MetaDataWork");
    
    // Анализируем длинные строки в справочниках
    Для НомерСправочника = 1 По Метаданные.Справочник() Цикл
        Справочник = Метаданные.Справочник(НомерСправочника);
        Для НомерРеквизита = 1 По Справочник.Реквизит() Цикл 
            Реквизит = Справочник.Реквизит(НомерРеквизита);
            Если (Реквизит.Тип = "Строка") И (Реквизит.Длина = 0) Тогда
                тз.НоваяСтрока();
                тз.Ид = мдв.ИДОбъекта(Реквизит);
                тз.Представление = "Справочник." + Справочник.Идентификатор + "." + Реквизит.Идентификатор;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    
    // Анализируем реквизиты шапки документов
    Для НомерДокумента = 1 По Метаданные.Документ() Цикл
        Документ = Метаданные.Документ(НомерДокумента);
        Для НомерРеквизита = 1 По Документ.РеквизитШапки() Цикл 
            Реквизит = Документ.РеквизитШапки(НомерРеквизита);
            Если (Реквизит.Тип = "Строка") И (Реквизит.Длина = 0) Тогда
                тз.НоваяСтрока();
                тз.Ид = мдв.ИДОбъекта(Реквизит);
                тз.Представление = "Документ." + Документ.Идентификатор + "." + Реквизит.Идентификатор;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    
    // Анализируем общие реквизиты документов
    Для НомерРеквизита = 1 По Метаданные.ОбщийРеквизитДокумента() Цикл 
        Реквизит = Метаданные.ОбщийРеквизитДокумента(НомерРеквизита);
        Если (Реквизит.Тип = "Строка") И (Реквизит.Длина = 0) Тогда
            тз.НоваяСтрока();
            тз.Ид = мдв.ИДОбъекта(Реквизит);
            тз.Представление = "ОбщийРеквизитДокумента." + Реквизит.Идентификатор;
        КонецЕсли;
    КонецЦикла;
    
    // Инициализируем SQLite базу данных в оперативной памяти
    База = СоздатьОбъект("SQLiteBase");
    База.Открыть(":memory:");
    База.УложитьТЗ(тз, "vt");
    
    // Выполняем прямой запрос к физической таблице 1SBLOB
    Запрос = База.НовыйЗапрос();
    тзРезультат = Запрос.ВыполнитьЗапрос("
    |SELECT
    |   Представление,
    |   count as [КоличествоБлоков],
    |   count * 97 as [ОбъемБайт]
    |FROM 
    |   (SELECT count(*) count, fieldid FROM __1S_BLOB GROUP BY FIELDID) as blob
    |JOIN vt ON blob.fieldid = id2str(vt.Ид, 4)
    |ORDER BY count DESC
    |");
    
    // Выводим полученную таблицу результатов
    глПросмотрТСЗ(тзРезультат);
КонецПроцедуры

Этот скрипт мгновенно сопоставляет захешированные четырехсимвольные коды полей FIELDID с реальными именами метаданных в конфигурации и выводит точный объем занимаемой памяти по каждому реквизиту. Обычно лидирующие позиции в этом отчете занимают логи интеграционных модулей (EDI-сообщения, логи взаимодействия с ГИС Меркурий, история обмена с сайтами).

Решение проблемы на примере Контур.EDI

Чаще всего виновником взрывного роста выступают модули электронного документооборота, такие как Контур.EDI. Они сохраняют входящие и исходящие XML-пакеты непосредственно в реквизиты справочников базы 1С. Выясним, как правильно решить эту проблему поэтапно.

Шаг 1. Безопасное удаление устаревших данных

Не пытайтесь удалять записи напрямую из DBF-файлов сторонними утилитами — это приведет к нарушению ссылочной целостности базы данных. Разработчики Контур поставляют готовую служебную обработку для безопасного удаления истории.

  1. Найдите в каталоге вашей базы данных (или в папке с внешними обработками) файл КонтурEDI_ФормаСервис_УдалениеСообщений.ert.
  2. Запустите обработку в режиме предприятия.
  3. Укажите период для удаления. Рекомендуется оставлять данные только за текущий год (или последние 1-3 месяца, в зависимости от интенсивности вашего документооборота).
  4. Запустите процесс очистки. Обработка корректно очистит ссылки внутри справочника КонтурEDI_Сообщения.

Шаг 2. Физическое сжатие базы (Упаковка таблиц)

После удаления старых сообщений физический размер файла 1SBLOB.dbf на диске останется прежним. Чтобы вернуть неиспользуемое дисковое пространство операционной системе, необходимо выполнить реорганизацию файлов базы данных:

  1. Попросите всех пользователей выйти из базы 1С.
  2. Запустите конфигуратор в монопольном режиме.
  3. Перейдите в меню «Администрирование» -> «Тестирование и исправление ИБ».
  4. Установите флажок напротив пункта «Упаковка таблиц книг» (в некоторых релизах называется «Упаковка таблиц»).
  5. Нажмите кнопку «Выполнить». В процессе выполнения платформа пересоберет DBF-файлы, полностью исключив из них удаленные записи и неиспользуемые пустые блоки.

Альтернативный и еще более надежный способ физического сжатия — выполнение полной выгрузки базы данных в формат .zip (через меню «Администрирование» -> «Выгрузка данных») и последующей ее загрузки в пустую папку («Администрирование» -> «Загрузка данных»).

Шаг 3. Переход на внешнее хранилище SQLite (Кардинальное решение)

Чтобы раз и навсегда предотвратить повторный рост файла 1SBLOB.dbf, необходимо отказаться от хранения тяжелых XML-сообщений внутри структуры 1С 7.7. Начиная с релиза интеграционного модуля 1.03.001.38, Контур добавил штатную возможность выноса длинных строк во внешнюю базу данных SQLite.

Для активации этой возможности выполните следующие действия:

  1. Обновите ваш модуль Контур.EDI до актуальной версии (рекомендуется версия 1.7.3 или новее). Если у вас сильно измененная нетиповая конфигурация (например, переписанная под ваши нужды «Бухгалтерия 4.5»), обратитесь в техническую поддержку Контура для получения актуального релиза и аккуратно перенесите свои доработки.
  2. Откройте модуль Контур.EDI в режиме предприятия.
  3. Перейдите по пути: «Настройки» -> «Настройки модуля» -> вкладка «Прочие настройки».
  4. Найдите параметр «Место хранения сообщений» и переключите его в режим «Во внешней базе данных SQLite».
  5. Система предложит вам автоматически перенести ранее накопленные сообщения из 1С в созданный внешний файл базы данных .db. Согласитесь на выполнение этой операции.

После этого все новые цепочки обмена сообщениями будут записываться в отдельный внешний файл базы данных SQLite, который не имеет лимита в 2 Гб и работает в разы быстрее устаревшего движка CodeBase.

Альтернативные и временные меры обхода лимита

Если ваша база экстренно заблокирована из-за превышения лимита в 2 Гб, а провести очистку прямо сейчас нет возможности, рассмотрите следующие варианты:

Регулярно проводите мониторинг размера файлов вашей базы данных, настраивайте регламентную очистку интеграционных логов и используйте современные внешние хранилища для обмена данными. Это гарантирует стабильную и быструю работу вашей системы на платформе 1С 7.7.

← На главную