При администрировании и обновлении крупных баз данных на платформе 1С:Предприятие 8 специалисты нередко сталкиваются с коварной системной ошибкой. В процессе проведения Тестирования и Исправления (ТиИ) база данных аварийно завершает работу с сообщением: «Нарушено ограничения PRIMARY KEY. Не удается вставить повторяющийся ключ в объект dbo._tmpRCT». При этом попытка провести некоторые документы (например, больничные листы или ведомости) вызывает сопутствующий сбой: «Ошибка SDBL: Тип поля 30:... несовместим с типом поля Fld...».
В этой статье мы подробно разберем природу возникновения этих взаимосвязанных ошибок, выясним, почему стандартное тестирование СУБД не решает проблему, и изучим четыре проверенных практических метода исправления структуры базы данных.
Для начала проанализируем симптомы и сопоставим данные из логов СУБД и платформы 1С. В сообщении об ошибке фигурируют два ключевых значения:
0x0000001e.Тип поля 30:....Если перевести шестнадцатеричное число 0x1e в десятичную систему счисления, мы получим ровно 30. Это указывает на то, что обе ошибки вызваны одной и той же фундаментальной проблемой: конфликтом и дублированием внутренних идентификаторов типов объектов метаданных.
Внутри платформы 1С каждому объекту метаданных (справочнику, документу, плану видов характеристик) сопоставляется уникальный целочисленный код (ID типа). Когда платформа выполняет операцию проверки логической и ссылочной целостности в рамках ТИИ, на стороне СУБД временно создается служебная таблица dbo._tmpRCT (Referential Consistency Table — таблица ссылочной согласованности). В эту таблицу выгружаются уникальные ID типов для верификации связей. Первичным ключом этой таблицы является сам идентификатор типа.
Если в базе данных по какой-то причине два разных объекта получили одинаковый внутренний ID (в данном случае 30), СУБД пытается дважды вставить значение 0x0000001e в поле первичного ключа таблицы _tmpRCT, что закономерно вызывает ошибку СУБД PRIMARY KEY constraint violation.
Рассмотрим механизм выделения идентификаторов платформой. Данный сбой чаще всего происходит по следующему сценарию:
.bak в MS SQL или дамп PostgreSQL) средствами самой СУБД поверх существующей базы.rmngr).rmngr сохраняет в своей оперативной памяти старый кэш счетчиков идентификаторов таблиц для этой базы данных.30).Начиная с версии платформы 8.3.15, этот конфликт отслеживается системой более явно, и при попытке обновить конфигурацию СУБД выдает ошибку: «Ошибка SDBL: Для одного ссылочного кода существует более одной таблицы в базе данных».
---
Ниже описаны четыре эффективных способа исправления структуры данных. Перед выполнением любых операций обязательно создайте резервную копию базы данных средствами СУБД и остановите сеансы пользователей.
Это наиболее щадящий и простой метод, позволяющий заставить платформу 1С самостоятельно перестроить проблемную таблицу СУБД и присвоить ей новый уникальный код.
Для начала нам необходимо определить, какие именно объекты метаданных используют конфликтующий идентификатор 30. Для этого мы можем воспользоваться программным кодом для анализа структуры хранения данных:
ТаблицаСтруктуры = ПолучитьСтруктуруХраненияБазыДанных();
Для Каждого Строка Из ТаблицаСтруктуры Цикл
Если Найти(Строка.ИмяТаблицыХранения, "30") > 0 Тогда
Сообщить("Конфликтный объект метаданных: " + Строка.Метаданные);
КонецЕсли;
КонецЦикла;
Предположим, анализ показал, что код 30 одновременно назначен предопределенному справочнику и новому созданному документу. Для исправления ситуации выполним следующие шаги по шагам:
ВременныйБулево и типом Булево).ВременныйБулево и повторно обновим конфигурацию (клавиша F7).Важное примечание: Данный способ не сработает напрямую, если конфликтующим объектом является перечисление (ПеречислениеСсылка), поскольку структура хранения перечислений в СУБД отличается и добавить реквизиты к ним в конфигураторе невозможно.
Создание начального образа РИБ — это мощный системный метод очистки и перегенерации внутренней структуры хранения. При создании подчиненного узла платформа заново формирует всю схему таблиц и распределяет новые идентификаторы «с нуля», полностью исключая дублирование.
Выполним процедуру по шагам:
ПланыОбмена.УстановитьГлавныйУзел(Неопределено);
После этого базу можно использовать в качестве основной рабочей базы данных.
Если база данных имеет огромный объем и создание образа РИБ занимает слишком много времени, можно прибегнуть к исправлению метаданных непосредственно в СУБД с помощью специализированных обработок со специализированных ресурсов (например, Инфостарт).
Подобные обработки выполняют следующие действия под управлением администратора:
Config.Params и Config), прописывая корректный свободный ID для переименованной таблицы.Внимание! Использование этого метода требует высокой квалификации и понимания внутренней структуры хранения данных 1С на уровне СУБД. Не забудьте сделать резервную копию перед запуском подобных утилит.
Если в процессе анализа выяснилось, что конфликт возник из-за объекта метаданных, который был добавлен в конфигурацию недавно и еще не успел накопиться в транзакциях и пользовательских данных, самым быстрым решением будет его пересоздание:
30 для старого объекта.rmngr), чтобы очистить кэш идентификаторов в оперативной памяти сервера приложений.Чтобы больше никогда не сталкиваться с ошибкой неуникальности ссылок в _tmpRCT и сбоями SDBL, строго придерживайтесь важного правила администрирования: при любом восстановлении базы данных из бэкапа средствами СУБД всегда производите перезапуск службы кластера 1С (сервиса rphost/rmngr). Это гарантирует очистку кэша идентификаторов метаданных и предотвратит появление дублирующих кодов при последующей разработке и обновлении конфигураций.