Использование механизма разделения данных вместо RLS






RLS, как известно, подтормаживает систему. 1С уже давненько реализовала механизм разделения данных, но до сих пор он не используется в типовых конфигурациях. Интересно, почему?
1.Преамбула.

Возникла необходимость организовать учет по двум организациям в одной ИБ. Ситуация не уникальная, но так сложилось, что наша сильно не типовая 250 гигобайтная УППшка работала довольно медленно, поэтому вместо RLS решили попробовать разделение данных. Что это такое, описано, например, здесь или здесь. Вкратце, если RLS дополняет условиями запросы SQL, то разделитель данных — это дополнительный столбец в таблицах на уровне СУБД, за счет чего механизм разделения должен работать пошустрее RLS.

Итак, в базу, где велся учет по ООО №1, необходимо перенести информацию из отдельной базы ООО №2 и организовать совместную работу. Прямо как на картинке:

Простые смертные работают только со своей ООО, а главбух иногда смотрит данные по двум юрлицам. В режиме доступа к обеим ООО можно только читать данные, поэтому главбух должен иметь возможность интерактивно переключаться между режимами «все читать»/»писать только по одной организации» и выбирать ООО (т.е. устанавливать значение общего реквизита) для проведения, например, расчета себестоимости.

2. Реализация

Платформа 8.2.19.90, без режима совместимости. СУБД — MSSQL Server 2008 R2 Standart.

Создали общий реквизит ОрганизацияРазделитель типа «число», согласились с предложением создать параметры сеанса, заполнили состав реквизита (включили несколько справочников, все документы, регистры накопления, бухгалтерии и расчета). Разделение данных — «Независимо и совместно». Значение параметра сеанса устанавливается из стандартных настроек пользователя в процедуре УстановкаПараметровСеанса в модуле сеанса:

Организация = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(глТекущийПользователь,"ОсновнаяОрганизация");
ПараметрыСеанса.ОрганизацияРазделительЗначение = Организация.ЗначениеРазделителя;

В интерфейсе главбуха сделали формочку с возможностью переключения между организациями и включения/выключения режима разделения:

 

При отключенном разделении, когда ПараметрыСеанса.ОрганизацияРазделительИспользование = Ложь, платформа отказывается записывать документы, вываливаясь с ошибками типа «ОшибкаSDBL: ожидается выражение (pos=12)», поэтому давать пользователю записывать документы в таком варианте нельзя. Для надежности, создали подписки на событие «Перед записью» для объектов, входящих в состав общего реквизита:

Если ПараметрыСеанса.ОрганизацияРазделительИспользование = Ложь Тогда
    #Если Клиент Тогда
        Предупреждение("Нельзя записать, т.к. разделение данных отключено!");
    #КонецЕсли
    Отказ = Истина;
КонецЕсли;

План действий у нас был такой: готовим конфигурацию-приемник ИБ №1, проставляем значения общего реквизита = 1, загружаем данные из ИБ №2, после загрузки для всех объектов с пустым (равным 0) значением разделителя устанавливаем ОрганизацияРазделитель = 2.

Конфигурацию подготовили,  возник вопрос, как установить значение общего реквизита для документов и их движений в закрытых периодах, причем быстро и без риска того, что полетят цифры в балансе? Через объектную модель 1С записывать разделитель отдельно от объекта невозможно, поэтому пришлось нарушить лицензионное соглашение  выкручиваться и писать запрос для MS SQL. Поскольку в составе общего реквизита много объектов, а таблиц в скуле по этим объектам еще больше, написали обработку, генерирующую запрос для SQL (для каждого объекта метаданных, входящего в состав разделителя, писали «update » + Имя_БД + «.dbo._» + ИмяТаблицы + » set _» + ПолеОбщийРеквизит + » = 1″;) 

Значение проставили, перенесли часть данных из ИБ №2, начали тестировать.

Результат разочаровал. Во-первых, проблемы с регистром бухгалтерии. При включенном разделении не видно аналитику:

