При попытке выделить отдельную организацию из базы 1С:Бухгалтерия Предприятия 3.0 с помощью распределенной информационной базы (РИБ) разработчики и администраторы часто сталкиваются со сбоем на этапе формирования начального образа. Ошибка возникает при вызове метода СоздатьНачальныйОбраз и сопровождается сообщением от MS SQL Server о невозможности выполнения инструкции CREATE UNIQUE INDEX из-за обнаружения повторяющегося ключа в индексах вида _ByRecorder.
В этой статье мы подробно проанализируем причины возникновения этой проблемы, разберем по шагам порядок ее диагностики и устранения, а также рассмотрим альтернативные варианты разделения базы данных по организациям.
Разберем основные факторы, приводящие к сбою уникальности индексов в СУБД MS SQL Server при формировании начального образа подчиненного узла:
ПриОтправкеДанныхПодчиненному или подписки на события отсекают часть документов или движений. В результате выгружаются движения регистра без самого документа-регистратора (или наоборот), либо нарушается порядковый номер записи в наборе, что приводит к совпадению составного ключа индекса _ByRecorder (регистратор + номер строки).В тексте ошибки SQL указывает внутреннее имя таблицы СУБД, например dbo._AccumRg25609. Чтобы узнать, какому объекту конфигурации 1С соответствует эта таблица, выполним специальный запрос в режиме 1С:Предприятия или через внешнюю обработку:
ИменаТаблиц = Новый Массив;
ИменаТаблиц.Добавить("РегистрНакопления.УплатаНДФЛНалоговымиАгентами");
СтруктураБазы = ПолучитьСтруктуруХраненияБазыДанных(ИменаТаблиц, Истина);
Для Каждого СтрокаТаблицы Из СтруктураБазы Цикл
Сообщить("Имя таблицы в SQL: " + СтрокаТаблицы.ИмяТаблицыХранения);
КонецЦикла;
Метод ПолучитьСтруктуруХраненияБазыДанных позволяет точно сопоставить имя SQL-объекта с конкретным регистром накопления, сведений или бухгалтерии.
Простое переиндексирование стандартными средствами 1С в данном случае часто оказывается неэффективным. Для восстановления физической целостности таблиц выполним следующие действия:
Если после реструктуризации ошибка продолжает возникать на конкретном регистре (например, УплатаНДФЛНалоговымиАгентами), и данные этого регистра не используются в выделяемой базе (к примеру, расчет зарплаты и НДФЛ ведется в отдельной программе 1С:ЗУП), можно произвести очистку записей регистра.
Очистить набор записей регистра по сбойной организации или полностью можно программно с помощью следующего кода:
НаборЗаписей = РегистрыНакопления.УплатаНДФЛНалоговымиАгентами.СоздатьНаборЗаписей();
// При необходимости устанавливаем отбор по организации
// НаборЗаписей.Отбор.Организация.Установить(ВыбраннаяОрганизация);
НаборЗаписей.Записать(); // Записываем пустой набор, удаляя данные
После удаления устаревших или поврежденных записей из регистра необходимо повторно выполнить пересчет итогов в конфигураторе, после чего запустить создание начального образа вызовом метода СоздатьНачальныйОбраз.
Если штатный механизм выгрузки узла РИБ с фильтрацией по организации не удается завершить из-за особенностей конфигурации или правил обмена, проанализируем обходные решения.
Рассмотрим алгоритм, который позволяет обойти проблемы с фильтрацией данных на этапе формирования базы:
УстановитьГлавныйУзел(Неопределено);
Если требуется получить чистую базу без истории ошибок в индексах:
Убедимся, что процедура формирования начального образа выполняется в 64-разрядном окружении (на 64-битном сервере 1С:Предприятия или через 64-битный клиент 1С). Это исключит ошибки недостатка оперативной памяти при обработке крупных таблиц объемом от 10 ГБ.