Почему файл 1sjourn.cdx увеличивается до 2 ГБ при обновлении конфигурации 1С 7.7 и как это исправить?

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

В практике администрирования и поддержки старых, но всё ещё активно эксплуатируемых баз данных на платформе 1С:Предприятие 7.7 в файловом режиме (формат DBF/CDX) специалисты нередко сталкиваются с крайне неприятным поведением системы. При сохранении изменений в конфигураторе, создании нового документа или запуске тестирования и исправления (ТиИ) процесс зависает на длительное время, а индексный файл общего журнала документов 1sjourn.cdx лавинообразно увеличивается в объеме, пока не достигает критического предела в 2 ГБ. После этого система аварийно завершает работу с ошибкой доступа к файлу: "Ошибка доступа к файлу new_stru/1sjourn.cdx" (Error #-70 или Error #-120).

Особенно парадоксально эта ситуация выглядит тогда, когда вся база данных весит не более 150–200 МБ, а сама таблица журнала документов 1sjourn.dbf занимает скромные 10–15 МБ. Каким образом индексный файл, предназначенный для ускорения поиска, может превышать размер индексируемых данных в сотни раз? Разберем подробно техническую природу этого сбоя, проанализируем внутреннее устройство файлового движка 1С 7.7 и рассмотрим практические способы решения этой проблемы.

Глубинная причина: архитектурные ограничения СУБД CodeBase

Файловая версия платформы 1С 7.7 использует в качестве встроенной СУБД сторонний движок CodeBase от компании Sequiter Software. Взаимодействие с базой данных на уровне платформы осуществляет библиотека dbeng32.dll. В архитектуре этого движка заложены жесткие лимиты на длину индексных ключей, которые напрямую связаны со структурой хранения сбалансированных деревьев (B-деревьев) индексов:

  1. Лимит в 117 байт: Для таблиц, объем которых превышает 30 000 записей (что для любого реального журнала документов является делом нескольких месяцев работы), максимальный физический размер одного индексного ключа не должен превышать 117 байт.
  2. Механизм сбоя при переполнении: Если длина ключа выходит за пределы 117 байт, алгоритм построения индекса в библиотеке dbeng32.dll дает критический сбой. Движок не может корректно выполнить балансировку и сжатие ветвей B-дерева. Вместо этого он уходит в бесконечный цикл дублирования пустых или некорректно сформированных узлов. Этот процесс вызывает лавинообразный (экспоненциальный) рост файла .cdx.
  3. Предел 2 ГБ: Рост продолжается до тех пор, пока файл не упирается в ограничение файловой системы или самого 32-битного движка DBF — ровно 2 147 483 648 байт (2 ГБ). После этого операционная система блокирует запись в файл, и платформа выдает ошибку доступа.

Проанализируем, как именно формируется проблемный индекс в системном журнале 1SJOURN, и почему под удар чаще всего попадают строковые реквизиты документов.

Как формируется индекс в таблице 1SJOURN

Таблица общего журнала документов 1SJOURN.DBF хранит метаданные всех существующих в базе документов (дата, время, тип, проведенность, уникальный идентификатор и значения общих реквизитов). Когда в конфигураторе у общего реквизита (например, "КомментарийДокумента" или "Содержание") взведены флаги «Сортировка» или «Отбор», система обязана построить по этому полю индексный тег в файле 1sjourn.cdx.

Для текстовых реквизитов в общем журнале индекс строится по сложному составному шаблону:

ИмяРеквизита(UPPER=X) + DATE + TIME + IDDOC

Рассмотрим детально длину составляющих этого составного ключа в байтах:

Если разработчик создает общий реквизит типа "Строка" неограниченной или просто большой длины (например, стандартные 255 символов) и включает по нему отбор, платформа зарезервирует под строковую часть ключа значительный объем байт. Суммарный размер ключа рассчитывается следующим образом:

Размер ключа = ДлинаСтроки + 8 (DATE) + 6 (TIME) + 9 (IDDOC)

Если длина строки равна 255, то размер ключа составит 255 + 23 = 278 байт, что более чем в два раза превышает критический порог в 117 байт. Даже если ограничить строку длиной в 100 символов, размер ключа составит 123 байта, что также является опасным значением при большом количестве документов в базе.

Пошаговая методика диагностики проблемы

Для того чтобы локализовать и устранить проблему, выполним несколько последовательных шагов.

Шаг 1. Анализ файла словаря данных 1Cv7.DD

В каталоге информационной базы найдем файл 1Cv7.DD. Откроем его с помощью любого текстового редактора (например, Notepad++). Нам необходимо найти описание структуры таблицы 1SJOURN и ее индексов. Найдем блок, описывающий индексы таблицы. Нам нужно обратить внимание на индексные теги, связанные с общими реквизитами. Пример проблемной записи в словаре данных выглядит так:


# Пример фрагмента файла 1Cv7.DD:
# Описание поля общего реквизита "Комментарий"
F=SP2239   |(P)КомментарийДокуме|C   |255   |0   
# Описание составного индекса по этому полю
I=VIA2239  |VIA2239             |0     |SP2239(UPPER=128),DATE,TIME,IDDOC

Здесь мы наглядно видим, что поле SP2239 имеет длину 255 символов, а индекс VIA2239 строится по формуле, использующей первые 128 символов этой строки в верхнем регистре совместно со служебными полями даты, времени и идентификатора документа. Очевидно, что длина ключа выходит за безопасные рамки.

Варианты решения проблемы

Рассмотрим несколько способов устранения этой ошибки — от самых простых и быстрых до архитектурно более сложных, но сохраняющих исходную функциональность системы.

Решение 1. Радикальное сокращение длины строкового реквизита

Если для бизнес-процессов не требуется хранить в реквизите отбора огромные тексты, самым простым и эффективным решением будет уменьшение длины реквизита в Конфигураторе.

  1. Откройте базу данных в режиме Конфигуратор.
  2. Найдите во вкладке "Общие" нужный реквизит (в нашем случае это общий реквизит документов "Комментарий" или аналогичный).
  3. Откройте его свойства и уменьшите длину строки до безопасного значения (рекомендуется от 50 до 70 символов). При длине 70 символов суммарный ключ составит 70 + 23 = 93 байта, что гарантированно укладывается в безопасный лимит 117 байт.
  4. Сохраните изменения. Платформа запустит реструктуризацию таблиц. Процесс пройдет быстро, а индексный файл 1sjourn.cdx больше не будет раздуваться.

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

Решение 2. Отключение индексации (сортировки и отбора) по длинному полю

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

  1. В Конфигураторе откройте свойства проблемного общего реквизита.
  2. Снимите галочки «Сортировка» и «Отбор по реквизиту».
  3. Сохраните конфигурацию.

После сохранения изменений платформа удалит описание этого индекса из файла словаря данных 1Cv7.DD и при очередной переиндексации полностью исключит его расчет. Файл 1sjourn.cdx вернется к нормальному компактному размеру.

Решение 3. Использование метода «Короткого ключа» (Хеширование)

Что делать, если бизнесу крайне необходим и длинный комментарий (255 символов), и возможность мгновенного поиска по нему в журналах? В таком случае программисты 1С 7.7 применяют обходную технологию разделения данных на "хранилище" и "поисковый индекс":

  1. Оставьте основной реквизит Комментарий длиной 255 символов, но отключите для него свойства «Сортировка» и «Отбор».
  2. Создайте новый общий реквизит документов, назовем его КомментарийДляПоиска, с типом "Строка", длиной 50 символов. Для этого реквизита включите свойства «Сортировка» и/или «Отбор».
  3. В модулях документов (или в глобальном модуле при записи документов) пропишите программное заполнение нового реквизита первыми 50 символами основного комментария.

Рассмотрим пример реализации программного заполнения поискового поля при записи документа:


// Процедура, вызываемая перед записью документа
Процедура ПриЗаписи()
    // Заполняем короткое индексируемое поле первыми символами длинного комментария
    Если ПустаяСтрока(Комментарий) = 0 Тогда
        КомментарийДляПоиска = Лев(СокрЛП(Комментарий), 50);
    Иначе
        КомментарийДляПоиска = "";
    КонецЕсли;
КонецПроцедуры

При таком подходе быстрый поиск и отборы в журналах будут осуществляться по полю КомментарийДляПоиска, что абсолютно безопасно для стабильности СУБД CodeBase, а детальный просмотр полной строки комментария будет выполняться из основного неиндексируемого поля Комментарий.

Решение 4. Переход на версию платформы с поддержкой SQL Server

Если база данных имеет большие объемы и активно развивается, лучшим стратегическим решением будет отказ от файлового режима DBF/CDX и переход на использование клиент-серверной версии 1С 7.7 под управлением Microsoft SQL Server.

В версии для MS SQL Server все индексы строятся механизмами промышленной СУБД. Ограничения на размер индексного ключа там несопоставимо выше (например, до 900 байт в старых версиях SQL Server и до 1700 байт в современных редакциях). При переходе на SQL-версию проблема с раздуванием файлов индексов исчезнет раз и навсегда, а общая стабильность информационной базы при многопользовательской работе существенно повысится.

← На главную