Связано это с тем, что регистр бухгалтерии на уровне СУБД хранится как несколько таблиц, и не во всех таблицах было проставлено значение общего реквизита (для просмотра структуры использовали обработку //infostart.ru/public/74608/).

Хорошо, проставляем значение разделителя через MS SQL, аналитику видим. Теперь не работают отчеты. Оказывается, проблемы с запросами к виртуальным таблицам регистра бухгалтерии «Обороты» и «ОборотыДтКт»:

(Fld27033 — это как раз общий реквизит в таблице регистра бухгалтерии)

Разделитель установлен во всех таблицах, это видно на уровне СУБД, в чем может быть ошибка, не понятно. Разворачиваем типовую пустую УПП, делаем описанные выше изменения в конфигурации, вводим пару документов (в этом варианте платформа сама проставляет значение разделителя во всех таблицах регистра бухгалтерии), но ошибки воспроизводятся. Плохо, но исключаем регистры бухгалтерии из состава общего реквизита, продолжаем тестирование.

Далее, выясняется что перестал работать механизм вытеснения у регистров расчета. Планы видов расчета мы не разделяли, пробуем искать проблему в таблицах  регистра расчетов и в перерасчетах. Проверяем, проставляем значение основного реквизита, делаем ТиИ — безрезультатно. 

Попутно, диагностируем проблему при записи в независимые регистры сведений из формы списка. При этом данные записываются, их можно увидеть после перезапуска. Проблема воспроизводится и на тестовой базе:

Регистры сведений «починить» путем манипуляций с SQL не получилось (значение разделителя во всех таблицах установлено), поэтому просто исключили их из состава общего реквизита. После нескольких дней экспериментов, неудачными оказываются и попытки восстановить работоспособность вытеснения. 

На этот момент принимаем решение выключить разделение данных и использовать-таки RLS. При установке разделения в «не использовать» натыкаемся на ошибки «Microsoft OLE DB Provider forSQL Server: CREATE UNIQUE INDEX terminated because a duplicate keywas found for index…». Т.е., вернуться в состояние до разделения так запросто не получается. Проблема с индексами таблиц перерасчетов, настроек хранения итогов и других. Дело в том, что в таблицах хранятся идентичные строки, отличающиеся только значением общего реквизита. При удалении общего реквизита появляются неуникальные записи. Придется удалить ненужные записи напрямую в MS SQL, примерно так (для таблицы перерасчетов):

use base;
ALTER TABLE _CRgRecalc1399
ADD id INT IDENTITY(1,1);
GO
DELETE FROM _CRgRecalc1399
WHERE id < (SELECT MAX(id)
FROM _CRgRecalc1399 AS T1
WHERE _CRgRecalc1399._RecorderTRef = T1._RecorderTRef and
_CRgRecalc1399.[_RecorderRRef] = T1.[_RecorderRRef] and
_CRgRecalc1399.[_CalcKindRRef] = T1.[_CalcKindRRef] and
_CRgRecalc1399.[_Fld1400RRef] = T1.[_Fld1400RRef] and
_CRgRecalc1399.[_Fld1401RRef] = T1.[_Fld1401RRef] and
_CRgRecalc1399.[_Fld1402RRef] = T1.[_Fld1402RRef]
);
GO
ALTER TABLE _CRgRecalc1399
DROP COLUMN id;

И только после чистки нескольких десятков таблиц удается выключить разделение данных. После выключения разделения никаких проблем нет. 

3. Выводы.

Теплилась надежда, что на 8.3 проблемы решены. Не поленились, проверили на 8.3.4.482 (с отключенным режимом совместимости). Смотрели на практически типовой УПП-шке, с изменениями в конфигурации только по общему реквизиту. На этой тестовой базе разделение включили до ввода информации, т.е. платформа должна была корректно записывать значение разделителя во все таблицы, самостоятельно напрямую в MS SQL ничего не писали.

Результат:  

  • Проблема с запросами к виртуальным таблицам «Обороты» и «ОборотыДтКт» воспроизводится. 

  • Проблема с вытеснением воспроизводится.

  • Проблема с записью в независимые регистры сведений воспроизводится.

  • + проблема с выключением разделения — одним нажатием кнопки от него избавится не получится!

Таким образом, заменить RLS новым механизмом у нас не получилось. Задумывался этот механизм, по всей видимости, для облачных сервисов, и в варианте использования разделяемых данных «независимо», может быть, разделение заработает, но нам нужна общая НСИ. Остается ждать, когда 1С исправит ошибки , а еще лучше, реализует типовой механизм разделения по организациям в типовых конфигурациях.

35 Comments

  1. Aleksey_3

    А разве можно указать у пользователя «список областей»?

    Reply
  2. script

    Спасибо первопроходцам.

    Reply
  3. AlX0id

    (1) Aleksey_3, нет. Разве что хитровыдуманными комбинациями разделителей обходиться.

    По теме: разделение — механизм в общем-то совсем простой, но сильно узкоспециализированный. Если пользователям нужно что-то быстро разделить — можно использовать. НО предупредить заранее о том, что можно будет поделить, а что — нельзя.

    Reply
  4. Aleksey_3

    (3) Вот и я о том же, т.е. смысла особого использовать разделитель именно как замену RLS нет, ну кроме если заводить 20 пользователей на каждую Область

    Баба Маня _ ООО «1»

    Баба Маня _ ООО «2»

    Баба Маня _ ИП

    и т.п.

    Т.е. это вещь в себе, и 1С сделали именно для себя (ну или мы еще не доросли до этой музыки).

    Reply
  5. zqzq

    Производились замеры производительности базы без RLS и с RLS по организациям? А то может и проблем особых нет, и не надо было ничего изобретать.

    Reply
  6. alex_4x

    За статью спасибо.

    Жаль что в 1С делают такие кривые механизмы платформы.

    Reply
  7. AlX0id

    (4) Aleksey_3,

    Ну как вещь в себе.. Надо мне справочник поделить — поделю именно разделителем ) Зачем мне гемор в виде продумывания системы ролей в таком случае?

    А то, что люди хотят взять очень сложную систему типа УПП и на раз-два поделить все ее данные одним разделителем, да еще и иметь при этом общие области данных.. Ну не удивительно, что ничего не получилось..

    Reply
  8. the1

    (0) А на предыдущем Инфостарт.Конф так красиво все расписывалось… Хотя все-таки делался акцент на привязку к облакам.

    Reply
  9. vdscom

    приходилось ранее использовать механизм разделения данных — режим «Независимо и совместно» — как раз по вышеописанной причине — совместный учет нескольких организаций в одной базе и нежелание использовать RLS. конфигурация «УТП для Украины».

    столкнулся с рядом проблем (список формирую по памяти):

    1. нельзя разделить объекты метаданных с предопределенными элементами (план счетов, например) — отсюда следует и невозможность разделения регистра бухгалтерии.

    2. ошибки при проведении документов в режиме управляемых блокировок. пришлось этот режим отключить

    3. некритичные ошибки в стандартных бух. отчетах (если память меня не подводит, связанные с чтением/сохранением настроек отчета)

    4. поскольку регистры бухгалтерии не разделяются, то транзакционные ошибки могут возникать также и в том случае, когда пользователи разных организации пытаются одновременно провести документы

    5. необходимо дорабатывать логическую структуру конфигурации — предопределенные элементы справочников, по мнению бухгалтеров разных организаций, должны иметь «свои» значения реквизитов

    6. ну и просто периодически возникающие ошибки типа «Ошибка SDBL»

    Reply
  10. AlX0id

    (9) vdscom,

    2. ошибки при проведении документов в режиме управляемых блокировок. пришлось этот режим отключить.

    Это ж насколько вас РЛС достало, что аж в автоматический режим перешли? ) Имхо, лучше остаться на управляемых блокировках, но с РЛС, чем наоборот )

    Reply
  11. vdscom

    (10) AlX0id,

    автоматический режим — это вынужденная мера, предпринятая в ожидании того, что 1с исправит явные ошибки механизма разделения данных. почему вообще решил использовать режим разделения ?.. посчитал его удобным и перспективным, но не учел, что технология сырая и, к сожалению, 1с не сильно горит желаниям ее отлаживать.

    даже с учетом тех недостатков, с которыми мне пришлось столкнуться (2.5 года назад примеров использования механизма разделения данных я в открытых источниках не нашел, поэтому все «шишки» набивал самостоятельно) — считаю, что в определенных (не массовых) случаях этот механизм можно применять

    Reply
  12. BabySG

    Никакого ошутимого ускорения не получилось бы.

    Что разделитель, что организация — это отдельная колонка. Ну, не будет в RLS ограничения по организации, но в запросе к СУБД условие-то останется! Так что смысла перехода почти нет, не говоря о том, что «за вечер» это не сделать.

    Reply
  13. PiccaHut001

    (11) vdscom, Впрочем, как и всегда, 1с облажалась.

    Reply
  14. AlX0id

    (13) BabySG, ну если организация — это просто колонка, то разделитель — это индексированная колонка, так что ощутимая разница, собственно, есть.

    А за вечер толком не сделать — это да.

    Reply
  15. BabySG

    (14) AlX0id, индекс хорошо помогает, когда значение достаточно уникально. В случае подведение под это понятия «организация» — тут этим даже не пахнет. Поэтому выигрыша и не будет (а если учесть затраты на переделку УПП — то будет чистый проигрыш)

    Reply
  16. AlX0id

    (15) BabySG,

    Не буду спорить — в конечном счете, чтобы прийти к истине в этом вопросе, нужно производить качественное тестирование, чем, как я понимаю, никто не собирается заниматься )

    Reply
  17. AlX0id

    ЗЫ. Ток что пришлось начать переделывать на РЛС сделанное разделение данных.. Захотелось пользователям общую папочку, понимаишь 🙁

    Reply
  18. DAnry

    Интересная статья. Спасибо автору!

    Reply
  19. newgluk

    (5) zqzq,

    RLS заметно подтормаживает, но до замеров с цифрами дело не дошло. Админы меняют платформу виртуализации, на Hyper-V по предварительным замерам существенно быстрее, но это уже совсем другая история.

    Reply
  20. newgluk

    (16) AlX0id,

    Не буду спорить — в конечном счете, чтобы прийти к истине в этом вопросе, нужно производить качественное тестирование, чем, как я понимаю, никто не собирается заниматься )

    протестировать не получилось — система, увы, неработоспособна)

    Reply
  21. Elisy

    Описывал свой опыт

    http://infostart.ru/public/290219/

    Не нашел, как делать общие отчеты по всем разделителям данных. Никто не пробовал строить отчеты, где в один отчет берутся данные с разных разделителей?

    Reply
  22. newgluk

    (21) Elisy,

    Описывал свой опыт

    http://infostart.ru/public/290219/

    Не нашел, как делать общие отчеты по всем разделителям данных. Никто не пробовал строить отчеты, где в один отчет берутся данные с разных разделителей?

    Я сделал возможность отключать разделение для пользователя (через параметры сеанса, вот формочка: http://infostart.ru/upload/iblock/5fc/%D0%A1%D1%82%D0%B0%D1%82%D1%8C%D1%81%D1­%8F%20%D1%80%D0%B8%D1%81%201.png ). Если разделение включено, то данные с разных разделителей не попадут в отчет, в чем и смысл разделения, ИМХО.

    Reply
  23. BabySG

    (0) Кстати, есть еще такой тонкий момент: пользователь, который может «видеть все», будет работать намного медленнее. Связано это с тем, что индексы просто тупо использоваться не будут.

    Reply
  24. newgluk

    (23) BabySG, может и не намного медленнее. Индексы вроде как используются. На документы, например, помимо кластеризованного индекса по разделителю и ссылке, создается некластеризованный только по ссылке. И при отключенном разделителе поиск идет по этим двум индексам. Причем именно Seek, а не Scan. Замедление определенное наверное есть, но не критичное, я даже не замерял какое.

    Reply
  25. newgluk

    (23) BabySG,

    ++хотя если накладывать какой-нибудь отбор (кроме как по ссылке), будет Scan c существенным увеличением времени выполнения. А замедление не заметили, поскольку в рабочую базу разделение не попало …

    Reply
  26. alex_il

    (23) BabySG, Есть такое дело! У нас предприятие из 25 территориально-разнесенных филиалов, внедрили комплексный учет, сейчас 1с 8,2.19.68. Часть справочников общая — контрагенты, номенклатура и т.д., часть у каждого свои. Пользователи филиалов параметром сеанса устанавливают свой разделитель и видят только свое, главный офис через меню «изменить подразделение» может выбрать любой филиал либо «общий режим» в котором видно все. В общем режиме отчеты по регистру бухучета строятся оччччень медленно, пришлось шаманить индексы на уровне субд (постгри). Работает все отлично. Пользователей около 130 одновременно работают, база около 100 Гб.

    Reply
  27. Kamikadze

    Думаю вопрос как раз в раздел конференции разработчиков.

    Reply
  28. Glebis

    Извините за поднятие старой темы.

    А почему при создании общего реквизита-разделителя не помогла установка свойства «значение заполнения» = 1? Зачем лесть в SQL для первоначального заполнения значения реквизита?

    Reply
  29. nvv1970

    ОМГ. Колоть орехи с помощью 1с не нужно. Используйте инструменты по назначению.

    Сама схема работы, описанная в статье, де-факто запрещена 1с в силу ряда причин. Но технически возможна. Филлипов Е. описывает в книге недопустимость такого подхода.

    А уж скулем без понимания похерить базу…

    РЛС не медленнее разделения. И то и другое делает добавки в запросы. Причем РЛС более гибкий и в части условий и в части индексирования. Создайте правильные роли, индексы и простейшие условия — все будет летать. 1с тут вообще не причем. Все в руках программиста.

    Reply
  30. newgluk

    (28) потому что (вы удивитесь) значение разделителя для уже существующих данных не заполнилось

    Reply
  31. newgluk

    (29) в какой книге Филиппов об этом пишет?

    Reply
  32. nvv1970

    Настольная книга эксперта

    3.11, последний абзац

    Reply
  33. newgluk

    (32) Филиппов описывает негативные последствия в части производительсти, которые собственно в этой ветке также обсуждались, см. выше. Причем эффекты возникнут при условии, что в базе работают пользователи с отключенным разделителем (в нашем случае, например аудиторы. Но они постоянно в базе не работают и вообще порой просто забирают всю базу к себе.).

    Но это неважно, поскольку на момент написания статьи данный подход вообще оказался неработоспособным. Может быть, сейчас платформа в этой части уже работает нормально. А кстати, может быть актуальная платформа сейчас уже создает дополнительные индексы без разделителя. С момента выпуска книги Филиппова прошло несколько лет, этот его пункт вполне может быть устаревшим.

    Reply
  34. nvv1970

    (33)

    А кстати, может быть актуальная платформа сейчас уже создает дополнительные индексы без разделителя.

    Нет, никто так не стал делать. И это правильно. Это нужно сделать полное дублирование всех индексов, просто капут. Выборочно — тоже не вариант.

    Не вижу причин не использовать под те же цели РЛС. Можно сделать отдельный индексированный реквизит. С ролями конечно придется повозиться.

    Reply
  35. newgluk

    (34)

    Можно сделать отдельный индексированный реквизит. С ролями конечно придется повозиться.

    вот не хочется возиться)

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *