В практике администрирования и разработки на платформе «1С:Предприятие 8» часто встречается схема, когда рабочую клиент-серверную (SQL) базу выгружают в файл резервной копии .dt, разворачивают локально в файловом варианте для проведения тяжелых регламентных операций, доработок или удаленной работы, а затем пытаются загрузить обратно на сервер. Этот процесс кажется интуитивным, но в нем скрывается серьезная техническая ловушка.
При импорте файла .dt обратно на SQL-сервер процесс может аварийно прерваться ошибкой: «Попытка вставки не уникального значения в уникальный индекс». В этой статье мы подробно разберем, почему возникает данная коллизия, как ведет себя база данных при такой ошибке, и рассмотрим пошаговые сценарии решения проблемы на примере справочника Контрольные соотношения в конфигурации «Бухгалтерия государственного учреждения» (БГУ).
Для того чтобы понять суть проблемы, проанализируем разницу в архитектуре систем управления базами данных (СУБД). Файловая база данных 1С (формат .1CD) использует собственный встроенный СУБД-движок. В силу особенностей его оптимизации и распределения транзакционной нагрузки, при аварийных завершениях сеансов, отключении питания компьютера или логических сбоях платформы механизмы проверки уникальности индексов могут сработать некорректно. В результате в физических таблицах файловой базы могут появиться строки-дубликаты по ключевым полям (например, по уникальному идентификатору GUID или коду).
Файловая база данных продолжает функционировать, «не замечая» этих дубликатов при повседневной работе пользователей. При выгрузке базы в формат .dt платформа производит простую последовательную сериализацию (сжатие и выгрузку) данных из таблиц «как есть», без глубокой проверки уникальности на физическом уровне.
Проблемы манифестируют себя в момент загрузки файла .dt в клиент-серверный вариант (MS SQL, PostgreSQL и др.). Процесс импорта происходит следующим образом:
CREATE UNIQUE INDEX terminated because a duplicate key was found.Один из ключевых вопросов, который волнует специалистов: «Загрузились ли остальные данные, если ошибка произошла только в одном справочнике?»
Ответ однозначный: нет, база данных загружается не полностью. Процесс восстановления базы данных из файла .dt представляет собой единую неделимую последовательность транзакций. Как только возникает критическая ошибка построения уникального индекса СУБД, процесс импорта аварийно прекращается. Все таблицы, которые должны были быть загружены и проиндексированы после сбойного справочника, попросту не попадают в итоговую базу данных. Использовать такую базу для ведения учета категорически запрещено, так как ее структура нарушена, а часть данных безвозвратно утеряна.
Проанализируем сопутствующий фактор, упомянутый в обсуждении: работа на разных версиях платформы 1С (в нашем кейсе это 8.3.13 для файлового варианта и 8.3.14 для SQL-сервера). Разработчики платформы постоянно оптимизируют структуры хранения данных, механизмы сериализации и построения индексов. Перенос данных через формат .dt между разными релизами платформы (особенно «вниз» по версиям или с существенным шагом вверх) значительно увеличивает риск рассинхронизации структур данных.
Рекомендация: Всегда выполняйте выгрузку и загрузку данных на строго идентичных версиях технологической платформы «1С:Предприятие 8» как на рабочем сервере СУБД, так и на локальном компьютере, где разворачивается файловая копия.
Справочник Контрольные соотношения (а также сопутствующие системные справочники регламентированной отчетности БГУ, такие как Правила проверки или Виды отчетов) хранит формулы увязки показателей и алгоритмы контроля корректности составления отчетов. Эти данные поставляются централизованно фирмой 1С в составе обновлений комплектов отчетности. Они не создаются вручную пользователем в процессе ведения учета и не содержат уникальной бухгалтерской информации.
По этой причине очистить справочник «Контрольные соотношения» — это абсолютно безопасный, быстрый и технически верный способ устранения ошибки уникальности индекса.
Выполним процедуру очистки справочника по шагам:
// Программный скрипт для полной физической очистки справочника
Выборка = Справочники.КонтрольныеСоотношения.Выбрать();
СистематическиеОшибки = 0;
ВсегоЭлементов = 0;
Пока Выборка.Следующий() Цикл
ВсегоЭлементов = ВсегоЭлементов + 1;
ОбъектСправочника = Выборка.ПолучитьОбъект();
Попытка
// Используем непосредственное удаление для обхода долгих проверок ссылок
ОбъектСправочника.Удалить();
Исключение
СистематическиеОшибки = СистематическиеОшибки + 1;
ЗаписьЖурналаРегистрации("ОчисткаСправочникаКС",
УровеньЖурналаРегистрации.Предупреждение,
,
,
"Ошибка удаления элемента: " + Выборка.Ссылка + ". Причина: " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
Сообщить("Процедура завершена. Всего обработано элементов: " + ВсегоЭлементов + ". Ошибок при удалении: " + СистематическиеОшибки);
После успешного выполнения скрипта и полной очистки справочника Контрольные соотношения в файловой базе, выгрузим её заново в файл .dt. Теперь в структуре выгрузки не будет дублирующихся записей по данному справочнику, и импорт в SQL-базу завершится успешно.
После того как очищенная база успешно развернулась на сервере СУБД, справочник контрольных соотношений окажется пустым. Нам необходимо вернуть актуальные правила проверки отчетности. Выполним следующие действия:
.repx).Контрольные соотношения новыми, чистыми и актуальными данными без каких-либо дубликатов физических индексов.Рассмотрим альтернативную, более сложную ситуацию. Что делать, если ошибка уникальности индекса произошла в справочнике, который содержит бизнес-данные (например, Контрагенты, Номенклатура или Договоры контрагентов)? Очевидно, что просто очистить такой справочник нельзя — это приведет к потере критически важных данных и нарушению ссылочной целостности документов.
В этом случае проанализируем и применим один из следующих подходов в исходной файловой базе перед ее выгрузкой:
Откроем файловую базу в режиме Конфигуратора. Перейдем в меню Администрирование -> Тестирование и исправление.... Установим флаги напротив опций «Проверка логической целостности» и «Проверка ссылочной целостности». В параметрах обработки незаполненных (несуществующих) ссылок выберем действие «Создавать объекты» или «Очищать ссылки». Запустим процесс тестирования. Платформа попытается автоматически устранить логические несоответствия и удалить «битые» дубликаты индексов.
Если сбой носит глубокий физический характер на уровне страниц файла базы данных, закроем все активные сеансы работы с базой. В каталоге установки платформы 1С (обычно путь вида C:\Program Files\1cv8\номер_версии\bin\) найдем и запустим утилиту chdbfl.exe. Укажем путь к файлу базы данных 1cv8.1cd, установим флаг «Исправлять обнаруженные ошибки» и запустим проверку. Утилита восстановит физическую целостность индексов файловой СУБД.
В режиме «1С:Предприятие» воспользуемся встроенным инструментом «Поиск и удаление дублей». Мы можем написать простой запрос для локализации дублирующих записей по коду или иным уникальным реквизитам. Разберем пример запроса для поиска дубликатов кодов в справочнике контрагентов:
// Запрос для выявления дубликатов кодов справочника "Контрагенты"
ЗапросДубли = Новый Запрос;
ЗапросДубли.Текст =
"ВЫБРАТЬ
| Контрагенты.Код КАК КодКонтрагента,
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Контрагенты.Ссылка) КАК КоличествоСсылок
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|
|СГРУППИРОВАТЬ ПО
| Контрагенты.Код
|
|ИМЕЮЩИЕ
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Контрагенты.Ссылка) > 1";
РезультатЗапроса = ЗапросДубли.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
ВыборкаДублей = РезультатЗапроса.Выбрать();
Пока ВыборкаДублей.Следующий() Цикл
Сообщить("Обнаружен дублирующийся код: " + ВыборкаДублей.КодКонтрагента + " встретился " + ВыборкаДублей.КоличествоСсылок + " раз.");
КонецЦикла;
КонецЕсли;
Обнаруженные дубликаты необходимо объединить, перенаправив все ссылки в документах на один ведущий элемент (оригинал), после чего пометить лишние элементы на удаление и выполнить их непосредственное удаление из базы данных.
Для предотвращения подобных ошибок в будущем рекомендуется пересмотреть подход к переносу данных между удаленными рабочими местами:
.dt для регулярного переноса баз туда и обратно. Формат .dt разработан фирмой 1С в первую очередь для создания резервных копий и архивации, а не для постоянного оперативного обмена.