|
|
|||||||||||||||||||||||||||||
|
Как раздать пользователям приоритетыИсточник: Interface Владимир Пржиялковский, преподаватель УКЦ Interface Ltd.
Не секрет, что уже достаточно давно фирма Oracle испытывает в области средств моделирования данных нечто вроде кризиса жанра (впрочем, не выделяясь в этом среди своих конкурентов). Взять хотя бы ее искания в этом направлении в продолжении последних лет, а заодно и результаты этих исканий. Замечая на протяжении длительного времени лишь ближние рыночные ориентиры, фирма сама подвела себя к нелегкой ситуации - перспективы в этой области неясны... В области же эксплуатационной то же самое поведение Oracle оказалось не столь пагубным, и наверстывание многого из того, что можно было бы сделать давным-давно, пока возможно, и реально продолжается с каждой последней версией. Словом - здесь лучше поздно, чем никогда, хотя в других областях может статься лучше никогда, чем поздно. Первое, например, касается очень простой задачи: как научиться выдавать пользователям, работающим с базой данных, приоритеты на процессорное время Oracle? Чтобы какой-нибудь из пользователей, запуская сложные запросы, не мешал работе остальных? Кое-что по части администрирования использования ресурсов системы известно и применяется на практике давно. Имеются в виду профили, которые можно приписывать пользователям, и которые позволяют ограничивать процессорное время и обращения к диску в рамках отдельных запросов или всего сеанса. Ну а если мы не хотим вводить абсолютные ограничения, а хотим ввести приоритеты? Такая возможность появилась в версии 8.1. Многие, наверное, обратили внимание на отсутствующие в более ранних версиях термины resource manager или consumer group, появившиеся формах OEM и в документации, но разобраться в них все было недосуг. Между тем, понять, о чем идет речь, вовсе нетрудно, что мы сейчас вместе и сделаем. Постановка задачи Допустим, мы хотим разбить пользователей на три группы:
Из этого, конечно, не следует, что, к примеру, прикладники будут всегда довольствоваться только 20-ю процентами. Если кроме них на машине - никого, то все 100% своего времени Oracle отдаст им. (Более сложные ситуации оставим пока в покое). Пусть, в свою очередь, прикладники делятся на
То есть, аналитики будут запускать свои задания практически в фоновом режиме и мешать работе операционистов почти не будут; время для них - не столь уж критично. Что для такой организации труда нужно сделать? Диспетчер ресурсов …Точнее было бы перевести "диспетчер ресурса" (resource manager), а еще точнее - "диспетчер ресурса процессорного времени", поскольку сейчас именно и только об этом ресурсе идет речь. В него входят:
Вот основные понятия, с которыми имеет дело диспетчер ресурсов. Группа потребителей (consumer group) - группа пользователей Oracle, с которой связывается та или иная гарантированная доля процессорного времени Ресурсный план (resource plan) - именованная схема распределения долей процессорного времени Рабочая область (pending area) - временная область, в которой, по технологии диспетчера ресурсов, собирается и проверяется на корректность ресурсный план, прежде чем его можно будет употреблять. Подготовительные действия Поначалу нужно выбрать пользователя-администратора, который будет создавать группы потребителей и ресурсные планы в рабочей области, расположенной у себя. Если этот пользователь по вашему выбору - не SYS и не SYSTEM (а к такому решению могут располагать организационные моменты), ему нужно дать право: EXEC DBMS_RESOURCE_MANAGER_PRIVS.GRANT_SYSTEM_PRIVILEGE( - 'SCOTT', 'ADMINISTER_RESOURCE_MANAGER', FALSE); EXEC DBMS_RESOURCE_MANAGER_PRIVS.GRANT_SYSTEM_PRIVILEGE( - Технология диспетчера организована так, что привилегия ADMINISTER RESOURCE MANAGER выдается и отбирается не обычными командами GRANT и REVOKE, а процедурно, на манер, как сделано выше. Теперь администратор диспетчера ресурсов должен создать рабочую область, где будет создаваться и готовиться план (см. предложения ниже): EXEC DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA(); Создаем план От имени администратора диспетчера выдаем: BEGIN DBMS_RESOURCE_MANAGER.CREATE_PLAN( 'DAILY', 'The plan for normal daily operations'); DBMS_RESOURCE_MANAGER.CREATE_PLAN( 'APPLICATIONS', 'The subplan for applications'); END; / Мы создали два плана: основной ('DAILY') и один подчиненный ('APPLICATIONS'). Подчиненных может быть и больше, а может и вовсе не быть. Создаем потребительские группы От имени администратора выдаем: BEGIN DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP( 'Database support', 'Database administration group'); DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP( 'Operators', 'Customer management department'); DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP( 'Analytics', 'System analysis group'); END; / Тут созданы три потребительские группы; из кода полностью ясно, как. Кроме указанных, системой автоматически создается группа OTHER_GROUPS, куда попадают все пользователи, не включенные в эти группы. Привязываем потребительские группы к плану Из созданной выше структуры для плана строим полноценный план, приписывая этой структуре потребительские группы: BEGIN DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE( 'DAILY ', 'Database support', 'Resource allocation for DBA group', cpu_p1 => 70); DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE( 'DAILY ', 'APPLICATIONS', 'Resource allocation for application users', cpu_p1 => 20); DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE( 'DAILY ', 'OTHER_GROUPS', 'For users not included to any group.', cpu_p1 => 10); END; / То же самое продолжаем для подчиненного плана: BEGIN DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE( 'APPLICATIONS', 'Operators', 'For general operators', cpu_p1 => 90); DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE( 'APPLICATIONS', 'Analytics', 'For the report writers', cpu_p1 => 10); END; / Итак, мы сформировали полный план в виде дерева с двумя уровнями. "Листья" дерева - потребительские группы, а промежуточное звено - подчиненный план. Передаем план в распоряжение системы Теперь мы готовы к тому, чтобы проверить сформированный план на правильность: может быть, в нем присутствуют циклы, отсутствующие группы или другие некорректности? Выдадим: EXEC DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA(); Если все в порядке (а в нашем случае должно быть так), план DAILY можно "сдавать в эксплуатацию": EXEC DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA(); Включаем в потребительские группы пользователей Oracle План готов к работе, но наши потребительские группы созданы только номинально: в них нет пользователей. По технологии, предлагаемой Oracle, пользователь системы может быть подключен к какой-нибудь группе только при наличии у него права SWITCH CONSUMER GROUP. Выдается оно также с помощью API, то есть одного из наших двух пакетов: BEGIN DBMS_RESOURCE_MANAGER_PRIVS.GRANT_SWITCH_CONSUMER_GROUP( 'SYSTEM', 'Database support', FALSE); DBMS_RESOURCE_MANAGER_PRIVS.GRANT_SWITCH_CONSUMER_GROUP( 'SCOTT', 'Operators', FALSE); DBMS_RESOURCE_MANAGER_PRIVS.GRANT_SWITCH_CONSUMER_GROUP( 'ADAMS', 'Analytics', FALSE); END; / И только теперь пользователей (из списка выше, коль скоро у них появилось на то право) можно фактически включать в группы: BEGIN DBMS_RESOURCE_MANAGER.SET_INITIAL_CONSUMER_GROUP( 'SYSTEM', 'Database support'); DBMS_RESOURCE_MANAGER.SET_INITIAL_CONSUMER_GROUP( 'SCOTT', 'Operators'); DBMS_RESOURCE_MANAGER.SET_INITIAL_CONSUMER_GROUP( 'ADAMS', 'Analytics'); END; / План начинает действовать Если теперь ADAMS запустит большой, но "несмертельный" запрос (например, на удвоение безындексной таблицы из полмиллиона записей), никто больше с Oracle не работает, и мы от имени SCOTT попросим выдать EMP, то увидим, что в нашем распоряжении отнюдь не 90% ресурсов. Чтобы план DAILY заработал, требуется поставить последнюю точку: ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = DAILY; Думаю, что радость пользователя SCOTT от времени реакции системы после этого с лихвой окупит его страдания от набирания всех [PL/]SQL-операторов, указанных выше ! Точку можно поставить и по-другому. Указание RESOURCE_MANAGER_PLAN = DAILY можно включить в файл INIT.ORA, и тогда план будет автоматически включаться в действие при старте СУБД, а не быть активным только до первого останова. Усовершенствования Описанную выше схему организации приоритетного доступа к процессорному времени можно развивать дальше. Вот некоторое, что приходит в голову сразу:
CREATE OR REPLACE TRIGGER resource_plan_on_startup AFTER STARTUP ON DATABASE DECLARE switch_to_daily varchar2(40) := 'ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = DAILY'; switch_to_nightly varchar2(40) := 'ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = NIGHTLY'; BEGIN IF (SYSDATE > TRUNC(SYSDATE) + 9 / 24) AND (SYSDATE < TRUNC(SYSDATE) + 18 / 24) THEN EXECUTE IMMEDIATE switch_to_daily; ELSE EXECUTE IMMEDIATE switch_to_nightly; END IF; END; / Чем это все хорошо В начале статьи молчаливо предполагалось, что выгоды от возможности введения приоритетов для пользователей, работающих с Oracle, настолько очевидны, что не требуют пояснений. Тем не менее, об одной абсолютно выигрышной стороне такой организации работ хотелось бы сказать явно и отдельно. Дело в том, что заведение приоритетов способом, описанным только что, никак не затрагивает устройство вашего приложения. Прикладную систему менять не надо и ее код никак при этом не модифицируется . Все делается на совершенно другом, изолированном от прикладного, уровне. Это значит, что в ваши старые приложения вы можете "вдохнуть новую жизнь", не переписывая ни одной строки кода. Приятное свойство! Что делать дальше Как это часто бывает в Oracle, простые внешне идеи при реализации обрастают пугающим новичка изобилием технических подробностей, в которых отнюдь не просто разобраться. (Объективно это или субъективно - для меня пока загадка. Поделитесь своим мнением!. Есть они и в случае с диспетчером ресурсов. Любознательные имеют возможность ознакомиться с ними, заглянув в документацию по Oracle. Надо надеяться, что полнофункциональный пример, приведенный выше, сделает такое знакомство менее травмирующим.
|
|