Почему не создаются таблицы изменений констант при повышении режима совместимости до 8.3.13 и как это исправить?

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

При сопровождении и развитии систем на базе 1С:Предприятие 8 программисты часто сталкиваются с необходимостью повышения режима совместимости конфигурации. Это позволяет использовать новые возможности платформы и повысить производительность. Однако переход с версий 8.2 (или низких режимов совместимости 8.3) на актуальные релизы платформы (8.3.13, 8.3.14 и выше) скрывает в себе серьезную проблему, связанную с изменением архитектуры хранения констант.

Разберем ситуацию: вы успешно обновили конфигурацию базы данных (нажали F7), платформа не выдала ошибок, но при первой же попытке записи любой константы система аварийно завершается с критической ошибкой SBL или сообщением об отсутствии таблицы в СУБД. Проанализируем, почему это происходит и как правильно выполнить реструктуризацию.

Изменение архитектуры хранения констант

Для начала рассмотрим, как менялась логика хранения данных в 1С. В старых версиях (режимы совместимости до 8.2.13 включительно) все константы хранились в одной общей таблице _Consts, а их изменения для планов обмена фиксировались в одной таблице _ConstsChngR. Это создавало серьезные проблемы с блокировками: при записи одной константы блокировалась вся таблица, что мешало параллельной работе пользователей.

Начиная с режима совместимости 8.3.12 (и особенно явно это проявилось в релизах платформы 8.3.13+), фирма «1С» перешла к раздельному хранению. Теперь для каждой константы создается собственная таблица (например, _Const22137) и собственная таблица регистрации изменений (например, _ConstChngR22257).

Проблема заключается в том, что при «скачке» через несколько версий совместимости (например, с 8.2.13 сразу на 8.3.14), платформа создает физические таблицы для самих констант, но по какой-то причине «забывает» создать таблицы регистрации изменений _ConstChngR для тех констант, которые включены в планы обмена. Выясним, как решить эту проблему программными и административными методами.

Способ 1: Пересоздание состава планов обмена (Рекомендуемый)

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

  1. Откроем конфигуратор и найдем планы обмена, в состав которых входят проблемные константы.
  2. Вариант А (радикальный): Если планов обмена немного и в них нет сложной настройки узлов, можно временно удалить эти планы обмена из конфигурации, сохранить изменения (F7), а затем вернуть их обратно (например, через сравнение/объединение с копией).
  3. Вариант Б (мягкий): Зайдем в состав каждого плана обмена. Для всех констант изменим свойство «Авторегистрация» на «Запретить» и уберем их из состава. Применим изменения (F7). После успешного обновления вернем константы в состав плана обмена и снова обновим конфигурацию базы данных.

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

Способ 2: Использование SQL-скрипта для создания недостающих таблиц

Если база данных имеет огромный объем, и повторная реструктуризация через конфигуратор занимает слишком много времени, или если вы работаете в условиях, когда изменения метаданных крайне нежелательны, можно воспользоваться методом прямого создания таблиц на уровне СУБД (например, MS SQL Server).

Внимание: Этот метод является «костылем» и должен применяться только опытными администраторами баз данных после создания резервной копии. Проанализируем пример скрипта, который находит таблицы констант, для которых отсутствуют таблицы изменений, и создает их:


DECLARE @TableName AS varChar(200)
DECLARE myCur CURSOR FOR 
SELECT LEFT(TABLE_NAME,6)+'ChngR'+RIGHT(TABLE_NAME,LEN(TABLE_NAME)-6) 
FROM [INFORMATION_SCHEMA].[TABLES]
WHERE LEFT(TABLE_NAME,6) = '_Const'
AND LEFT(TABLE_NAME,11) <> '_ConstChngR'
AND LEFT(TABLE_NAME,6)+'ChngR'+RIGHT(TABLE_NAME,LEN(TABLE_NAME)-6) NOT IN (SELECT TABLE_NAME FROM [INFORMATION_SCHEMA].[TABLES])

OPEN myCur
FETCH NEXT FROM myCur INTO @TableName  
WHILE @@FETCH_STATUS=0 BEGIN  
    EXEC ('CREATE TABLE [dbo].['+@TableName+'](
    [_NodeTRef] [binary](4) NOT NULL,
    [_NodeRRef] [binary](16) NOT NULL,
    [_MessageNo] [numeric](10, 0) NULL,
    [_ConstID] [binary](16) NOT NULL
    ) ON [PRIMARY]')
    
    -- Не забудьте про индексы, иначе обмен будет работать крайне медленно
    EXEC ('CREATE CLUSTERED INDEX [PK_'+@TableName+'] ON [dbo].['+@TableName+'] ([_NodeTRef], [_NodeRRef], [_ConstID])')
    
    FETCH NEXT FROM myCur INTO @TableName  
END  
CLOSE myCur
DEALLOCATE myCur

Посмотрим на структуру создаваемой таблицы. Поля _NodeTRef и _NodeRRef отвечают за ссылку на узел плана обмена, _MessageNo хранит номер сообщения, а _ConstID — идентификатор самой константы. Создание этих таблиц вручную позволит 1С выполнять запись без критических ошибок SBL.

Способ 3: Очистка регистрации изменений перед обновлением

Одной из причин сбоя реструктуризации является наличие «старых» записей в общей таблице _ConstsChngR. Платформа пытается сопоставить данные старой структуры с новой, и если в данных есть противоречия (например, ссылки на несуществующие узлы), процесс создания новых таблиц может прерваться.

Проанализируем алгоритм правильного перехода:

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

Для Каждого ПланОбмена Из Метаданные.ПланыОбмена Цикл
    Узлы = ПланыОбмена[ПланОбмена.Имя].Выбрать();
    Пока Узлы.Следующий() Цикл
        Если Узлы.Ссылка = ПланыОбмена[ПланОбмена.Имя].ЭтотУзел() Тогда
            Продолжить;
        КонецЕсли;
        ПланыОбмена.УдалитьРегистрациюИзменений(Узлы.Ссылка, Метаданные.Константы);
    КонецЦикла;
КонецЦикла;

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

Нюансы с утилитой cnvdbfl.exe

В процессе обсуждения данной проблемы часто упоминается утилита cnvdbfl.exe и версии 8.2.14 или 8.3.8. Важно понимать различие: эти версии относятся к формату файла базы данных (.1CD для файловых версий), а не к режиму совместимости конфигурации.

Повышение формата файла до 8.3.8 с помощью cnvdbfl.exe -c -f 8.3.8 позволяет базе использовать страницы размером 64 КБ и эффективно работать с таблицами более 4 ГБ, но это никак не решает проблему структуры таблиц констант. Разделение таблиц констант управляется исключительно свойством конфигурации «Режим совместимости».

Резюме

Если вы столкнулись с тем, что после повышения режима совместимости до 8.3.13 и выше база данных «падает» при попытке записать константу, выполните следующие действия:

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

← На главную