После очередного обновления у нас повалился шквал заявок. Пользователи не могли работать. Сеансы завершались. Что коллеги только не пробовали, даже перешли на платформу 8.3.23.
В итоге начали глушить регламентные задания и нашли причину. Накануне трагедии была добавлена внешняя обработка с регламентными заданиями, и одно из этих заданий запускало создание версий для «Истории данных»
Код задания:
ИсторияДанных.ОбновитьИсторию();
На первый взгляд ломаться нечему… Но, когда регламент был выключен, все работало как прежде, правда, не создавались версии.
Для начала была создана обработка с одной единственной кнопкой, выполняющей код, написанный выше. При запуске вручную выпадала ошибка:
Текст ошибки:
«На сервере 1С:Предприятия произошла неисправимая ошибка. Приложение будет закрыто»
Дальше стало интереснее. Коллега решил проверить, рушится на всех объектах или на каком-то определенном. История у нас в базе, в которой это происходило, велась только по документам.
Он написал небольшой цикл, в котором оббегал Метаданные.Документы и добавлял в массив документы, запуская обновление истории данных по выбранным типам документов.
Синтаксис:
ОбновитьИсторию(<ВключитьМетаданные>, <ИсключитьМетаданные>, <ВыполнитьОбработкуПослеЗаписиВерсий>, <АвтоУдалениеИзОбработкиПослеЗаписиВерсий>)
Таким образом был выявлен один из типов документов, на котором происходило «Крушение». Это основной документ для той конфигурации, в которой запускался регламент.
Дальше коллега попытался запустить обновление, подавая ссылку одного документ данного типа. Обновление по ссылке одного документа работало без проблем.
И все бы ничего, но именно по данному документу и еще по одному История данных была включена в самой конфигурации более полугода назад, мало того, по данному документу было включено «Обновление истории данных сразу после записи».
Другие же документы, по которым проходило создание версий, были включены программно перед тем, как был создан регламент, убивающий rphost.
Дальше за проблему взялся я и полез в SQL. Я решил пройтись по таблицам Истории данных и посмотреть на «странности, которые бросятся в глаза»
Первым делом нужно было определить [_MetadataId] у документа, который приводит к катастрофе, сделать это было легко. Документ у меня был включен в конфигураторе, значит, мне его нужно было выключить программно и посмотреть в таблице [_DataHistorySettings] на [_MetadataId] у новой строки. Для программного отключения я использовал свою обработку Настройка состава "Истории данных"
Дальше я полез в таблицу [_DataHistoryMetadata], если кратко, в данной таблице хранится структура объекта, и при изменении в конфигураторе данного объекта создается новая запись с новым значением версии метаданных.
Хм… А почему у некого поля _Fld312 значение NULL по данному документу? Ранее я уже видел поля _Fldxxx в данной таблице, но в других конфигурациях, и стал догадываться, что это общий реквизит.
Далее я запустил первую попавшуюся под руку обработку по получению соответствия метаданных с наименованием в СУБД и вуаля.
Fld312 -> ОбщийРеквизит.ОбластьДанныхОсновныеДанные
Данную базу у нас обновляют непосредственно создатели конфигурации и, видимо, несколько месяцев назад они добавили новый общий реквизит.
Как будем лечить?
Вариант 1. Тушить пожар.
В обновлении истории подать исключенные метаданные.
Синтаксис:
ОбновитьИсторию(<ВключитьМетаданные>, <ИсключитьМетаданные>, <ВыполнитьОбработкуПослеЗаписиВерсий>, <АвтоУдалениеИзОбработкиПослеЗаписиВерсий>)
Вариант 2. Лечить проблему вопреки лозунгам фирмы 1С не лазить в SQL.
Я выбрал этот вариант.
Скрипт SQL:
update [Моя_БД].[dbo].[_DataHistoryMetadata] set _Fld312 = 0 where _Fld312 is NULL
Итог:
После этого регламент стал работать отлично.
Ошибка была отправлена в 1С.
Выводы:
1) Судя по всему, в фирме 1С не предусмотрели взаимодействие с общими реквизитами, в связи с чем если вы вдруг для каких-то «странных целей» добавите общие реквизиты, не забудьте прописать значение по умолчанию в SQL, иначе словите убийственный баг.
2) Не слушайте вендора, призывающего не лазить в SQL.
На этом статью заканчиваю. Надеюсь, сэкономил чье-то время на поиск подобной ситуации.
Полезные статьи по данной теме:
Версионирование объектов VS История данных