В распределенных информационных базах (РИБ) на платформе «1С:Предприятие 8» администраторы и разработчики иногда сталкиваются с крайне неприятной проблемой: после очередного сеанса обмена данными некоторые пользователи неожиданно «пропадают» из списка авторизации или теряют свои права. При этом в самой конфигурации (например, в «1С:Комплексная автоматизация 1.1» или «1С:Управление производственным предприятием 1.3») элементы справочника Пользователи остаются на месте. Все их персональные данные, настройки и реквизиты в карточке отображаются корректно, однако зайти в базу под этой учетной записью невозможно.
Временным решением обычно становится обычное пересохранение (перезапись) карточки пользователя в режиме «1С:Предприятие». После этого связь восстанавливается, но ровно до следующего цикла синхронизации данных. В этой статье мы подробно разберем, почему возникает этот сбой, проанализируем внутренние механизмы платформы и предложим несколько надежных способов решения проблемы раз и навсегда.
Для того чтобы понять природу этой ошибки, проанализируем, как именно платформа «1С:Предприятие» хранит информацию о пользователях. Здесь существует жесткое разделение на два независимых контура:
v8users. Доступ к этой таблице напрямую через прикладное решение закрыт, а управление записями осуществляется через конфигуратор или специализированные методы платформы. Каждый пользователь здесь имеет свой уникальный системный идентификатор — GUID (уникальный идентификатор).Пользователи. Этот объект создан разработчиками конфигурации в метаданных для того, чтобы связывать системных пользователей ИБ с конкретными объектами учета (документами, задачами, бизнес-процессами). Связь между элементом справочника и записью в таблице v8users осуществляется через скрытый реквизит справочника — обычно он называется ИдентификаторПользователяИБ и имеет тип данных УникальныйИдентификатор.Выясним, что происходит в момент выполнения обмена данными в РИБ. Справочник Пользователи является обычным объектом метаданных, поэтому его элементы регистрируются к обмену и успешно мигрируют между базами-узлами. Вместе с реквизитами справочника передается и значение реквизита ИдентификаторПользователяИБ (тот самый GUID связи).
Однако системные пользователи ИБ (записи из таблицы СУБД v8users) платформенным обменом РИБ **не переносятся**. На каждом узле распределенной базы существует своя локальная таблица v8users. Когда в базу-приемник «прилетает» измененный элемент справочника Пользователи из базы-источника, локальный элемент перезаписывается. Вместе с этим перезаписывается и реквизит ИдентификаторПользователяИБ — он заменяется на GUID, пришедший из другой базы.
В результате в базе-приемнике элемент справочника начинает ссылаться на GUID, которого физически нет в локальной таблице v8users этой базы. Платформа фиксирует разрыв связи: для нее пользователь «исчезает», а при попытке сопоставить текущего авторизованного пользователя с элементом справочника происходит сбой.
Самый надежный способ предотвратить затирание уникальных идентификаторов при синхронизации — исключить реквизит ИдентификаторПользователяИБ из обмена. Если базы имеют идентичную структуру, но пользователи администрируются локально в каждом узле, этот реквизит не должен мигрировать.
Разберем по шагам, как настроить правила обмена в программе «1С:Конвертация данных 2»:
Пользователи.ИдентификаторПользователяИБ.Если обмен настроен без использования внешних правил (на уровне стандартного механизма РИБ «по конфигурации»), можно воспользоваться программным переопределением при отправке или получении данных.
Если полностью исключить реквизит из обмена невозможно (например, по технологическим причинам конфигурации), мы можем прибегнуть к программной обработке события загрузки. Рассмотрим пример кода, который можно поместить в модуль объекта справочника Пользователи в обработчик события ПередЗаписью или использовать в правилах обмена в обработчике «После загрузки»:
Процедура ПередЗаписью(Отказ, РежимЗаписи)
// Исключаем обработку, если запись происходит под управлением обмена данными
Если ОбменДанными.Загрузка Тогда
// Нам необходимо сохранить локальный GUID связи, если элемент уже существовал в базе
Если Не ЭтоНовый() Тогда
ТекущийИдентификаторБД = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "ИдентификаторПользователяИБ");
// Если прилетевший GUID отличается от локального, возвращаем локальный назад
Если ЗначениеЗаполнено(ТекущийИдентификаторБД) И ИдентификаторПользователяИБ <> ТекущийИдентификаторБД Тогда
ИдентификаторПользователяИБ = ТекущийИдентификаторБД;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Этот простой алгоритм гарантирует, что при загрузке элемента справочника из файла обмена существующая локальная связь с пользователем операционной системы или СУБД не будет перезаписана «чужим» идентификатором.
В современных версиях конфигураций 1С (а также в обновленных версиях «1С:Комплексная автоматизация» на базе Библиотеки стандартных подсистем — БСП) предусмотрен штатный интерактивный инструмент для поиска и устранения рассинхронизации между справочником и системными пользователями.
Рассмотрим, как им воспользоваться:
Иногда сбой в таблице v8users происходит хаотично и не связан напрямую с файлами обмена. Это может быть вызвано некорректной работой драйверов СУБД, ошибками динамического обновления или блокировками транзакций. Проанализируем системные способы устранения подобных неполадок:
Params (где хранится файл параметров пользователей users.usr). Обновление платформы на актуальный стабильный релиз полностью решает эту системную проблему.1C:Enterprise 8 Server Agent.C:\Program Files\1cv8\srvinfo на Windows).reg_XXXX, за исключением конфигурационных файлов)..dt), после чего создайте новую чистую базу на сервере СУБД и загрузите файл обратно. Это позволяет пересоздать внутренние индексы СУБД и исправить структуру таблиц v8users и Params.Важное предупреждение для системных администраторов: ни в коем случае не пытайтесь вручную «сносить» или очищать таблицу v8users напрямую средствами MS SQL Server без предварительного создания полной резервной копии схемы данных. Записи в v8users тесно переплетены со строками настроек прав в таблице Params. Неаккуратное вмешательство на уровне SQL-запросов гарантированно приведет к полной неработоспособности авторизации в базе данных.