使用者组
创建资源用户组OLTP_GRP,将用户HR,OE加入此组:
BEGIN
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.create_consumer_group(
consumer_group => 'OLTP_GRP',
comment => '',
cpu_mth => 'ROUND-ROBIN'
);
dbms_resource_manager.submit_pending_area();
BEGIN
dbms_resource_manager_privs.grant_switch_consumer_group('HR', 'OLTP_GRP', false);
dbms_resource_manager_privs.grant_switch_consumer_group('OE', 'OLTP_GRP', false);
END;
END;
创建资源用户组BATH_GRP,将用户BI,SH加入此组:
BEGIN
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.create_consumer_group(
consumer_group => 'BATH_GRP',
comment => '',
cpu_mth => 'ROUND-ROBIN'
);
dbms_resource_manager.submit_pending_area();
BEGIN
dbms_resource_manager_privs.grant_switch_consumer_group('BI', 'BATH_GRP', false);
dbms_resource_manager_privs.grant_switch_consumer_group('SH', 'BATH_GRP', false);
END;
END;
将HR,OE的初始化用户组制定为OLTP_GRP
BEGIN
dbms_resource_manager.set_initial_consumer_group(
user => 'HR',
consumer_group => 'OLTP_GRP'
);
END;
BEGIN
dbms_resource_manager.set_initial_consumer_group(
user => 'OE',
consumer_group => 'OLTP_GRP'
);
END;
将BI,SH的初始化用户组制定为BATH_GRP
BEGIN
dbms_resource_manager.set_initial_consumer_group(
user => 'BI',
consumer_group => 'BATH_GRP'
);
END;
BEGIN
dbms_resource_manager.set_initial_consumer_group(
user => 'SH',
consumer_group => 'BATH_GRP'
);
END;
创建一个资源计划“MY_DAY_PLAN”,并对CPU进行资源分配:
BEGIN
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.create_plan( 'MY_DAY_PLAN', '');
dbms_resource_manager.create_plan_directive(
plan => 'MY_DAY_PLAN',
group_or_subplan => 'BATH_GRP',
comment => '',
cpu_p1 => NULL, cpu_p2 => 20, cpu_p3 => NULL, cpu_p4 => NULL,
cpu_p5 => NULL, cpu_p6 => NULL, cpu_p7 => NULL, cpu_p8 => NULL,
parallel_degree_limit_p1 => NULL,
active_sess_pool_p1 => NULL,
queueing_p1 => NULL,
switch_group => '',
switch_time => NULL,
switch_estimate => false,
max_est_exec_time => NULL,
undo_pool => NULL,
max_idle_time => NULL,
max_idle_blocker_time => NULL,
switch_time_in_call => NULL
);
dbms_resource_manager.create_plan_directive(
plan => 'MY_DAY_PLAN',
group_or_subplan => 'OLTP_GRP',
comment => '',
cpu_p1 => NULL, cpu_p2 => 80, cpu_p3 => NULL, cpu_p4 => NULL,
cpu_p5 => NULL, cpu_p6 => NULL, cpu_p7 => NULL, cpu_p8 => NULL,
parallel_degree_limit_p1 => NULL,
active_sess_pool_p1 => NULL,
queueing_p1 => NULL,
switch_group => '',
switch_time => NULL,
switch_estimate => false,
max_est_exec_time => NULL,
undo_pool => NULL,
max_idle_time => NULL,
max_idle_blocker_time => NULL,
switch_time_in_call => NULL
);
dbms_resource_manager.create_plan_directive(
plan => 'MY_DAY_PLAN',
group_or_subplan => 'OTHER_GROUPS',
comment => '',
cpu_p1 => NULL, cpu_p2 => NULL, cpu_p3 => 100, cpu_p4 => NULL,
cpu_p5 => NULL, cpu_p6 => NULL, cpu_p7 => NULL, cpu_p8 => NULL,
parallel_degree_limit_p1 => NULL,
active_sess_pool_p1 => NULL,
queueing_p1 => NULL,
switch_group => '',
switch_time => NULL,
switch_estimate => false,
max_est_exec_time => NULL,
undo_pool => NULL,
max_idle_time => NULL,
max_idle_blocker_time => NULL,
switch_time_in_call => NULL
);
dbms_resource_manager.create_plan_directive(
plan => 'MY_DAY_PLAN',
group_or_subplan => 'SYS_GROUP',
comment => '',
cpu_p1 => 100, cpu_p2 => NULL, cpu_p3 => NULL, cpu_p4 => NULL,
cpu_p5 => NULL, cpu_p6 => NULL, cpu_p7 => NULL, cpu_p8 => NULL,
parallel_degree_limit_p1 => NULL,
active_sess_pool_p1 => NULL,
queueing_p1 => NULL,
switch_group => '',
switch_time => NULL,
switch_estimate => false,
max_est_exec_time => NULL,
undo_pool => NULL,
max_idle_time => NULL,
max_idle_blocker_time => NULL,
switch_time_in_call => NULL
);
dbms_resource_manager.submit_pending_area();
dbms_resource_manager.switch_plan( plan_name => 'MY_DAY_PLAN', sid => 'orcl' );
END;
确认用户的初始化用户组:
conn /as sysdba
alter user hr account unlock identified by hr;
alter user oe account unlock identified by oe;
alter user bi account unlock identified by bi;
alter user sh account unlock identified by sh;
grant select on v_$session to hr,oe,bi,sh;
grant select on v_$mystat to hr,oe,bi,sh;
conn hr/hr
select resource_consumer_group from v$session where sid=(select sid from v$mystat where rownum=1);
conn bi/bi
select resource_consumer_group from v$session where sid=(select sid from v$mystat where rownum=1);
我们不仅可以通过指定用户与资源用户组的映射关系,从而指定用户所产生的session所属的用户组,我们还可以通过其他映射关系来指定session属于哪个用户组
资源管理器提供了很多种映射用户组的方法,比如我们可以指定某个特定的客户端计算机名称登录到数据库产生的session属于某个用户组,也可以指定通过某个特定的应用程序登录到数据库所产生的session属于某个用户组等
由于我们可以设置登录到操作系统的用户所对应的用户组(比如oracle对应os_grp组),同时设置登录数据库用户所对应的用户组(比如用户HR对应OLTP_GRP),因此就存在一个问题,当这两种设置存在矛盾时,应该怎么办?比如,我们以oracle用户登录操作系统,然后以HR用户登录到数据库,这时产生的session到底属于哪个用户组呢?
通过设定这些映射的优先级来解决这个问题,默认情况下,操作系统用户映射关系的优先级比数据库用户映射关系低
测试对CPU的限制
在hr和bi下分别运行死循环:
conn hr/hr
declare
i number;
j number;
begin
i := 0;
loop
j := sqrt(i);
i := i + 1;
end loop;
end;
conn bi/bi
declare
i number;
j number;
begin
i := 0;
loop
j := sqrt(i);
i := i + 1;
end loop;
end;
对并行度的限定
在没有对BATH_GRP进行限定之前:
conn sh/sh
select sid from v$mystat where rownum=1;
select /*+parallel(sales,6)*/ * from sales;
conn /as sysdba
select sid, qcsid, degree from v$px_session where qcsid=159;
对其限定后:
BEGIN
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.update_plan_directive(
plan => 'MY_DAY_PLAN',
group_or_subplan => 'BATH_GRP',
new_comment => '',
new_parallel_degree_limit_p1 => 3
);
dbms_resource_manager.submit_pending_area();
END;
conn sh/sh
select sid from v$mystat where rownum=1;
select /*+parallel(sales,6)*/ * from sales;
conn /as sysdba
select sid, qcsid, degree from v$px_session where qcsid=140;
可以看到,虽然只指定了并行度为6,但是使用资源管理器对其限定后,只产生3个从属进程
设置活动的会话数(session个数)
当用户组里某个用户所产生的会话数超过了session数的限定值时,如果还要再产生session,则会将session放入队列,直到当前正在活动的session变为不活动时,等待活动的session才开始活动,该队列为先进先出的规则,注意,并行执行时产生的从属进程不算作活动的session,我们可以控制试图活动的session在队列里存放的时间长度,这叫超时。如果在队列里的session等待时间超过指定的时间,则该session被切断。
对OLTP_GRP进行限定
conn /as sysdba
BEGIN
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.update_plan_directive(
plan => 'MY_DAY_PLAN',
group_or_subplan => 'BATH_GRP',
new_comment => '',
new_active_sess_pool_p1 => 2,
new_queueing_p1 => 5
);
dbms_resource_manager.submit_pending_area();
END;
以bi用户连入数据库,开两个会话,并运行死循环
conn bi/bi
declare
i number;
j number;
begin
i := 0;
loop
j := sqrt(i);
i := i + 1;
end loop;
end;
conn bi/bi
declare
i number;
j number;
begin
i := 0;
loop
j := sqrt(i);
i := i + 1;
end loop;
end;
开第三个session
conn bi/bi
ERROR:
ORA-07454: queue timeout, 5 second(s), exceeded
select sysdate from dual;
select sysdate from dual
*
ERROR at line 1:
ORA-07454: queue timeout, 5 second(s), exceeded
将其中一个session,kill掉
select sysdate from dual;
产生UNDO的数量
conn /as sysdba
grant select on dba_objects to hr;
conn hr/hr
create table test as select * from dba_objects;
conn /as sysdba
BEGIN
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.update_plan_directive(
plan => 'MY_DAY_PLAN',
group_or_subplan => 'OLTP_GRP',
new_comment => '',
new_undo_pool => 1
);
dbms_resource_manager.submit_pending_area();
END;
超出了限制,报错。
update test set OBJECT_NAME=lpad('abc',100);
update test set OBJECT_NAME=lpad('abc',100)
*
ERROR at line 1:
ORA-30027: Undo quota violation - failed to get 60 (bytes)
估计执行时间的上限
当session还没开始较长时间的操作之前就被终止
conn hr/hr
create table test as select * from dba_objects;
conn /as sysdba
BEGIN
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.update_plan_directive(
plan => 'MY_DAY_PLAN',
group_or_subplan => 'OLTP_GRP',
new_comment => '',
new_max_est_exec_time => 1
);
dbms_resource_manager.submit_pending_area();
END;
conn hr/hr
select count(*) from test;
ERROR at line 1:
ORA-07455: estimated execution time (2 secs), exceeds limit (1 secs)
使用者组切换
当session执行时间的上限超过了指定的值后,切换到另一个组
conn /as sysdba
BEGIN
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.update_plan_directive(
plan => 'MY_DAY_PLAN',
group_or_subplan => 'OLTP_GRP',
new_comment => '',
new_switch_group => 'BATH_GRP',
new_switch_time => 10
);
dbms_resource_manager.submit_pending_area();
END;
以HR用户打开一个session,执行死循环
conn hr/hr
declare
i number;
j number;
begin
i := 0;
loop
j := sqrt(i);
i := i + 1;
end loop;
end;
打开监视器,10秒钟后发现以hr登录的session被切换到了BATH_GRP
设置空闲时间的上限
conn /as sysdba
BEGIN
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.update_plan_directive(
plan => 'MY_DAY_PLAN',
group_or_subplan => 'OLTP_GRP',
new_comment => '',
new_max_idle_time => 5,
new_max_idle_blocker_time => 10
);
dbms_resource_manager.submit_pending_area();
END;
conn hr/hr
连接到数据库后,什么都不干,超过5秒运行任何操作都报错如:
select sysdate from dual;
ERROR at line 1:
ORA-02396: exceeded maximum idle time, please connect again
conn hr/hr
update employees set first_name='aaa' where employee_id=108;
conn hr/hr
update employees set first_name='aaa' where employee_id=108;
当超过10秒后,第一个session会被中断,第二个session被执行