При сопровождении и развитии систем на базе 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 для тех констант, которые включены в планы обмена. Выясним, как решить эту проблему программными и административными методами.
Это самый безопасный и «чистый» метод с точки зрения логики платформы. Если после повышения режима совместимости вы обнаружили, что таблицы изменений не создались, выполним следующие шаги:
F7), а затем вернуть их обратно (например, через сравнение/объединение с копией).F7). После успешного обновления вернем константы в состав плана обмена и снова обновим конфигурацию базы данных.Рассмотрим, что происходит в этот момент: при удалении объекта из состава плана обмена платформа инициирует процедуру очистки метаданных. При повторном включении в состав на новом режиме совместимости механизм реструктуризации уже «знает», что для каждой константы в текущем режиме должна существовать индивидуальная таблица _ConstChngR, и создает ее корректно.
Если база данных имеет огромный объем, и повторная реструктуризация через конфигуратор занимает слишком много времени, или если вы работаете в условиях, когда изменения метаданных крайне нежелательны, можно воспользоваться методом прямого создания таблиц на уровне СУБД (например, 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.
Одной из причин сбоя реструктуризации является наличие «старых» записей в общей таблице _ConstsChngR. Платформа пытается сопоставить данные старой структуры с новой, и если в данных есть противоречия (например, ссылки на несуществующие узлы), процесс создания новых таблиц может прерваться.
Проанализируем алгоритм правильного перехода:
Для Каждого ПланОбмена Из Метаданные.ПланыОбмена Цикл
Узлы = ПланыОбмена[ПланОбмена.Имя].Выбрать();
Пока Узлы.Следующий() Цикл
Если Узлы.Ссылка = ПланыОбмена[ПланОбмена.Имя].ЭтотУзел() Тогда
Продолжить;
КонецЕсли;
ПланыОбмена.УдалитьРегистрациюИзменений(Узлы.Ссылка, Метаданные.Константы);
КонецЦикла;
КонецЦикла;
После очистки регистрации выполнение обновления через F7 проходит гораздо стабильнее, так как платформе не нужно переносить данные из старой общей таблицы в десятки новых индивидуальных таблиц.
В процессе обсуждения данной проблемы часто упоминается утилита cnvdbfl.exe и версии 8.2.14 или 8.3.8. Важно понимать различие: эти версии относятся к формату файла базы данных (.1CD для файловых версий), а не к режиму совместимости конфигурации.
Повышение формата файла до 8.3.8 с помощью cnvdbfl.exe -c -f 8.3.8 позволяет базе использовать страницы размером 64 КБ и эффективно работать с таблицами более 4 ГБ, но это никак не решает проблему структуры таблиц констант. Разделение таблиц констант управляется исключительно свойством конфигурации «Режим совместимости».
Если вы столкнулись с тем, что после повышения режима совместимости до 8.3.13 и выше база данных «падает» при попытке записать константу, выполните следующие действия:
_ConstXXXX существует парная таблица _ConstChngRXXXX.Следуя этим рекомендациям, мы сможем безопасно перевести систему на современный режим работы, избавившись от избыточных блокировок в таблице констант и обеспечив стабильность работы механизмов обмена данными.