gifts2017

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

Опубликовал Иван (newgluk) в раздел Администрирование - Защита, права, пароли

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, начали тестировать.

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

Связано это с тем, что регистр бухгалтерии на уровне СУБД хранится как несколько таблиц, и не во всех таблицах было проставлено значение общего реквизита (для просмотра структуры использовали обработку http://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С исправит ошибки , а еще лучше, реализует типовой механизм разделения по организациям в типовых конфигурациях.

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Алексей Алексеев (Aleksey_3) 06.09.14 23:23
А разве можно указать у пользователя "список областей"?
2. script Мальчинко (script) 07.09.14 01:47
Спасибо первопроходцам.
3. Алексей 1 (AlX0id) 07.09.14 13:52
(1) Aleksey_3, нет. Разве что хитровыдуманными комбинациями разделителей обходиться.

По теме: разделение - механизм в общем-то совсем простой, но сильно узкоспециализированный. Если пользователям нужно что-то быстро разделить - можно использовать. НО предупредить заранее о том, что можно будет поделить, а что - нельзя.
4. Алексей Алексеев (Aleksey_3) 07.09.14 14:54
(3) Вот и я о том же, т.е. смысла особого использовать разделитель именно как замену RLS нет, ну кроме если заводить 20 пользователей на каждую Область
Баба Маня _ ООО "1"
Баба Маня _ ООО "2"
Баба Маня _ ИП
и т.п.

Т.е. это вещь в себе, и 1С сделали именно для себя (ну или мы еще не доросли до этой музыки).
5. ффф ыыы (zqzq) 08.09.14 10:19
Производились замеры производительности базы без RLS и с RLS по организациям? А то может и проблем особых нет, и не надо было ничего изобретать.
6. Allexey (alex_4x) 08.09.14 10:23
За статью спасибо.
Жаль что в 1С делают такие кривые механизмы платформы.
7. Алексей 1 (AlX0id) 08.09.14 10:36
(4) Aleksey_3,
Ну как вещь в себе.. Надо мне справочник поделить - поделю именно разделителем ) Зачем мне гемор в виде продумывания системы ролей в таком случае?
А то, что люди хотят взять очень сложную систему типа УПП и на раз-два поделить все ее данные одним разделителем, да еще и иметь при этом общие области данных.. Ну не удивительно, что ничего не получилось..
8. Maxim Kolkin (the1) 08.09.14 11:36
(0) А на предыдущем Инфостарт.Конф так красиво все расписывалось... Хотя все-таки делался акцент на привязку к облакам.
9. Дмитрий Романовский (vdscom) 08.09.14 14:29
приходилось ранее использовать механизм разделения данных - режим "Независимо и совместно" - как раз по вышеописанной причине - совместный учет нескольких организаций в одной базе и нежелание использовать RLS. конфигурация "УТП для Украины".

столкнулся с рядом проблем (список формирую по памяти):
1. нельзя разделить объекты метаданных с предопределенными элементами (план счетов, например) - отсюда следует и невозможность разделения регистра бухгалтерии.
2. ошибки при проведении документов в режиме управляемых блокировок. пришлось этот режим отключить
3. некритичные ошибки в стандартных бух. отчетах (если память меня не подводит, связанные с чтением/сохранением настроек отчета)
4. поскольку регистры бухгалтерии не разделяются, то транзакционные ошибки могут возникать также и в том случае, когда пользователи разных организации пытаются одновременно провести документы
5. необходимо дорабатывать логическую структуру конфигурации - предопределенные элементы справочников, по мнению бухгалтеров разных организаций, должны иметь "свои" значения реквизитов
6. ну и просто периодически возникающие ошибки типа "Ошибка SDBL"
wondermaker; pt_olga; +2 Ответить 1
10. Алексей 1 (AlX0id) 08.09.14 14:38
(9) vdscom,
2. ошибки при проведении документов в режиме управляемых блокировок. пришлось этот режим отключить.

Это ж насколько вас РЛС достало, что аж в автоматический режим перешли? ) Имхо, лучше остаться на управляемых блокировках, но с РЛС, чем наоборот )
11. Дмитрий Романовский (vdscom) 08.09.14 15:47
(10) AlX0id,
автоматический режим - это вынужденная мера, предпринятая в ожидании того, что 1с исправит явные ошибки механизма разделения данных. почему вообще решил использовать режим разделения ?.. посчитал его удобным и перспективным, но не учел, что технология сырая и, к сожалению, 1с не сильно горит желаниям ее отлаживать.

