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_GROUPand; - 
   
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_PRIVSPL/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.