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

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

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

«Попытка вставки неуникального значения в уникальный индекс... Не удается вставить повторяющуюся строку ключа в объект "dbo._InfoRgXXXXX" с уникальным индексом... HRESULT=80040E2F, SQLSrvr: SQLSTATE=23000, native=2601».

Разберем природу данной ошибки, выясним, почему в базе могут проявляться парадоксальные аномалии чтения данных и как восстановить работоспособность системы на уровне СУБД и средств платформы 1С.

Анализ причин возникновения ошибки

Проанализируем две принципиально разные причины возникновения этой ситуации:

  1. Логические дубли в наборе записей. В коде проведения документа формируются строки с одинаковым набором ключевых измерений. При попытке физической записи набора в базу СУБД отвергает дублирующуюся строку.
  2. Физическое повреждение страниц данных или B-дерева индексов в SQL Server. Если логических дублей в коде нет, но при выборках через SQL Server Management Studio (SSMS) наблюдаются аномалии (например, фильтр по дополнительному полю возвращает больше строк, чем запрос без него), это говорит о повреждении ссылочной структуры между некластеризованными индексами и страницами таблицы. Из-за этого СУБД считает, что ключ уже занят, либо считывает некорректные указатели.

Повреждения страниц чаще всего возникают в результате сбоев подсистемы ввода-вывода (сброс кэша дискового контроллера без BBU, резкое обесточивание сервера, сбои RAM) или прямого вмешательства стороннего софта (например, сканирования файлов базы антивирусом).

Также обратим внимание на даты вида янв 1 4017 в сообщении об ошибке. Это штатный механизм смещения дат платформы 1С на 2000 лет вперед (для обхода ограничений типа DATETIME в Microsoft SQL Server, где нижняя граница равна 01.01.1753). Реальной дате 01.01.2017 в СУБД соответствует 01.01.4017.

Шаг 1. Локализация проблемной таблицы и полей индекса

Выясним, какой именно таблице 1С соответствует имя физической таблицы SQL (например, _InfoRg20971). Для этого воспользуемся встроенной функцией платформы:


СтруктураХранения = ПолучитьСтруктуруХраненияБазыДанных();
Для Каждого Стр Из СтруктураХранения Цикл
    Если Стр.ИмяТаблицыХранения = "_InfoRg20971" Тогда
        Сообщить("Имя объекта метаданных: " + Стр.Имя);
    КонецЕсли;
КонецЦикла;

Сопоставив поля таблицы, мы получаем доступ к реальным измерениям регистра (например, РегистрСведений.ГрафикиРаботыПоВидамВремени).

Шаг 2. Проверка целостности таблицы средствами SQL Server

Если в коде 1С дубликатов измерений не обнаружено, выполним диагностику целостности страниц данных проблемной таблицы в SSMS с помощью команды DBCC CHECKTABLE:

DBCC CHECKTABLE ('_InfoRg20971') WITH DATA_PURITY;

Если в результате выполнения отображаются сообщения вида Ошибка в таблице... Неправильный порядок ключей на странице... или CHECKTABLE обнаружил ошибки согласованности, структура индексов повреждена.

Шаг 3. Исправление повреждений на уровне СУБД

Рассмотрим варианты восстановления целостности таблицы через SQL Server:

  1. Перестроение индексов таблицы (Index Rebuild). В большинстве случаев достаточно заново перестроить поврежденные индексы без потери данных: ALTER INDEX ALL ON [dbo].[_InfoRg20971] REBUILD;
  2. Автоматическое восстановление через DBCC. Если перестроение индексов не помогло или таблица содержит ошибки размещения страниц, выполним процедуру восстановления структуры: DBCC CHECKTABLE ('_InfoRg20971', REPAIR_REBUILD); Параметр REPAIR_REBUILD устраняет ошибки структуры B-дерева и восстанавливает индексы без удаления пользовательских данных.

Шаг 4. Устранение проблемы штатными средствами 1С

Если нет прямого доступа к SQL Server Management Studio или требуется комплексное исправление всей базы данных, применим стандартные процедуры платформы 1С:

  1. Тестирование и исправление:

    Запустим информационную базу в режиме Конфигуратор, перейдем в меню Администрирование → Тестирование и исправление... и выберем режимы:

    • Переиндексация таблиц информационной базы — заново строит все индексы согласно метаданным;

    • Реструктуризация таблиц информационной базы — полностью пересоздает физические таблицы в СУБД с последовательным переносом всех данных, гарантированно очищая структуру от скрытых сбоев.

  2. Выгрузка и загрузка через DT-пакет:

    Выполним операцию Администрирование → Выгрузить информационную базу в файл .dt. Данная выгрузка вычитывает только логические записи 1С. Затем создадим новую чистую базу на сервере СУБД и выполним в нее загрузку полученного файла, что сформирует таблицы и индексы с нуля.

Профилактика и регламентное обслуживание

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

  1. Настроим в SQL Server Agent еженедельный регламентный план с командой DBCC CHECKDB для раннего обнаружения поврежденных страниц.
  2. Включим регулярную дефрагментацию и перестроение индексов (REBUILD / REORGANIZE) для активных таблиц базы данных.
  3. Исключим каталоги с файлами базы данных (.mdf, .ldf) из зоны сканирования серверных антивирусов.
← На главную