Как исправить ошибку «Попытка вставки неуникального значения в уникальный индекс» при реструктуризации базы 1С?

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

При обновлении конфигурации или выполнении реструктуризации базы данных администраторы и программисты 1С часто сталкиваются с критической ошибкой SQL: «Попытка вставки неуникального значения в уникальный индекс». Особенно неприятно, когда эта ошибка возникает на этапе создания временных таблиц (индекс с суффиксом NG), а стандартные средства вроде «Тестирования и исправления» (ТиИ) не показывают никаких проблем. Рассмотрим детально, почему это происходит и как вылечить базу данных, если обычные методы бессильны.

Выясняем причину: почему платформа «видит» дубликаты?

Проанализируем ситуацию. Ошибка вида CREATE UNIQUE INDEX прервано, поскольку обнаружен повторяющийся ключ для объекта с именем "dbo._DocumentJournalXXXXXNG" означает, что в процессе реструктуризации 1С создает новую версию таблицы журнала документов (с суффиксом NG — New Generation) и пытается перенести туда данные из старой таблицы. В процессе переноса платформа обнаруживает, что две записи имеют одинаковый набор полей, входящих в уникальный индекс (обычно это ссылка на документ _DocumentRRef и тип документа).

Одной из ключевых причин в современных версиях платформы (начиная с 8.3.16) является официально признанная ошибка 10221419. Она проявляется в тех случаях, когда документ включен в план обмена в расширении конфигурации, и при этом данный документ входит в состав журнала документов в основной конфигурации. В момент реструктуризации происходит конфликт метаданных, и система пытается дважды зарегистрировать одну и ту же запись в журнале.

Шаг 1: Идентификация проблемного объекта

Прежде чем приступать к «лечению», нам нужно точно понять, какой документ вызывает сбой. Посмотрим на значение ключа из текста ошибки: (0, 0x00000265, 0x80e2001e674d523c11e4d36c6e75dd82).

  1. Первое число (0) — это разделитель области данных (в большинстве случаев будет 0).
  2. Второй блок (0x00000265) — это внутренний идентификатор типа объекта (Metadata ID).
  3. Третий блок (0x80e2...) — это уникальный идентификатор (GUID) конкретной записи документа.

Чтобы найти этот документ в базе 1С, выполним в консоли запросов простой запрос, подставив полученный GUID:


ВЫБРАТЬ
    Ссылка
ИЗ
    Документ.СчетНаОплатуПокупателю // Замените на предполагаемый тип документа
ГДЕ
    Ссылка = ССЫЛКА(Документ.СчетНаОплатуПокупателю, "80e2001e-674d-523c-11e4-d36c6e75dd82")

Если тип документа неизвестен, его можно вычислить по имени таблицы _DocumentJournalXXXXX в SQL, посмотрев структуру таблиц в 1С (через консоль запросов или обработку «Структура таблиц БД»).

Шаг 2: Диагностика на уровне SQL

Проверим таблицу журнала на наличие физических дублей, которые «не видит» 1С. Для этого выполним запрос в консоли SQL Server Management Studio (SSMS):


SELECT _DocumentRRef, COUNT(*)
FROM _DocumentJournal61795 // Имя вашей таблицы из ошибки
GROUP BY _DocumentRRef
HAVING COUNT(*) > 1

Если запрос вернул строки — значит, в журнале действительно есть «зависшие» записи-сироты. Если запрос пуст, значит проблема носит логический характер и возникает именно в момент работы механизмов реструктуризации платформы.

Шаг 3: Основной алгоритм решения (Метод очистки через XML)

Если простое удаление расширений не помогает, применим радикальный, но проверенный способ «перезагрузки» данных проблемного типа документа. Разберем его по шагам:

  1. Исключение из журналов: В конфигураторе найдем все журналы, в которые входит проблемный тип документа (например, «Счет на оплату покупателю»), и временно снимем флажки включения этого документа в данные журналы.
  2. Первая реструктуризация: Выполним обновление конфигурации базы данных. На этом этапе платформа должна успешно удалить записи о счетах из таблиц журналов в SQL.
  3. Выгрузка данных: С помощью обработки «Выгрузка загрузка данных XML» выгрузим в файл все документы данного типа (и только их).
  4. Очистка в SQL: Чтобы полностью исключить влияние «мусора», очистим основную таблицу документов в SQL (внимание: делайте это только после успешной выгрузки в XML и при наличии бэкапа!): TRUNCATE TABLE _Document255; -- Имя таблицы вашего документа
  5. Возврат метаданных: В конфигураторе вернем настройки журналов в исходное состояние (снова включим документ в журналы).
  6. Вторая реструктуризация: Снова обновим конфигурацию базы данных. Теперь таблицы журналов и документов девственно чисты, и ошибок индекса быть не должно.
  7. Загрузка данных: С помощью той же обработки загрузим документы из созданного ранее XML-файла. При записи документов 1С автоматически сформирует корректные записи в журналах.

Шаг 4: Работа с расширениями и планами обмена

Поскольку мы выяснили, что причиной часто является баг 10221419, проанализируем наши расширения. Рассмотрим альтернативный (более простой) путь, который помогает в ряде случаев:

Шаг 5: Переключение режима реструктуризации

Иногда современные механизмы оптимизированной реструктуризации (появившиеся в платформе 8.3.15+) ведут себя некорректно. Попробуем заставить платформу работать по старинке (построчно).

Для этого в файле conf.cfg (находится в папке conf в каталоге установки платформы 1С) добавим строку:

DisableOptimizedRestructuring=1

Или запустим конфигуратор с параметром командной строки: /IBCheckAndRepair -Rebuild

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

Дополнительные рекомендации

Выясним, не повреждена ли база данных на физическом уровне. Даже если 1С молчит, выполним команду SQL:

DBCC CHECKDB ('ВашаБазаДанных') WITH NO_INFOMSGS, ALL_ERRORMSGS;

Если обнаружены ошибки, используйте REPAIR_ALLOW_DATA_LOSS, но помните, что это крайняя мера. В большинстве случаев проблема «неуникального значения» в журналах решается именно через временное исключение типа документа из состава журнала в метаданных и последующий пересчет (как описано в Шаге 3).

Помните, что перед любыми манипуляциями с таблицами SQL или массовыми операциями в конфигураторе создание резервной копии базы данных (.dt или бэкап SQL) является обязательным условием.

← На главную