Oracle DB リソース管理

DBのリソース管理は通常CPUの配分のみ指定可能。(ExadataではIOリソースも管理可能)
CPUの配分は、インスタンス毎、PDB毎に設定が可能

#インスタンス・ケージング（インスタンス毎の制限）
　CPU(OSから見えるvCPUを指す)リソースをインスタンス毎に上限設定可能
###設定手順
```SQL
-- 1.利用vCPUの上限設定。OSが認識するvCPUを超えて設定できない。RACの場合各インスタンス毎の上限。
--   OS上に複数DBインスタンスがある場合、CPU_COUNTの合計がvCPUを超えるかはチェックされない
--   未指定の場合、DB起動時にOSが認識するvCPUが自動的に設定される。
--   インスタンスの合計がvCPUを超えるとビジー時にCPUを取り合うことになる。
alter system set CPU_COUNT=2 sid='*';

-- 2.プラン設定
-- DEFAULT_PLANは事前定義されたプラン。自分で定義も可能だが、ここでは既存のプランを利用する場合のみ説明する。
-- 処理により詳細にCPUを配分する場合は新規に作成するが、インスタンス全体の上限を設定したい場合はこれで十分
alter system set resource_manager_plan=DEFAULT_PLAN sid='*';
-- 上記設定(未設定)の場合、自動メンテナンスウインドウがOPENするとそちらで定義したPLANになる。【重要】
-- 自動メンテナンス中でも同じプランを利用したい場合は下記の指定とする。
alter system set resource_manager_plan='FORCE:DEFAULT_PLAN' sid='*';
```

