Отказ от ответственности: вы все здесь взрослые и делаете всё на свой страх и риск. Да, и ещё: лицензионное соглашение не разрешает вам это делать, поэтому данное описание дано для образовательных целей.
После перехода с 8.3.12 на 8.3.15 словили неприятную ошибку "Для одного ссылочного кода существует более одной таблицы в базе данных". Самое неприятное, что ошибка стала вылезать и на типовых базах, которые никто никогда не трогал.
Гугл ничего не дал кроме стандартных "почистить кэш, перерегистрировать базу в кластере, выполнить ТИИ". Ну и еще "добавить реквизит к объекту и обновить БД" (этот пункт не пробовал, напишите в комментариях — вдруг это самый простой метод в комментариях к этой статье есть сообщение что метод сработал на 8.3.16.1030, пробуйте).
На партнерке есть пара веток, в т.ч. https://partners.v8.1c.ru/forum/topic/1792992, из которой приведу пару цитат:
Воспроизводится так (проверено на релизе 8.3.13.1644 / SQL 2024):
1. Создаём две базы test1 и test2
2. Запускаем конфигуратор test1, добавляем справочник, обновляем конфигурацию. В базе добавляется таблица _Reference21
3. Делаем SQL бэкап базы test1 и восстанавливаем его в test2.
4. Запускаем конфигуратор test2 и добавляем документ, обновляем конфигурацию. В базе видим таблицы: _Reference21 и _Document21.
Помогает перезапуск rmngr.exe после восстановления test2 из бэкапа.
И ответ представителя фирмы 1С:
Да, действительно, в этом сценарии две таблицы получают два одинаковых ссылочных номера.
Это ошибка, будет исправлена в одной из следующих версий.
Что можно сказать по этой ошибке. Во-первых, чистка кэша не поможет. Во-вторых, ошибка воспроизводится только если было хотя бы одно добавление объекта метаданных до восстановления из резервной копии (это приводит к инициализации сервиса в менеджере кластера, и как следствие — сохранению значения последнего номера таблицы).
Рекомендации на сейчас (до выхода версий с исправлением) по обходу ошибки: сразу после восстановления ИБ средствами СУБД — производите перезапуск сервера платформы.
Я провел тест на 8.3.12 — проблема по методике первой цитаты воспроизводится. Так что делаю выводы:
1) проблема с задвоением внутренней нумерации объектов существовала очень давно, как минимум с 8.3.12, но лишь в 8.3.15 добавили проверку (понятно) и запрет применения изменений (а вот тут явно не подумали что у пользователей много таких "поломанных" баз)
2) по-идее, можно жить спокойно на релизах менее 8.3.15 и ждать манны небесной от фирмы 1С.
Ну а нам ждать "одной из следующих версий" нельзя. Базы разработчиков "встают" одна за другой на этой ошибке. Я предлагал откатиться на 8.3.13 или 8.3.14 — но согласился пробовать найти свое решение, т.к. когда будет эта "манна" — неизвестно. А если продолжить использовать "старые" релизы — то дубли нумерации скорее всего будут только плодиться, хоть мы их и не будем видеть.
Размышления привели к пониманию того, что надо найти "где в базе хранится сопоставление таблиц sql и объектов конфигурации". Как оказалось таких мест два: таблица DBSchema и реквизит DBNames таблицы Params.
Попытка получить DBSchema использованием SQL Management studio завершилась неудачей: в режиме ssms получается получить лишь первые 65КБ двоичных данных, хранящихся в таблице, и при вставке в hex-редактор получаем неполную структуру.
А уж DBNames и вовсе хранится в сжатом виде. Поэтому усилия были перенаправлены на поиск инструмента для редактирования этих данных. И он был найден: Восстановление структуры DBSchema
Стоимость инструмента — 10sm (Мопед не мой!). Впрочем, описанная ниже методика не зависит именно от этой обработки; можете поискать аналог или написать свою. Функционал указанной обработки используется только в части выгрузки DBSchema и DBNames из sql в файл и обратно.
А я опишу методику лечения баз:
- рекомендуется использовать Notepad++ или аналог. В отдельном файле открыть текст ошибки из конфигуратора.
- запустить обработку, получить DBSchema (схема — список объектов — распознать схему) и DBNames (вверху "загрузить из БД в файл"), выгрузить обе структуры в файлы, указав вверху пути и нажав на кнопки рядом. Открыть файлы в Notepad++. Должно получиться примерно следующее (слева DBNames, справа — DBSchema):
- из текста ошибки для каждой пары объектов выбрать "жертву"; проще менять номер у констант или регистров, т.к. на них обычно нет ссылок в реквизитах других объектов. Желательно выбирать в таком качестве "таблицы изменений" вида _ConstChngR2346 или _DocumentChngR3078 не имеющие табличных частей (у нет таблиц вида Document750.VT20237 или _Reference49197_VT3332).
- в DBNames находим строку жертвы по номеру объекта, переносим строку в конец файла, меняем номер объекта (+1 к предыдущему)
- в файле с текстом ошибки к номеру "жертвы" добавляем "-НовыйНомер"
- в DBSchema находим объект, меняем номер объекта (в третьем параметре); ищем все вхождения имени объекта (например Reference3048) — ссылки на этот объект в реквизитах других объектов — выполняем замену например Reference3048 на Reference49189.
- в DBNames первый параметр меняем на новый максимальный номер объекта
- сохраняем файлы, считываем их обработкой (вся схема — текст — прочитать схему из файла, Имена — Прочитать DBNames из файла), выгружаем из обработки в БД
- пишем sql-код для переименования всех таблиц вида:
EXEC sp_rename _Enum3066, _Enum49200
EXEC sp_rename _Enum3067, _Enum49201
EXEC sp_rename _DocumentChngR3078, _DocumentChngR49202
и выполняем его. Если все-таки жертвой был справочник с табличной частью — во всех табличных частях надо переименовать ссылку
EXEC sp_rename '_Reference49197_VT3332._Reference3048_IDRRef', '_Reference49197_IDRRef', 'column'
- после выполнения указанных действий также рекомендую удалить-добавить базу в кластере.
Хотя от представителя 1с на партнерском форуме есть альтернатива — рекомендация перезапускать сервер — в комментариях (7) к данной статье коллега отписался о неэффективности этого метода.
Мне помогло просто выгрузить базу в *.dt из sql, загрузить в Postgres, выгрузить обратно в *.dt и опять загрузить
Мне помогло просто выгрузить базу в *.dt из sql, загрузить в Postgres, выгрузить обратно в *.dt и опять загрузить в SQL. Проблемма исчезла
Мне помог * платформы на предыдущий релиз, где эта ошибка не возникала. Сделал копии поломанных объектов заново в конфигураторе, стараясь избегать объектов ссылочных типов (мне повезло в паре к справочникам поломаны были несколько регистров сведений и накопления). Скопировал информацию оттуда опять же средствами 1с. Старые объекты удалил. И запустил на свежей платформе с перезапуском сервера 1с. Выгрузка или ТиИ занимает много времени поэтому пришлось так.
(1) кажется и через файловую сработает. Но всё упирается в размер.
(2) хитрый ход 😉
Что было предпринято и не помогло, на что не стоит тратить время:
— Тестирование и исправление на уровне конфигуратора — результат: долго проверяет и в итоге вываливает ту же самую ошибку без исправления;
— Выгрузка базы в Dt –файл и загрузка его в чистую базу – ошибка не исчезает;
— Выгрузка базы в Dt –файл и загрузка в файловый вариант – ошибка не исчезает;
— Установка Postgre и загрузка данных туда из Dt –файла, снова выгрузка в Dt –файл и загрузка в базу на SQL север;
— Тестирование встроенным проверщиком утилитой chdbfl — тоже ничего не нашло и ошибку не исправило.
При всех этих вариантах структура базы переносилась с ошибкой и ничего не менялось.
Что помогло
купили обработку:
Однако, в ней нет инструкции, что и как, по чату с разработчиком удалось восстановить целостность базы данных. Обработка помогла, база восстановлена. Рекомендую провести восстановление на копии базы, А затем, когда уже будут готовые текстовые файлы с исправленным содержимым для DBNames и СхемаБазы — просто обновить эти таблицы из этих файлов и после сделать запрос: sp_rename _ReferenceХХXX, _ReferenceYYYY — где ХХХХ номер с задвоением таблиц, YYYY — следующий свободный порядковый номер в таблице имен.
Если ошибок несколько, то по каждой надо отдельно вносить корректировки.
Вносить корректировки лучше через автопоиск и автозамену, т.к. малейшие неточности приведут к тому, что при открытии базы получите надпись «Ошибка открытия потока» и восстановить базу можно будет только с бэкапа SQL
За тем, как именно это делается обращайтесь к разработчику или пишите в личку, вышлю свою инструкцию что и как делал.
Благодарю помогло. Но таки поправь в статье — «P.s. после выполнения указанных действий также рекомендую удалить-добавить базу в кластере, или перезапустить службу. » Заменить на п.10 Обязательно удалить/добавить ИБ в кластере .Если просто рестартовать сервер ошибки будут — проверил ((
Ну и еще «добавить реквизит к объекту и обновить БД» (этот пункт не пробовал, напишите в комментариях — вдруг это самый простой метод) — похоже что да, помогло на версии 8.3.16.1030
(8)»добавить реквизит к объекту и обновить БД» если несколько объектов то нужно к каждому добавить. Помогло на платформе 1С:Предприятие 8.3 (8.3.15.1747)
(8) у меня было 40! задублированных ссылочных кодов таблиц. Мне помогла выгрузка данных для перехода в сервис из битой базы и загрузка их в чистую базу. Платформа 8.3.16.1030
размер базы какой у вас?
(10) а где эти пункты меню?
(11) 5Гб
(12) В режиме предприятия: Администрирование — Сервис — Выгрузить данные для перехода в сервис. Если команда не видна — в верхнем углу шестеренка — Настройка действий. Там же и команда загрузки данных из сервиса. (11) База небольшая. Для больших баз конечно, наверное, проще возиться с добавлением атрибутов или действовать по плану (6), тут каждый выбирает что ему подходит
ну тогда можно и dt выгружать пробовать, у нас так не получится, поэтому сразу решили реквизитами пробовать исправлять
На мой взгляд не совсем корректное решение. Правильное:https://infostart.ru/public/1147114/
(16) ахаха ты просто скопировал коммент автора со своего поста и заменил ссылку? Обиделся шоль?)
(17) Очевидно да, он обиделся.
(16) Ответ на твой вопрос «Чем же решение Дмитрий74Чел корректней (правильней) чем решение user646807_kazako.a911? »
В решении от user646807_kazako.a911 предложено поменять UUID на произвольный. Не на правильный (которого -то и нет, т.к. проблема не в UUID), а на какой-то там любой.
Тем более сомнительна рекомендация «В файле «ConfigDumpInfo» UUID объекта можно не менять.». Т.е. в одном месте конфигурации у документа будет один идентификатор, а в другом — другой. На мой взгляд так получаем битую конфигурацию. То, что метод сработал на одной базе скорее всего является следствием лишь того, что в ней указанный документ не использовался.
В решении Дмитрий74Чел приведены несколько вариантов, как сложных (с заменой номеров объектов), так и простых и 100% безопасных (временное добавление объекту реквизита).
Может кто из гуру подскажет как быть в такой ситуации ?
Если в посте выше ошибка конкретно указывает на действительно существующие объекты где номер одинаковый, то у нас например вообще не понятно что именно не нравится конфигуратору и платформе…
«В процессе обновления информационной базы произошла критическая ошибка
по причине:
Ошибка SDBL:
Ошибка обновления конфигурации базы данных. Для одного ссылочного кода существует более одной таблицы в базе данных.
Имена таблиц с кодом 18: DataHistoryVersions, Reference18
Имена таблиц с кодом 19: DataHistoryLatestVersions, Reference19
Имена таблиц с кодом 20: DataHistoryMetadata, Reference20
Имена таблиц с кодом 21: DataHistorySettings, Reference21
Для исправления проблемы вы можете обратиться в службу технической поддержки.»
Я не наблюдаю в первых ссылках на всякие инструменты хранения истории хоть какой то нумерации, к тому же инструментарий хранения историй полностью выключен… 1С пока что работает под пользователем.
Добавление реквизитов к выше упомянутым справочникам вообще в принципе ничего не дает… Натолкните куда копать и как решать ? Платформа по сути ругается на все то что связано с инструментом истории данных…
направьте куда копать….
(20)
В моем случае помогло ПОМИМО добавки временных реквизитов к данным объектам еще смена режима совместимости в конфигураторе на «Версия 8.3.10»
Может кому то поможет… После данных манипуляций конфигурация обновилась без ошибок.
(21) полагаю, ключевое изменение здесь именно понижение версии совместимости. Т.е. по-сути вы просто отключили механизм проверки встроенный в 8.3.15
(22) на данный момент по-моему самый просто вариант «добавить реквизит к объекту и обновить БД». В вашем случае — добавить к каждому проблемному объекту.
Если остался интерес и «битая» база — попробуйте.