References
Oracle® Database Administrator's Guide 11g Release 1 (11.1)
- Chapter 25, "Managing Resource Allocation with Oracle Database Resource Manager"
Oracle® Database PL/SQL Packages and Types Reference 11g Release 1 (11.1)
-
DBMS_RESOURCE_MANAGER
-
CREATE_PENDING_AREA
-
SET_CONSUMER_GROUP_MAPPING
-
SUBMIT_PENDING_AREA
-
UPDATE_PLAN_DIRECTIVE
-
VALIDATE_PENDING_AREA
-
DBMS_RESOURCE_MANAGER_PRIVS
-
DBMS_SESSION
Oracle® Database Reference 11g Release 1 (11.1)
- Part I Initialization Parameters
- Part II Static Data Dictionary Views
- Part III Dynamic Performance Views
Overview
The OCM 11G Upgrade Objective is:
Set up and configure Resource Manager to control active sessions, number of I/Os, execution time..etc
My reading of this and the experience of the 11G exam leads me to say that there are several possible sub-tasks:
- Set up Resource Manager
- Configure Resource Plans to allocate CPU resources
- Control Active Sessions through
- Assigning them to Resource Groups
- Switching between Resource Groups
- Killing the session once resource limits have been exceeded
- Killing the SQL once resource limits have been exceeded
The MIXED_WORKLOAD_PLAN Resource Plan
Use a Sample Plan
Rather than create a resource plan from scratch, I used a sample predefined plan called
MIXED_WORKLOAD_PLAN
from
An Oracle-Supplied Mixed Workload Plan
.
Although it would be nice to go through the agony of creating a new resource plan via PL/SQL, I think that the OEM interface is sufficiently robust to create a resource plan painlessly.
Activate Resource Plans
According to
Enabling Oracle Database Resource Manager and Switching Plans
, the system parameter,
RESOURCE_MANAGER_PLAN
, needs to be set to a valid plan in order for Resource Plans to work:
ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = MIXED_WORKLOAD_PLAN SCOPE = BOTH;
Ensure that MIXED_WORKLOAD_PLAN Plan is Active
The current active plan can be determined in one of two (2) ways. The first is to query the dynamic view,
V$RSRC_PLAN
, to see what the top plan is:
SQL> SELECT * FROM v$rsrc_plan;
ID | NAME | IS_TOP_PLAN | CPU_MANAGED |
---|---|---|---|
11187 | DEFAULT_MAINTENANCE_PLAN | TRUE | ON |
11185 | ORA$AUTOTASK_SUB_PLAN | FALSE | ON |
11186 | ORA$AUTOTASK_HIGH_SUB_PLAN | FALSE | ON |
Or, by the system parameter,
RESOURCE_MANAGER_PLAN
,
SQL> show parameter resource_manager_plan
NAME | TYPE | VALUE |
---|---|---|
resource_manager_plan | string | MIXED_WORKLOAD_PLAN |
Or, if the maintenance window is currently active, the output is:
NAME | TYPE | VALUE |
---|---|---|
resource_manager_plan | string | SCHEDULER[0x2C0B]:DEFAULT_MAINTENANCE_PLAN |
Experiment in Switching
I want to see the switching between resource groups in action. The chosen resource plan,
MIXED_WORKLOAD_PLAN
, switches between the
INTERACTIVE_GROUP
and the
BATCH_GROUP
when limits are exceeded.
The following SQL is a resource hog:
select sum( dbms_random.value() ) from dual connect by level < 10000000;
The obvious user is
SH
who will need access to the following groups:
-
INTERACTIVE_GROUP
and; -
BATCH_GROUP
Change the Resource Group Mapping
Initially, the user,
SH
, is mapped to the
DEFAULT_CONSUMER_GROUP
:
SQL> SELECT username, initial_rsrc_consumer_group FROM dba_users WHERE username = 'SH';
USERNAME | INITIAL_RSRC_CONSUMER_GROUP |
---|---|
SH | DEFAULT_CONSUMER_GROUP |
Since the resource plan,
MIXED_WORKLOAD_PLAN
, does not mention the group,
DEFAULT_CONSUMER_GROUP
, explictly, users in this group are mapped to the rule for
OTHER_GROUPS
in the plan.
Instead of running in the
OTHER_GROUPS
, the user,
SH
, will be mapped to the
INTERACTIVE_GROUP
and thereby be affected by possible group switching. This is done through the
SET_CONSUMER_GROUP_MAPPING
procedure:
BEGIN dbms_resource_manager.clear_pending_area(); dbms_resource_manager.create_pending_area(); dbms_resource_manager.set_consumer_group_mapping( dbms_resource_manager.oracle_user, 'SH', 'INTERACTIVE_GROUP' ); dbms_resource_manager.submit_pending_area(); END;
Checking the initial resource consumer group is now correct via the
DBA_USERS
view:
SQL> SELECT username, initial_rsrc_consumer_group FROM dba_users WHERE username = 'SH';
USERNAME | INITIAL_RSRC_CONSUMER_GROUP |
---|---|
SH | INTERACTIVE_GROUP |
The user,
SH
, has to be granted access to the following groups:
-
INTERACTIVE_GROUP
; and -
BATCH_GROUP
.
Without giving the permission to switch into the
BATCH_GROUP
, we get an error as follows when I try using the
SWITCH_CURRENT_CONSUMER_GROUP
procedure:
SQL> connect sh/sh Connected. SQL> VARIABLE old_consumer_group VARCHAR2(32) SQL> EXEC DBMS_SESSION.switch_current_consumer_group( 'BATCH_GROUP', :old_consumer_group, TRUE ) Attempting to switch to BATCH_GROUP from current group BEGIN DBMS_SESSION.switch_current_consumer_group( 'BATCH_GROUP', :old_consumer_group, TRUE ); END; * ERROR at line 1: ORA-01031: insufficient privileges ORA-06512: at "SYS.DBMS_SESSION", line 130 ORA-06512: at line 1
Granting Group Switching Rights
According to Granting and Revoking the Switch Privilege ,:
Using the
DBMS_RESOURCE_MANAGER_PRIVS
PL/SQL package, you can grant or revoke the switch privilege to a user, role, or PUBLIC. The switch privilege enables a user or application to switch a session to a specified resource consumer group. It also enables the database to automatically switch a session to a consumer group specified in a session-to–consumer group mapping rule or specified in the SWITCH_GROUP parameter of a resource plan directive.Emphasis Mine
Thus, I need to grant the privilege to switch into the target groups to the
SH
user through the
GRANT_SWITCH_CONSUMER_GROUP Procedure
procedure as follows:
BEGIN dbms_resource_manager_privs.grant_switch_consumer_group( 'SH', 'INTERACTIVE_GROUP', FALSE ); dbms_resource_manager_privs.grant_switch_consumer_group( 'SH', 'BATCH_GROUP', FALSE ); END; /
Now, I test the ability of the
SH
user to switch between groups by again using the
SWITCH_CURRENT_CONSUMER_GROUP
procedure:
SQL> connect sh/sh Connected. SQL> select initial_rsrc_consumer_group from user_users; INITIAL_RSRC_CONSUMER_GROUP ------------------------------ INTERACTIVE_GROUP SQL> VARIABLE old_consumer_group VARCHAR2(32) SQL> exec DBMS_SESSION.switch_current_consumer_group( 'BATCH_GROUP', :old_consumer_group, TRUE ) PL/SQL procedure successfully completed. SQL> print old_consumer_group OLD_CONSUMER_GROUP -------------------------------------------------------------------------------- SQL> exec DBMS_SESSION.switch_current_consumer_group( 'BATCH_GROUP', :old_consumer_group, TRUE ) PL/SQL procedure successfully completed. SQL> print old_consumer_group OLD_CONSUMER_GROUP -------------------------------------------------------------------------------- SQL> exec DBMS_SESSION.switch_current_consumer_group( 'INTERACTIVE_GROUP', :old_consumer_group, TRUE ) PL/SQL procedure successfully completed. SQL> print old_consumer_group OLD_CONSUMER_GROUP -------------------------------------------------------------------------------- BATCH_GROUP
Note: The first switch says that the old consumer group is NULL even though the initial resource consumer group is not.
Running the Experiment in Group Switching
SQL for Experiment
The SQL to be tested is a guaranteed CPU hog:
select sum( dbms_random.value() ) from dual connect by level < 10000000;
Lower Thresholds for Group Switching
The supplied resource plan,
MIXED_WORKLOAD_PLAN
, switches to
BATCH_GROUP
after 60 seconds of CPU. I want to lower the switching threshold to five (5) CPU seconds by using
UPDATE_PLAN_DIRECTIVE
procedure:
BEGIN DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA; DBMS_RESOURCE_MANAGER.UPDATE_PLAN_DIRECTIVE ( plan => 'MIXED_WORKLOAD_PLAN', group_or_subplan => 'INTERACTIVE_GROUP', new_switch_time => 5, new_switch_for_call => TRUE); DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA; DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA; END; /
Result of Experiment
Confimed that the
SH
user is in the correct initial resource group:
select resource_consumer_group from v$session where username = 'SH';
RESOURCE_CONSUMER_GROUP |
---|
INTERACTIVE_GROUP |
Run the SQL:
SQL> select sum( dbms_random.value() ) from dual connect by level < 10000000; SUM(DBMS_RANDOM.VALUE()) ------------------------ 4998828.87 Elapsed: 00:01:58.72
Statistics from the Experiment
The data from the dynamic view,
V$RSRC_CONS_GROUP_HISTORY
, shows the group switching having occurred because the SQL exceeded the CPU quantum:
SELECT name, requests, consumed_cpu_time, switches_in_cpu_time, switches_out_cpu_time, sql_canceled, active_sess_killed FROM v$rsrc_cons_group_history WHERE sequence# = (SELECT MAX(sequence#) FROM V$RSRC_CONS_GROUP_HISTORY) AND name NOT LIKE 'ORA%' AND name <> '_ORACLE_BACKGROUND_GROUP_' ORDER BY name;
NAME | REQUESTS | CONSUMED_CPU_TIME | SWITCHES_IN_CPU_TIME | SWITCHES_OUT_CPU_TIME | SQL_CANCELED | ACTIVE_SESS_KILLED |
---|---|---|---|---|---|---|
BATCH_GROUP | 0 | 6168608 | 2 | 1 | 0 | 0 |
INTERACTIVE_GROUP | 2 | 9890216 | 1 | 2 | 0 | 0 |
OTHER_GROUPS | 26 | 16677997 | 0 | 0 | 0 | 0 |
SYS_GROUP | 5 | 6277055 | 0 | 0 | 0 | 0 |
Here we see two (2) switches out of the
INTERACTIVE_GROUP
and one (1) switch back in due to CPU threshold. And the reverse is true for the
BATCH_GROUP
. It would appear that the switch from
BATCH_GROUP
to
INTERACTIVE_GROUP
is due to the
SWITCH_AFTER_CALL
flag in the resource plan directive.
We confirm the resource consumer group after the call is back to the original:
SQL> select resource_consumer_group from v$session where username = 'SH';
RESOURCE_CONSUMER_GROUP |
---|
INTERACTIVE_GROUP |
Cancel the SQL If It Runs Too Long
Update Plan Directive
To cancel the SQL statement after running for more than five (5) CPU seconds, the
MIXED_WORKLOAD_PLAN
plan is updated to set the
NEW_SWITCH_GROUP
to
CANCEL_SQL
via the
UPDATE_PLAN_DIRECTIVE
procedure:
BEGIN DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA; DBMS_RESOURCE_MANAGER.UPDATE_PLAN_DIRECTIVE ( plan => 'MIXED_WORKLOAD_PLAN', group_or_subplan => 'INTERACTIVE_GROUP', new_switch_time => 5, new_switch_group => 'CANCEL_SQL'); DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA; DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA; END; /
Run the Experiment Again
The same SQL is used again with the following results:
SQL> select sum( dbms_random.value() ) from dual connect by level < 10000000; select sum( dbms_random.value() ) from dual connect by level < 10000000 * ERROR at line 1: ORA-00040: active time limit exceeded - call aborted Elapsed: 00:00:05.30
Statistics from the Experiment
The data from the dynamic view,
V$RSRC_CONS_GROUP_HISTORY
, shows the group switching having occurred because the SQL exceeded the CPU quantum:
SELECT name, requests, consumed_cpu_time, switches_in_cpu_time, switches_out_cpu_time, sql_canceled, active_sess_killed FROM v$rsrc_cons_group_history WHERE sequence# = (SELECT MAX(sequence#) FROM V$RSRC_CONS_GROUP_HISTORY) AND name NOT LIKE 'ORA%' AND name <> '_ORACLE_BACKGROUND_GROUP_' ORDER BY name;
NAME | REQUESTS | CONSUMED_CPU_TIME | SWITCHES_IN_CPU_TIME | SWITCHES_OUT_CPU_TIME | SQL_CANCELED | ACTIVE_SESS_KILLED |
---|---|---|---|---|---|---|
BATCH_GROUP | 0 | 0 | 0 | 0 | 0 | 0 |
INTERACTIVE_GROUP | 1 | 1765545 | 0 | 0 | 1 | 0 |
OTHER_GROUPS | 4 | 92 | 0 | 0 | 0 | 0 |
SYS_GROUP | 3 | 0 | 0 | 0 | 0 | 0 |
This shows that the statistics are reset (actually given a new
SEQUENCE#
) whenever the resource plan is updated.
Here we see the SQL being cancelled is being recorded for the
INTERACTIVE_GROUP
.
I cannot make sense of the
CONSUMED_CPU_TIME
value.
Cancel the Session If the SQL Runs Too Long
Update Plan Directive
To cancel the session whenever the SQL statement after running for more than five (5) CPU seconds, the
MIXED_WORKLOAD_PLAN
plan is updated to set the
NEW_SWITCH_GROUP
to
KILL_SESSION
via the
UPDATE_PLAN_DIRECTIVE
procedure:
BEGIN DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA; DBMS_RESOURCE_MANAGER.UPDATE_PLAN_DIRECTIVE ( plan => 'MIXED_WORKLOAD_PLAN', group_or_subplan => 'INTERACTIVE_GROUP', new_switch_time => 5, new_switch_group => 'KILL_SESSION'); DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA; DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA; END; /
Performance Problem
This change in Resource Plan Directive took a very long time (about 40 minutes to complete). The OEM top activity showed the following graph:
The ASH report for the period, 03:10 to 03:50, is attached as
ASH_report_1327656054538.html
. The Top User Events were:
Event | Event Class | % Event | Avg Active Sessions |
---|---|---|---|
resmgr:cpu quantum | Scheduler | 99.05 | 3.48 |
Run the Experiment Again
The same SQL is used again with the following results:
SQL> select sum( dbms_random.value() ) from dual connect by level < 10000000; select sum( dbms_random.value() ) from dual connect by level < 10000000 * ERROR at line 1: ORA-00041: active time limit exceeded - session terminated Elapsed: 00:00:05.80
Statistics from the Experiment
The data from the dynamic view,
V$RSRC_CONS_GROUP_HISTORY
, shows the group switching having occurred because the SQL exceeded the CPU quantum:
SELECT name, requests, consumed_cpu_time, switches_in_cpu_time, switches_out_cpu_time, sql_canceled, active_sess_killed FROM v$rsrc_cons_group_history WHERE sequence# = (SELECT MAX(sequence#) FROM V$RSRC_CONS_GROUP_HISTORY) AND name NOT LIKE 'ORA%' AND name <> '_ORACLE_BACKGROUND_GROUP_' ORDER BY name;
NAME | REQUESTS | CONSUMED_CPU_TIME | SWITCHES_IN_CPU_TIME | SWITCHES_OUT_CPU_TIME | SQL_CANCELED | ACTIVE_SESS_KILLED |
---|---|---|---|---|---|---|
BATCH_GROUP | 0 | 0 | 0 | 0 | 0 | 0 |
INTERACTIVE_GROUP | 1 | 3974203 | 0 | 0 | 0 | 1 |
OTHER_GROUPS | 9 | 6086496 | 0 | 0 | 0 | 0 |
SYS_GROUP | 6 | 5355213 | 0 | 0 | 0 | 0 |
And we see the statistic,
ACTIVE_SESS_KILLED
, has a value of one (1) for when the session was killed.
Restore Resource Plan to Original State
Used the following SQL to restore the
MIXED_WORKLOAD_PLAN
plan back to its original state:
BEGIN DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA; DBMS_RESOURCE_MANAGER.UPDATE_PLAN_DIRECTIVE ( plan => 'MIXED_WORKLOAD_PLAN', group_or_subplan => 'INTERACTIVE_GROUP', new_switch_time => 60, new_switch_group => 'BATCH_GROUP', new_switch_for_call => TRUE); DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA; DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA; END; /
Conclusion
This demonstration of the Resource Manager is far in excess of what is expected on the OCM 11G upgrade exam, but I wanted to explore as much as possible. I have demonstrated:
- Switching between groups
- Killing the SQL
- Killing the Session
This was only done for CPU.
The performance of the plan updating is problematic. Probably a bug in Oracle RDBMS 11.1.0.6.
The values displayed in
CONSUMED_CPU_TIME
of the
V$RSRC_CONS_GROUP_HISTORY
dynamic view do not make any sense.