###確認用SQL
```SQL
-- 現在のプランの確認
show parameter resource_manager_plan
-- 下記は複数表示される
-- SELECT name, is_top_plan FROM v$rsrc_plan;

-- 定義済プランの一覧
select PLAN from DBA_RSRC_PLANS;

-- 自動メンテナンスタスクのウインドウは、デフォルトDEFAULT_MAINTENANCE_PLANとなっている
-- メンテナンスウインドウがOPENすると、CLOSEするまでリソースプランがこの定義に変更される
col window_name   format A26
col resource_plan format A26
select window_name,resource_plan from dba_scheduler_windows;

-- プランのCPU割り当て状況を確認。検索条件は調べたいプラン名に変更
col GROUP_OR_SUBPLAN format A20
select GROUP_OR_SUBPLAN,TYPE,MGMT_P1,UTILIZATION_LIMIT
 from DBA_RSRC_PLAN_DIRECTIVES where plan='DEFAULT_PLAN';

-- MGMT_P1は保障CPU使用率、UTILIZATION_LIMITは最大CPU使用率(未指定は100%)
-- SYS_GROUP    - SYSおよびSYSTEMユーザ
-- ORA_AUTOTASK - 自動メンテナンスタスク
-- OTHER_GROUPS - 上記以外の処理
-- 同一グループに複数セッション・タスクがあれば均等に分配

-- DEFAULT_PLANの内容(自動メンテナンスタスクは1%～90%の範囲で稼働)
GROUP_OR_SUBPLAN     TYPE              MGMT_P1 UTILIZATION_LIMIT
-------------------- -------------- ---------- -----------------
SYS_GROUP            CONSUMER_GROUP         90
OTHER_GROUPS         CONSUMER_GROUP          9
ORA$AUTOTASK         CONSUMER_GROUP          1                90

-- DEFAULT_MAINTENANCE_PLANの内容(自動メンテナンスタスクは5%～90%の範囲で稼働)
GROUP_OR_SUBPLAN     TYPE              MGMT_P1 UTILIZATION_LIMIT
-------------------- -------------- ---------- -----------------
SYS_GROUP            CONSUMER_GROUP         75
OTHER_GROUPS         CONSUMER_GROUP         20
ORA$AUTOTASK         CONSUMER_GROUP          5                90
```
+ [事前定義済コンシューマグループの一覧はこちらを参照](https://docs.oracle.com/cd/E60665_01/db121/ADMIN/dbrm.htm#CHDJAJHE)
+ [12.2ではPDB毎のCPU/メモリリソース制限がようやく可能に](http://www.oracle.com/technetwork/jp/database/articles/cosol-db12cr2/cosol-3-3849601-ja.html)

#CDBリソース・プラン(PDB毎の制限)
###設定可能リソース
マルチテナントDBの場合、PDB毎のリソース配分を設定可能。下記の3つの設定パラメータを用い、ROOTから設定。

|設定項目              |説明|
|:--------------------|:---|
|shares(共有)          |PDBの重み値。デフォルト1。PDBのshares/sum(PDBのshares)*100がCPU保障使用率(%)となる。|
|utilization_limit    |PDBのCPU最大使用率(%)を指定。未指定時は100%。|
|parallel_server_limit|PDBのパラレルサーバー最大使用率(%)。未指定時はutilization_limitの値。|
+ CDBのvCPUはCPU_COUNTで、パラレルサーバ数はparallel_server_limit初期化パラメータで設定された値となる。
    + 例：CPU_COUNT=2でutilization_limit=50なら、2x50%で100%(vCPU1つ全部)が最大使用率となる。

###CDBプラン作成例
```SQL
sqlplus / as sysdba
-- 0.現在のPDB構成確認
show pdbs
    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 PDB1                           READ WRITE NO
         4 PDB2                           READ WRITE NO

-- 1.PENDING AREA作成
exec DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA()
-- 2.CDB PLAN作成
exec DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN(plan=>'TESTPLAN',comment=>'1:2')
-- 3.PDB DIRECTIVE設定(pararell_server_limitを設定しない)
exec DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN_DIRECTIVE('TESTPLAN','PDB1', -
     shares=>1,utilization_limit=>50)
exec DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN_DIRECTIVE('TESTPLAN','PDB2', -
     shares=>2,utilization_limit=>90)
-- 4.PENDING AREA検証
exec DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA()
-- 5.PENDING AREA確定
exec DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA()
-- 6.CDB PLAN一覧表示
col plan format A25
col pluggable_database format A25
col shares format 99
col umax format 999
col pmax format 999
select plan,pluggable_database,shares,utilization_limit as umax,parallel_server_limit as pmax
  from dba_cdb_rsrc_plan_directives order by 1,2;
PLAN                      PLUGGABLE_DATABASE        SHARES UMAX PMAX
------------------------- ------------------------- ------ ---- ----
DEFAULT_CDB_PLAN          ORA$AUTOTASK                       90  100
DEFAULT_CDB_PLAN          ORA$DEFAULT_PDB_DIRECTIVE      1  100  100
DEFAULT_MAINTENANCE_PLAN  ORA$AUTOTASK                       90  100
DEFAULT_MAINTENANCE_PLAN  ORA$DEFAULT_PDB_DIRECTIVE      1  100  100
ORA$INTERNAL_CDB_PLAN     ORA$AUTOTASK
ORA$INTERNAL_CDB_PLAN     ORA$DEFAULT_PDB_DIRECTIVE
ORA$QOS_CDB_PLAN          ORA$AUTOTASK                       90  100
ORA$QOS_CDB_PLAN          ORA$DEFAULT_PDB_DIRECTIVE      1  100  100
TESTPLAN                  ORA$AUTOTASK                       90  100 --自動メンテナンスタスク用
TESTPLAN                  ORA$DEFAULT_PDB_DIRECTIVE      1  100  100 --定義されていないPDB用
TESTPLAN                  PDB1                           1   50      --CPU 1/3=33%～50%
TESTPLAN                  PDB2                           2   90      --CPU 2/3=66%～90%
-- 7.PLAN有効化
ALTER SYSTEM SET resource_manager_plan='FORCE:TESTPLAN';
-- 有効なCDB PLAN確認
SELECT name FROM v$rsrc_plan WHERE con_id = 1;
NAME
--------------------------------
TESTPLAN
-- PLANを定義しないとDEFAULT_CDB_PLANが用いられる。
```

###PLANが有効になっていることをテスト
```SQL
-- 前提：pdb1,pdb2がopenしていること
-- テストしやすいようCPU_COUNT=1とする
alter system set CPU_COUNT=1;
-- PDB1に接続変更
alter session set container=pdb1;
-- 下記の無限ループを実行
exec BEGIN while ( true ) loop NULL; end loop; END;
-- topコマンドで確認すると、CPU利用率の平均は 1/vCORE数*0.5*100%程度となる
-- CTRL-Cで中断
-- 別の端末を開きPDB2に接続
alter session set container=pdb2;
-- 上記と同じ無限ループを実行
-- topコマンドで確認すると、CPU利用率の平均は 1/vCORE数*0.9*100%程度となる
-- 無限ループを動かしたまま、pdb1に接続した端末でも無限ループを実行
-- topで見ると最初のoracleプロセスが平均66%、後から接続したoracleプロセスが平均33%程度となる
-- CTRL-Cで2つの処理を中断
-- パラレルサーバのテストは難しそうなので実施していない
```

###CDB PLANの無効化
```SQL
-- 無効化
ALTER SYSTEM SET resource_manager_plan = '';
-- 確認
SELECT name FROM v$rsrc_plan WHERE con_id = 1;
NAME
--------------------------------
ORA$INTERNAL_CDB_PLAN
```

###マルチテナントでの自動メンテナンスタスクの動作
+ 自動メンテナンスタスクはROOTでのみ実行【重要】
+ メンテナンスウインドウOPEN時のリソースプラン動作はインスタンス・ケージングと同様
+ 12.1ではROOTと全PDBに対して実行
+ 12.2ではPDB毎の制御用に下記の初期化パラメータが追加された
    + ENABLE_AUTOMATIC_MAINTENANCE_PDB
        + ROOT true:ROOTと全PDBに対し実行(デフォルト) false:PDB毎に設定可能(ROOTは常に有効)
        + PDB  true:有効 false:無効 - ROOTがfalseの場合のみPDB毎に設定可能
    + AUTOTASK_MAX_ACTIVE_PDBS - 自動メンテナンス・タスクを同時にスケジュールできるPDBの最大数を指定(デフォルト2)
+ 自動メンテナンスタスク用のshareがnullの場合、DB全体の20%が割当(少なくとも20%が確保される)

###自動メンテナンス用と定義されていないPDB用の変更手順
```SQL
-- 1.PENDING AREA作成
exec DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA()
-- 2.自動メンテナンス用の設定変更
--   自動で定義された値はほぼ制限なしなので上限を抑えることを推奨
exec DBMS_RESOURCE_MANAGER.UPDATE_CDB_AUTOTASK_DIRECTIVE('TESTPLAN', -
     new_shares=>1,new_utilization_limit=>20,new_parallel_server_limit=>20)
-- 3.定義されていないPDB用の設定変更
exec DBMS_RESOURCE_MANAGER.UPDATE_CDB_DEFAULT_DIRECTIVE('TESTPLAN', -
     new_shares=>1,new_utilization_limit=>40,new_parallel_server_limit=>40)
-- 4.PENDING AREA検証
exec DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA()
-- 5.PENDING AREA確定
exec DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA()
-- 6.TESTPLANの一覧表示
col plan format A25
col pluggable_database format A25
col shares format 99
col umax format 999
col pmax format 999
select plan,pluggable_database,shares,utilization_limit as umax,parallel_server_limit as pmax
  from dba_cdb_rsrc_plan_directives where plan='TESTPLAN' order by 1,2;

PLAN                      PLUGGABLE_DATABASE        SHARES UMAX PMAX
------------------------- ------------------------- ------ ---- ----
TESTPLAN                  ORA$AUTOTASK                   1   20   20
TESTPLAN                  ORA$DEFAULT_PDB_DIRECTIVE      1   40   40
TESTPLAN                  PDB1                           1   50
TESTPLAN                  PDB2                           2   90

-- 上記でテストすると、自動メンテナンスタスクはCPUが余っていても20%しか利用しない。
-- また、sum(shares)=4となるため、自動メンテナンスタスクはCPUがビジーでも20%割当られる。
```

#PDBリソース・プラン(PDB内の制限)
　PDB内(非CDBの場合はDB内)で更にコンシューマ・グループによるリソース制限がかけられる。
　PDBでは単一レベル、コンシューマーグループは8個まで、サブプランなしと非CDBよりスペックダウンしているが、これで十分だと思う。
  使ったことがないので、詳細はマニュアル参照。

#参考
[リソースマネージャ11gr2](http://www.oracle.com/technetwork/jp/database/enterprise-edition/db11gr2-03-134820-ja.pdf)
[ユーザが使用可能なCPUリソースを制限する方法](https://www.ashisuto.co.jp/db_blog/article/201710-resource-manager.html)

#更新履歴
2018/04/03 初版公開
2018/04/09 大幅改訂
2018/04/12 ROOTをCDBに修正(正式名はCDBルート)
2018/04/16 4/12修正を戻す(CDBはDB全体を表すため)
2018/05/01 12.2ではPDBのリソース制限が簡単にできるのでリンクを追記