こちらを参考に
Oracle® Database管理者ガイド 12cリリース1 (12.1) - 27 Oracle Database Resource Managerを使用したリソースの管理
Oracle Database Resource Managerとは
Oracle Database Resource Manager (リソース・マネージャ)を使用すると、システム・リソースやデータベース・リソースを求めて競合するデータベース内の複数のワークロードを管理できます。
ざっくりいうとDBが使用するリソースを制御できるOracle Databaseの機能
Enterprise Editionのみ使用可能で8iから導入されている
今回はCPUの制御についてざっくりと記載する。
予備知識
リソース・マネージャの要素について
リソース・コンシューマ・グループ:管理したい対象を1まとめにしたグループ。ユーザーやサービスなどをマッピングして管理対象としてグループに紐付ける。
リソース・プラン:リソース制御のルールを紐付けるプラン。実際の細かい制御方法はディレクティブで設定するので、リソース制御設定(ディレクティブ)と対象(コンシューマグループ)を管理する箱だと思えば良い。プランを切り替えることで、日中帯の優先度、夜間の優先度切替えなど、高度な運用ができる。
リソース・プラン・ディレクティブ:各コンシューマ・グループごとのリソース使用率を定義するルール。
ペンディング・エリア:リソース・プランを作成するときに使用する一時的な場所。
Maximum Utilization Limit:コンシューマ・グループごとに CPU リソースの使用率の上限を指定可能
インスタンス・ケージング:CPU_COUNT パラメータを使用して、インスタンスごとに CPU リソースの使用率を制限可能
検証1.何も制御をかけなかった場合の動作
セッションとプロセスIDを確認
SQL> conn unoki/unoki
Connected.
SQL> select sid, pid, spid, s.username, osuser, s.program from v$process p, v$session s where p.addr=s.paddr and s.PROGRAM like '%sqlplus%';
SID PID SPID USERNAME OSUSER PROGRAM
---------- ---------- ------------------------ ------------------------------ ------------------------------ ------------------------------------------------
166 38 22484 UNOKI oracle sqlplus@test.jp.test.com (TNS V1-V3)
90 43 32294 SYS oracle sqlplus@test.jp.test.com (TNS V1-V3)
SIDは166、SPIDは22484
高CPU処理実行
バズ・ライトイヤー並にカウントアップを無限の彼方へさあ行こう、させる
SQL> DECLARE
2 i NUMBER;
3 BEGIN
4 WHILE (1=1) LOOP
5 i := i + 1;
6 IF i > 1000000 THEN
7 i := 0;
8 END IF;
9 END LOOP;
10 END;
11 /
TOPで確認してみる
top - 17:00:35 up 70 days, 21:59, 4 users, load average: 1.63, 1.30, 1.38
Tasks: 333 total, 2 running, 330 sleeping, 0 stopped, 1 zombie
Cpu(s): 18.0%us, 1.1%sy, 0.0%ni, 79.5%id, 0.9%wa, 0.0%hi, 0.0%si, 0.5%st
Mem: 12320264k total, 10203968k used, 2116296k free, 407472k buffers
Swap: 6152492k total, 2016k used, 6150476k free, 5560928k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
22484 oracle 20 0 2249m 49m 44m R 99.5 0.4 0:43.98 oracle_22484_or
16705 oracle -2 0 2244m 19m 17m S 2.3 0.2 35:02.72 ora_vktm_orcl1
PID 22484がぶん回っていることが確認できる。
検証2.リソース・プランを有効化した場合
今回はoltpというユーザーを作成して、CPUを75%に制御したプランで検証する
まず検証に際して専用のユーザーを作成する
SQL> create user res_manager identified by oracle;
User created.
SQL> grant connect to res_manager;
Grant succeeded.
SQL> BEGIN
2 DBMS_RESOURCE_MANAGER_PRIVS.GRANT_SYSTEM_PRIVILEGE(
GRANTEE_NAME => ' 3 ^C
SQL> BEGIN
2 DBMS_RESOURCE_MANAGER_PRIVS.GRANT_SYSTEM_PRIVILEGE(
3 GRANTEE_NAME => 'res_manager',
4 PRIVILEGE_NAME => 'ADMINISTER_RESOURCE_MANAGER',
5 ADMIN_OPTION => FALSE);
6 END;
7 /
PL/SQL procedure successfully completed.
ユーザーの作成
SQL> create user oltp identified by oltp;
User created.
SQL> grant connect to oltp; --ずるした
Grant succeeded.
下記のコマンドでリソースプランを一括して作成
BEGIN
DBMS_RESOURCE_MANAGER.CLEAR_PENDING_AREA(); -- ペンディングエリアのクリア
DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA(); -- ペンディングエリアの作成
-- コンシューマ・グループの作成
DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP (
CONSUMER_GROUP => 'OLTP',
COMMENT => 'OLTP applications');
-- OLTPユーザーとOLTPコンシューマ・グループのマッピング
DBMS_RESOURCE_MANAGER.SET_CONSUMER_GROUP_MAPPING (
DBMS_RESOURCE_MANAGER.ORACLE_USER, 'OLTP', 'OLTP');
-- リソース・プランの作成
DBMS_RESOURCE_MANAGER.CREATE_PLAN(
PLAN => 'OLTP_PLAN',
COMMENT => 'More resources for OLTP applications');
-- リソース・プラン・ディレクティブの作成
DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE (
PLAN => 'OLTP_PLAN',
GROUP_OR_SUBPLAN => 'OLTP',
COMMENT => 'OLTP group',
UTILIZATION_LIMIT => 75);
-- リソース・プラン・ディレクティブの作成
-- マッピングで定義した以外の処理(OTHER_GROUPS)に対してのディレクティブ設定は必須
DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE (
PLAN => 'OLTP_PLAN',
GROUP_OR_SUBPLAN => 'OTHER_GROUPS',
COMMENT => 'Other group',
UTILIZATION_LIMIT => 25);
-- ペンディング・エリアの発行
DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA();
END;
/
-- 作成したプランを有効化
ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = 'OLTP_PLAN';
では、実行
top - 17:20:50 up 70 days, 22:20, 4 users, load average: 1.50, 1.35, 1.45
Tasks: 335 total, 2 running, 332 sleeping, 0 stopped, 1 zombie
Cpu(s): 12.7%us, 0.7%sy, 0.0%ni, 84.5%id, 1.5%wa, 0.0%hi, 0.1%si, 0.5%st
Mem: 12320264k total, 10213276k used, 2106988k free, 407492k buffers
Swap: 6152492k total, 2016k used, 6150476k free, 5553592k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
30915 oracle 20 0 2249m 32m 28m R 69.4 0.3 0:09.64 oracle_30915_or
3410 grid 20 0 616m 75m 15m S 2.3 0.6 2278:31 gipcd.bin
だいたい75%付近でCPU使用率が推移している
ではその他のユーザーではどうか
SQL> conn unoki/unoki
Connected.
SQL> DECLARE
i NUMBER;
BEGIN
WHILE (1=1) LOOP
i := i + 1;
IF i > 1000000 THEN
i := 0;
END IF;
END LOOP;
END;
TOP
top - 17:22:14 up 70 days, 22:21, 4 users, load average: 1.39, 1.36, 1.44
Tasks: 335 total, 1 running, 333 sleeping, 0 stopped, 1 zombie
Cpu(s): 4.5%us, 1.1%sy, 0.0%ni, 91.1%id, 2.7%wa, 0.0%hi, 0.0%si, 0.6%st
Mem: 12320264k total, 10212996k used, 2107268k free, 407496k buffers
Swap: 6152492k total, 2016k used, 6150476k free, 5553964k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
31261 oracle 20 0 2248m 31m 27m S 20.9 0.3 0:01.34 oracle_31261_or
3410 grid 20 0 616m 75m 15m S 2.3 0.6 2278:33 gipcd.bin
だいたい25%以下で推移している
ちなみにリソース・マネージャによって制御が発生した場合はresmgr:cpu quantumという待機が発生する
17:23:06 SQL> select INST_ID,SESSION_ID,SQL_ID,MODULE,EVENT from gv$active_session_history where SAMPLE_TIME > TO_DATE('2019/04/02 17:22:54','yyyy/mm/dd hh24:mi:ss') and session_id ='166';
INST_ID SESSION_ID SQL_ID MODULE EVENT
---------- ---------- ------------- ---------------------------------------------------------------- ----------------------------------------------------------------
1 166 gqucc4uk7yymd SQL*Plus resmgr:cpu quantum
1 166 gqucc4uk7yymd SQL*Plus resmgr:cpu quantum
1 166 gqucc4uk7yymd SQL*Plus resmgr:cpu quantum
1 166 gqucc4uk7yymd SQL*Plus
1 166 gqucc4uk7yymd SQL*Plus resmgr:cpu quantum
5 rows selected.
マッピングの優先順位も下記のようにつけれるみたいなので、次回検証したい(多分)
BEGIN
DBMS_RESOURCE_MANAGER.SET_CONSUMER_GROUP_MAPPING_PRI(
EXPLICIT => 1,
SERVICE_MODULE_ACTION => 2,
SERVICE_MODULE => 3,
MODULE_NAME_ACTION => 4,
MODULE_NAME => 5,
SERVICE_NAME => 6,
ORACLE_USER => 7,
CLIENT_PROGRAM => 8,
CLIENT_OS_USER => 9,
CLIENT_MACHINE => 10,
CLIENT_ID => 11);
END;
/