При работе с файловыми базами данных формата DBF в платформе 1С:Предприятие 7.7 администраторы и разработчики часто сталкиваются с фундаментальным ограничением СУБД CodeBase. Максимальный физический размер любого файла таблицы (с расширением .dbf) или файла индексов (.cdx) составляет ровно 2 Гб (2 147 483 647 байт). Превышение этого лимита приводит к аварийному завершению работы системы, ошибкам записи и фатальным сбоям СУБД.
Особенно уязвимым к росту является файл 1SBLOB.dbf. В этой таблице хранятся так называемые «длинные строки» — реквизиты справочников и документов с типом «Строка неограниченной длины». Из-за специфики хранения информации в формате DBF, где данные режутся на фиксированные блоки, этот файл может раздуваться со стремительной скоростью. В этой статье мы подробно разберем, как проанализировать структуру 1SBLOB.dbf, выявить конкретные объекты-виновники роста, корректно очистить базу и перевести ресурсоемкие модули (такие как Контур.EDI) на внешнее хранилище.
Для начала проанализируем внутреннее устройство таблицы 1SBLOB.dbf. Каждая длинная строка в системе 1С 7.7 нарезается небольшими блоками по 80 символов. Физически в файле базы данных запись состоит из следующих полей:
FIELDID — идентификатор реквизита (длина 4 символа).OBJID — уникальный идентификатор объекта-владельца строки (справочника или документа, длина 9 символов).BLOCKNO — порядковый номер блока (числовое поле).BLOCK — непосредственно текстовое содержимое блока (80 символов).Каждая физическая запись в файле занимает около 97 байт. Если пользователь сохраняет длинный текст (например, XML-пакет обмена EDI или лог выгрузки Меркурия), система создает десятки и сотни таких блоков. Ситуация усложняется тем, что при перезаписи или очистке реквизитов старые блоки в файле 1SBLOB.dbf не удаляются физически, а лишь помечаются как неиспользуемые. Без регулярного сжатия таблицы файл стремительно приближается к критическому порогу.
Если база данных уже находится в критическом состоянии, нам необходим быстрый инструмент для анализа. Запускать стандартный перебор всех объектов метаданных штатными средствами 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. Они сохраняют входящие и исходящие XML-пакеты непосредственно в реквизиты справочников базы 1С. Выясним, как правильно решить эту проблему поэтапно.
Не пытайтесь удалять записи напрямую из DBF-файлов сторонними утилитами — это приведет к нарушению ссылочной целостности базы данных. Разработчики Контур поставляют готовую служебную обработку для безопасного удаления истории.
КонтурEDI_ФормаСервис_УдалениеСообщений.ert.КонтурEDI_Сообщения.После удаления старых сообщений физический размер файла 1SBLOB.dbf на диске останется прежним. Чтобы вернуть неиспользуемое дисковое пространство операционной системе, необходимо выполнить реорганизацию файлов базы данных:
Альтернативный и еще более надежный способ физического сжатия — выполнение полной выгрузки базы данных в формат .zip (через меню «Администрирование» -> «Выгрузка данных») и последующей ее загрузки в пустую папку («Администрирование» -> «Загрузка данных»).
Чтобы раз и навсегда предотвратить повторный рост файла 1SBLOB.dbf, необходимо отказаться от хранения тяжелых XML-сообщений внутри структуры 1С 7.7. Начиная с релиза интеграционного модуля 1.03.001.38, Контур добавил штатную возможность выноса длинных строк во внешнюю базу данных SQLite.
Для активации этой возможности выполните следующие действия:
.db. Согласитесь на выполнение этой операции.После этого все новые цепочки обмена сообщениями будут записываться в отдельный внешний файл базы данных SQLite, который не имеет лимита в 2 Гб и работает в разы быстрее устаревшего движка CodeBase.
Если ваша база экстренно заблокирована из-за превышения лимита в 2 Гб, а провести очистку прямо сейчас нет возможности, рассмотрите следующие варианты:
Регулярно проводите мониторинг размера файлов вашей базы данных, настраивайте регламентную очистку интеграционных логов и используйте современные внешние хранилища для обмена данными. Это гарантирует стабильную и быструю работу вашей системы на платформе 1С 7.7.