даже с учетом тех недостатков, с которыми мне пришлось столкнуться (2.5 года назад примеров использования механизма разделения данных я в открытых источниках не нашел, поэтому все "шишки" набивал самостоятельно) - считаю, что в определенных (не массовых) случаях этот механизм можно применять
12. John Smith (PiccaHut001) 08.09.14 19:56
(11) vdscom, Впрочем, как и всегда, 1с облажалась.
13. BabySG (BabySG) 08.09.14 19:05
Никакого ошутимого ускорения не получилось бы.
Что разделитель, что организация - это отдельная колонка. Ну, не будет в RLS ограничения по организации, но в запросе к СУБД условие-то останется! Так что смысла перехода почти нет, не говоря о том, что "за вечер" это не сделать.
Восьмой; zqzq; +2 Ответить 1
14. Алексей 1 (AlX0id) 08.09.14 21:30
(13) BabySG, ну если организация - это просто колонка, то разделитель - это индексированная колонка, так что ощутимая разница, собственно, есть.
А за вечер толком не сделать - это да.
15. BabySG (BabySG) 09.09.14 08:54
(14) AlX0id, индекс хорошо помогает, когда значение достаточно уникально. В случае подведение под это понятия "организация" - тут этим даже не пахнет. Поэтому выигрыша и не будет (а если учесть затраты на переделку УПП - то будет чистый проигрыш)
16. Алексей 1 (AlX0id) 09.09.14 14:36
(15) BabySG,
Не буду спорить - в конечном счете, чтобы прийти к истине в этом вопросе, нужно производить качественное тестирование, чем, как я понимаю, никто не собирается заниматься )
17. Алексей 1 (AlX0id) 09.09.14 20:50
ЗЫ. Ток что пришлось начать переделывать на РЛС сделанное разделение данных.. Захотелось пользователям общую папочку, понимаишь :(
18. DAnry (DAnry) 10.09.14 15:49
Интересная статья. Спасибо автору!
19. Иван (newgluk) 17.09.14 11:04
(5) zqzq,
RLS заметно подтормаживает, но до замеров с цифрами дело не дошло. Админы меняют платформу виртуализации, на Hyper-V по предварительным замерам существенно быстрее, но это уже совсем другая история.
20. Иван (newgluk) 17.09.14 11:08
(16) AlX0id,
Не буду спорить - в конечном счете, чтобы прийти к истине в этом вопросе, нужно производить качественное тестирование, чем, как я понимаю, никто не собирается заниматься )

протестировать не получилось - система, увы, неработоспособна)
21. Сергей Карташев (Elisy) 17.09.14 11:56
Описывал свой опыт
http://infostart.ru/public/290219/
Не нашел, как делать общие отчеты по всем разделителям данных. Никто не пробовал строить отчеты, где в один отчет берутся данные с разных разделителей?
22. Иван (newgluk) 17.09.14 12:29
(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 ). Если разделение включено, то данные с разных разделителей не попадут в отчет, в чем и смысл разделения, ИМХО.
23. BabySG (BabySG) 05.10.14 17:46
(0) Кстати, есть еще такой тонкий момент: пользователь, который может "видеть все", будет работать намного медленнее. Связано это с тем, что индексы просто тупо использоваться не будут.
24. Иван (newgluk) 10.10.14 08:42
(23) BabySG, может и не намного медленнее. Индексы вроде как используются. На документы, например, помимо кластеризованного индекса по разделителю и ссылке, создается некластеризованный только по ссылке. И при отключенном разделителе поиск идет по этим двум индексам. Причем именно Seek, а не Scan. Замедление определенное наверное есть, но не критичное, я даже не замерял какое.
25. Иван (newgluk) 10.10.14 09:01
(23) BabySG,
++хотя если накладывать какой-нибудь отбор (кроме как по ссылке), будет Scan c существенным увеличением времени выполнения. А замедление не заметили, поскольку в рабочую базу разделение не попало ...
26. Alex Il (alex_il) 01.06.15 13:57
(23) BabySG, Есть такое дело! У нас предприятие из 25 территориально-разнесенных филиалов, внедрили комплексный учет, сейчас 1с 8,2.19.68. Часть справочников общая - контрагенты, номенклатура и т.д., часть у каждого свои. Пользователи филиалов параметром сеанса устанавливают свой разделитель и видят только свое, главный офис через меню "изменить подразделение" может выбрать любой филиал либо "общий режим" в котором видно все. В общем режиме отчеты по регистру бухучета строятся оччччень медленно, пришлось шаманить индексы на уровне субд (постгри). Работает все отлично. Пользователей около 130 одновременно работают, база около 100 Гб.
27. Игорь Дзеса (Kamikadze) 17.11.15 11:10
Думаю вопрос как раз в раздел конференции разработчиков.