Ошибки, связанные с дублированием записей в уникальных индексах, являются одними из самых критичных для платформы 1С:Предприятие. Особенно часто это проявляется при обновлении конфигурации или выполнении тестирования и исправления (ТиИ). Ситуация осложняется, когда стандартная утилита chdbfl.exe не приносит результата, а база выдает сложные ошибки формата SDBL. В данной статье мы разберем, что представляет собой таблица _ACCRGED, почему возникают дубли и как поэтапно восстановить работоспособность информационной базы.
Для начала проанализируем структуру базы данных. Таблицы с префиксом _ACCRGED (Accounting Register Ged) — это вспомогательные таблицы значений субконто бухгалтерского регистра. В архитектуре 1С 8.3 они используются для оптимизации хранения и быстрого извлечения данных аналитики. Ошибка дублирования в уникальном индексе этой таблицы (например, _accrged7952_1) означает, что для одной и той же проводки — сочетания регистратора, номера строки и вида субконто — в базе физически записано две или более строки.
Основные причины появления таких ошибок:
fsync могут привести к тому, что данные не фиксируются должным образом.Первым делом рассмотрим самый простой, но не всегда эффективный способ — использование утилиты chdbfl.exe, которая находится в папке bin установленной платформы. Запустим её, выберем файл нашей базы данных и обязательно установим флаг «Исправлять обнаруженные ошибки». Рассмотрим ситуацию: если утилита удалит дублирующиеся записи, индекс снова станет уникальным, и база запустится. Однако, если после прохода chdbfl ошибка сохраняется или база вылетает при обновлении, перейдем к более глубокому анализу.
Посмотрим на пример системного сообщения: DETAIL: Key (_fld12396, _period, _recordertref, _recorderrref, _lineno, _kindrref, _correspond)=(0, 2015-05-15 23:59:59, \x000000b5, \xab32001a4d38920e11e523db3c85e9f9, 3, \xb44b334de4c5d19d4d7785e8f75e7abe, 1) is duplicated.
Из этого текста мы можем извлечь точные координаты «битой» записи:
_period: 15.05.2015 23:59:59 — это дата документа._recorderrref: ab32001a4d38920e11e523db3c85e9f9 — уникальный идентификатор (GUID) документа-регистратора._lineno: 3 — номер строки в проводках._kindrref: b44b334de4c5d19d4d7785e8f75e7abe — ссылка на вид субконто (например, Номенклатура или Контрагенты).Чтобы найти конкретный объект в базе, мы можем использовать следующий код на языке 1С для преобразования полученного шестнадцатеричного значения в понятную ссылку:
// Пример функции для преобразования строки из ошибки в УИД
Функция ПолучитьСсылкуИзОшибки(СтрокаИд)
// Формируем стандартный формат GUID: 00000000-0000-0000-0000-000000000000
СтрокаУИД = Прав(СтрокаИд, 8) + "-" + Сред(СтрокаИд, 21, 4) + "-" + Сред(СтрокаИд, 17, 4) + "-" + Сред(СтрокаИд, 1, 4) + "-" + Сред(СтрокаИд, 5, 12);
Возврат Новый УникальныйИдентификатор(СтрокаУИД);
КонецФункции
// Пример поиска документа
УИД_Документа = ПолучитьСсылкуИзОшибки("ab32001a4d38920e11e523db3c85e9f9");
СсылкаНаДокумент = Документы.РеализацияТоваровУслуг.ПолучитьСсылку(УИД_Документа);
Сообщить(СсылкаНаДокумент);
Найдя проблемный документ, попробуем его перепровести или отменить проведение и провести заново. Это может заставить платформу перезаписать данные в таблице _ACCRGED.
Проанализируем ситуацию, когда при обновлении возникает ошибка: «Для одного ссылочного кода существует более одной таблицы в базе данных». Это означает, что внутренняя таблица описания структуры (DBSCHEMA) содержит дублирующие записи о соответствии объектов метаданных физическим таблицам. Например, код 32389 ссылается одновременно на InfoRgChngR32389 и ReferenceChngR32389.
В этом случае обычное «Тестирование и исправление» может не помочь. Рассмотрим профессиональные методы решения:
GROUP BY ... HAVING COUNT(*) > 1 и удалить лишние строки через системный идентификатор ctid (в Postgres) или %%physloc%% (в MS SQL)..1CD. С её помощью можно открыть таблицу DBSCHEMA и вручную удалить записи, вызывающие конфликт. Внимание: это крайне опасная операция, требующая обязательного наличия копии базы!Разберем пример исправления, если вы решили временно перевести базу на PostgreSQL для лечения. Выясним причину дубля и удалим его. Предположим, мы нашли таблицу с дублями в уникальном индексе. Выполним запрос:
-- Поиск дублирующихся записей по ключевым полям индекса
SELECT _period, _recorderrref, _lineno, COUNT(*)
FROM _accrged7952
GROUP BY _period, _recorderrref, _lineno
HAVING COUNT(*) > 1;
-- Удаление одной из дублирующихся строк (оставляем только одну)
DELETE FROM _accrged7952 a
WHERE a.ctid <> (SELECT min(b.ctid)
FROM _accrged7952 b
WHERE a._period = b._period
AND a._recorderrref = b._recorderrref
AND a._lineno = b._lineno);
После удаления дублей необходимо выполнить выгрузку в .dt и загрузку обратно в файловый вариант (или оставить в SQL). Это гарантированно очистит индексы.
Подведем итоги нашего исследования. Если вы столкнулись с ошибкой дублей в _ACCRGED, действуйте по следующему алгоритму:
chdbfl.exe с исправлением ошибок.Помните, что такие ошибки часто являются следствием проблем с «железом» или сетью. Проверьте состояние жесткого диска и убедитесь, что база данных не лежит на сетевом ресурсе с нестабильным соединением, так как файловый вариант 1С крайне чувствителен к качеству связи.