Oracle
Oracle

01 марта 2001 года

Как раздать пользователям приоритеты

Владимир Пржиялковский,
преподаватель УКЦ 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;

/

В этом случае, однако, вам придется позаботиться об автоматическом переключении плана при наступлении 9 утра и 6 вечера. Сделать это можно с помощью пакета DBMS_JOB. Чем это все хорошо

В начале статьи молчаливо предполагалось, что выгоды от возможности введения приоритетов для пользователей, работающих с Oracle, настолько очевидны, что не требуют пояснений. Тем не менее, об одной абсолютно выигрышной стороне такой организации работ хотелось бы сказать явно и отдельно. Дело в том, что заведение приоритетов способом, описанным только что, никак не затрагивает устройство вашего приложения. Прикладную систему менять не надо и ее код никак при этом не модифицируется. Все делается на совершенно другом, изолированном от прикладного, уровне.

Это значит, что в ваши старые приложения вы можете “вдохнуть новую жизнь”, не переписывая ни одной строки кода. Приятное свойство!

Что делать дальше

Как это часто бывает в Oracle, простые внешне идеи при реализации обрастают пугающим новичка изобилием технических подробностей, в которых отнюдь не просто разобраться. (Объективно это или субъективно – для меня пока загадка. Поделитесь своим мнением!. Есть они и в случае с диспетчером ресурсов. Любознательные имеют возможность ознакомиться с ними, заглянув в документацию по Oracle. Надо надеяться, что полнофункциональный пример, приведенный выше, сделает такое знакомство менее травмирующим.

За дополнительной информацией обращайтесь в Interface Ltd.


Interface Ltd.

Tel: 7+(095) 135-55-00, 135-25-19
E-mail: mail@interface.ru
http://www.interface.ru
Подготовили:oracle@interface.ru
kurmaz@interface.ru

Дата: 01.03.2001