Администрирование · 12 мин
Дублирующиеся ключи в уникальных индексах таблицы 1С: причины и исправление
Что означает ошибка дублирующихся ключей в уникальных индексах таблиц 1С, как найти дубликаты и исправить их через SQL, тестирование и исправление или chdbfl.
Ошибка «обнаружены дублирующиеся ключи в уникальных индексах» появляется при тестировании и исправлении базы 1С, обновлении конфигурации или реструктуризации таблиц. Она означает, что в таблице, к которой применён уникальный индекс, есть две или более строки с одинаковым значением ключа — а по логике платформы такого быть не должно. Пока дубликаты существуют, построить уникальный индекс невозможно, и операция прерывается.
Чаще всего проблема возникает в файловых базах после аварийного завершения работы (отключение электричества, разрыв сетевого диска, сбой оборудования) и в клиент-серверных базах после некорректного восстановления из копии, ошибок СУБД или прямых манипуляций с таблицами в обход платформы. Типичные «пострадавшие» — таблицы регистров сведений, регистров накопления, документов и служебные таблицы хранения настроек.
Хорошая новость: в большинстве случаев ситуация исправима без потери данных, если действовать последовательно — сначала локализовать таблицу и дублирующиеся значения, затем устранить лишние записи и только после этого перестроить индексы. Главное правило — любые действия выполнять только после создания резервной копии.
Почему появляются дублирующиеся ключи
Уникальный индекс — это ограничение целостности: платформа 1С гарантирует, что комбинация определённых полей (например, измерений регистра сведений вместе с периодом) встречается в таблице только один раз. Если это правило нарушено, значит, данные были записаны в обход штатного механизма контроля или повреждены на физическом уровне.
На практике встречаются такие причины:
- аварийное завершение процесса 1С или сервера СУБД в момент записи транзакции;
- сбои дисковой подсистемы, нехватка места на диске, ошибки RAID-контроллера;
- работа файловой базы по сети с обрывами соединения;
- прямые изменения данных в таблицах SQL-запросами в обход платформы;
- восстановление базы из повреждённой или неполной резервной копии;
- обмены данными, в которых одна и та же запись загружалась повторно с нарушением механизмов регистрации.
Понимание причины важно для профилактики: если дубликаты появились из-за нестабильного диска или сети, после исправления ошибка вернётся, пока не устранён первоисточник.
Какая таблица указана в тексте ошибки и из каких полей состоит индекс
Полный протокол проверки — там перечислены таблицы и количество проблемных записей
Запросом с GROUP BY и HAVING COUNT(*) > 1 найти конкретные значения ключей
Что сделать до начала исправления
Первый и обязательный шаг — резервная копия. Для файловой базы это копирование файла 1Cv8.1CD при остановленной работе пользователей либо выгрузка в dt через конфигуратор. Для клиент-серверной базы — штатный backup средствами СУБД (полная копия базы данных), а не только выгрузка dt: dt может «не взять» повреждённые данные или, наоборот, перенести проблему в новую базу.
Второй шаг — зафиксировать точную формулировку ошибки. В сообщении платформы или в протоколе тестирования указывается имя таблицы (например, _InfoReg12345) и иногда имя индекса. Это ключ к дальнейшей диагностике: без точного имени таблицы искать дубликаты придётся вслепую.
Третий шаг — завершить все сеансы пользователей и фоновые задания. Исправление дубликатов выполняется в монопольном режиме: параллельная запись данных во время чистки может создать новые нарушения и свести работу на нет.
Как найти таблицу и дублирующиеся записи
Соответствие физических имён таблиц (вида _Document123, _InfoReg456) объектам метаданных определяется через функцию ПолучитьСтруктуруХраненияБазыДанных() — её можно выполнить в консоли кода или посмотреть в отчёте по структуре хранения. Так вы узнаете, что, например, _InfoReg456 — это регистр сведений «Курсы валют» конкретной базы.
В клиент-серверной базе дубликаты ищутся прямым запросом к СУБД. Логика одинаковая для MS SQL Server и PostgreSQL: группируем строки по полям уникального индекса и отбираем группы, где больше одной записи.
SELECT Поле1, Поле2, COUNT(<em>) AS Cnt
FROM _InfoReg456
GROUP BY Поле1, Поле2
HAVING COUNT(</em>) > 1;Поля для группировки берутся из определения индекса: для регистра сведений это обычно измерения плюс период (для периодических), для регистра накопления — набор полей уникального индекса записей. Состав индекса виден в СУБД (sp_helpindex в MS SQL или pg_indexes в PostgreSQL) и в протоколе ошибки.
В файловой базе прямого SQL-доступа нет. Здесь ориентир — протокол тестирования и исправления, а также утилита chdbfl из каталога bin платформы: проверка физической целостности файла покажет повреждённые таблицы. Иногда помогает загрузка базы в клиент-серверный вариант на тестовом сервере — тогда дубликаты можно найти запросом.
Способы исправления дубликатов
Выбор способа зависит от режима работы базы и масштаба проблемы. Ниже — три рабочих варианта в порядке от штатного к более рискованному.
Тестирование и исправление через конфигуратор
Штатный инструмент: конфигуратор → «Администрирование» → «Тестирование и исправление». Отметьте проверку логической целостности, реиндексацию таблиц и пересчёт итогов. В ряде случаев платформа сама устраняет задвоения, если они возникли на уровне индексов, а не физических строк. Минус метода — при большом числе физических дубликатов процедура может завершиться ошибкой, и тогда нужен ручной разбор.
Удаление дубликатов запросом к СУБД
Если дубликаты — физические строки, лишние записи удаляются прямым запросом. Критично определить, какая из строк «правильная»: обычно оставляют одну из идентичных строк (по минимальному или максимальному служебному идентификатору строки). Перед удалением выгрузите дублирующиеся записи в отдельную таблицу-копию — это страховка на случай ошибочного удаления.
- 1Сделайте полную резервную копию базы средствами СУБД
- 2Определите таблицу и состав полей уникального индекса
- 3Найдите дубли запросом с GROUP BY и HAVING COUNT(*) > 1
- 4Сохраните найденные строки во временную таблицу-копию
- 5Удалите лишние строки, оставив по одной в каждой группе дублей
- 6Проверьте запросом, что дубликатов не осталось
- 7Запустите тестирование и исправление с реиндексацией и пересчётом итогов
Выгрузка и загрузка через dt
Выгрузка в dt с последующей загрузкой в пустую базу иногда «отфильтровывает» часть проблем, так как данные перечитываются и записываются заново. Однако метод не гарантирован: если дубликаты физически присутствуют в таблицах, они могут перенестись в новую базу или помешать самой выгрузке. Используйте этот вариант как дополнительный, а не основной.
Сравнение вариантов исправления
Штатно и безопасно, но не справляется с физическими дубликатами строк
Точечно решает проблему, но требует понимания структуры таблиц и обязательной копии
Пересоздаёт базу целиком; долго на больших объёмах и не гарантирует устранение дублей
Восстанавливает физическую целостность файла, но не решает логические дубликаты записей
Проверка результата после исправления
После удаления дубликатов повторите контрольный запрос с GROUP BY — он должен вернуть пустой результат. Затем запустите тестирование и исправление в конфигураторе с реиндексацией: процедура должна завершиться без сообщений о дублирующихся ключах.
Если ошибка возникала при обновлении конфигурации — повторите обновление. Реструктуризация, которая раньше прерывалась, должна пройти до конца. Дополнительно проверьте отчёты по затронутому объекту: если чистили регистр сведений, убедитесь, что данные на месте и не потерялись нужные записи (здесь пригодится временная таблица-копия удалённых строк).
Как проверить результат
Результат пустой — дублей нет
Остались группы с COUNT(*) > 1
Завершается без ошибок логической целостности
Повторное сообщение о дублирующихся ключах
Реструктуризация проходит полностью
Обрыв на создании уникального индекса
Записи на месте, отчёты сходятся с копией
Пропали нужные строки, расхождения в отчётах
Типичные ошибки при исправлении
Самая частая ошибка — удаление дубликатов без анализа: администратор удаляет «лишние» строки, не разобравшись, какая из них актуальна, и теряет реальные данные. Вторая типичная ошибка — исправление без резервной копии: любая ошибка в запросе DELETE становится необратимой.
Третья ошибка — игнорирование первопричины. Если дубликаты появились из-за сбоев диска или обмена данными, чистка таблицы даст лишь временный эффект. Четвёртая — попытка исправить всё одной выгрузкой dt на повреждённой файловой базе: выгрузка может оборваться на середине, а исходный файл к этому моменту уже будет недоступен, если перед этим его «лечили» без копии.
Профилактика повторного появления дублей
Основа профилактики — стабильная инфраструктура: исправные диски, источник бесперебойного питания, отказ от размещения файловой базы на сетевых дисках с нестабильным соединением. Для клиент-серверных баз — мониторинг журналов СУБД на предмет ошибок ввода-вывода и регулярная проверка целостности (DBCC CHECKDB для MS SQL, pg_amcheck для PostgreSQL).
Регламентные операции тоже важны: периодическое тестирование и исправление, контроль обменов данными (дубли часто приходят из обменов при повторной загрузке) и запрет на прямые правки таблиц в обход платформы для всех, кроме осознанных аварийных случаев. Регулярные резервные копии с проверкой восстановления превращают подобную аварию из катастрофы в плановую задачу на один вечер.
Что важно запомнить
Дублирующиеся ключи — это строки с одинаковыми значениями полей уникального индекса. Порядок действий: резервная копия, поиск дублей запросом или через протокол тестирования, аккуратное удаление лишних строк, реиндексация и проверка. Без копии и без устранения первопричины исправление рискованно и недолговечно.
Частые вопросы
Можно ли исправить дублирующиеся ключи без доступа к СУБД?
Для файловой базы — да: используйте утилиту chdbfl (проверка физической целостности) и тестирование и исправление в конфигураторе. Если дубликаты логические (одинаковые записи в регистре), их можно найти и удалить штатными средствами 1С — запросом в консоли запросов по измерениям объекта.
Опасно ли удалять дубликаты в регистре сведений напрямую?
Риск зависит от регистра. В независимых регистрах сведений (например, хранящих настройки) удаление одной из идентичных строк обычно безболезненно. В подчинённых регистратору регистрах и регистрах накопления ручное удаление может нарушить связь с документом и итоги — там безопаснее перепроведение документов или пересчёт итогов после чистки.
Почему тестирование и исправление не убирает дубликаты?
Потому что платформа устраняет нарушения на уровне индексов и ссылочной целостности, но не решает за администратора, какая из двух физически разных строк «правильная». Физические дубликаты строк нужно удалить вручную, после чего тестирование пройдёт успешно.
Поможет ли выгрузка в dt и загрузка обратно?
Иногда — да, так как данные перечитываются и записываются заново. Но если дубликаты физически присутствуют в таблицах, они часто переносятся в новую базу или вызывают ошибку уже на этапе загрузки. Рассматривайте dt как дополнительный инструмент, а не гарантированное лекарство.
Как понять, какая таблица скрывается за именем вида _InfoReg12345?
Выполните в консоли кода функцию ПолучитьСтруктуруХраненияБазыДанных() — она возвращает соответствие имён таблиц СУБД объектам метаданных. В клиент-серверной базе также можно посмотреть описание полей таблицы и сопоставить их с измерениями и реквизитами объекта.
Может ли ошибка появиться снова после исправления?
Да, если не устранена причина: сбоящий диск, нестабильная сеть при файловом режиме, некорректно настроенный обмен данными или прямые правки в СУБД. После исправления проверьте журналы оборудования и СУБД и настройте регулярный контроль целостности базы.