O Resource Manager nos permite gerenciar recursos de hardware alocados para o nosso database, e assim como já era implementado em ambientes non-CDB’s, também temos essa opção para a arquitetura Multitenant. Com ele, podemos controlar, por exemplo, recursos de CPU Time, Degree de Paralelismo, Limite de Sessões em Idle, etc. Nesse artigo, vamos explorar a criação de 2 planos de Resource Manager, com “Shares Directives” distintos, para vermos o reflexo disso entre 2 PDBs. A tabela abaixo ilustra o cenário de teste:
Resource Manager Plan | PDB | Shares Directive |
BALANCEADO | HIPOFISE1 | 1 |
BALANCEADO | HIPOFISE2 | 1 |
DESBALANCEADO | HIPOFISE1 | 3 |
DESBALANCEADO | HIPOFISE2 | 1 |
Validando nossos PDB’s:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | [oracle@quiasma admin]$ sqlplus / as sysdba SQL*Plus: Release 18.0.0.0.0 - Production on Thu Jun 10 05:36:56 2021 Version 18.13.0.0.0 Copyright (c) 1982, 2018, Oracle. All rights reserved. Connected to: Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production Version 18.13.0.0.0 SQL> SHOW PDBS; CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 HIPOFISE2 READ WRITE NO 4 HIPOFISE1 READ WRITE NO |
Agora vamos conectar em cada PDB, e criar o objeto PL/SQL abaixo, que realiza operações aritméticas, consumindo assim o recurso de CPU, que será gerenciado pelos planos de Resource Manager:
1 2 3 4 5 6 7 8 9 10 11 12 | CREATE OR REPLACE PROCEDURE SYSTEM.HIT_CPU ( P_LOOP NUMBER ) IS V_BEGIN DATE; V NUMBER; BEGIN V_BEGIN := SYSDATE; FOR I IN 1..P_LOOP*10000 LOOP V := SQRT(I); END LOOP; DBMS_OUTPUT.PUT_LINE('ELAPSED TIME: ' || ROUND((SYSDATE-V_BEGIN)*24*60*60,2 )|| ' seconds'); END HIT_CPU; / |
PDB HIPOFISE1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | [oracle@quiasma admin]$ sqlplus system/oracle@HIPOFISE1 SQL*Plus: Release 18.0.0.0.0 - Production on Thu Jun 10 05:38:26 2021 Version 18.13.0.0.0 Copyright (c) 1982, 2018, Oracle. All rights reserved. Last Successful login time: Thu Jun 10 2021 05:36:48 -03:00 Connected to: Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production Version 18.13.0.0.0 SQL> CREATE OR REPLACE PROCEDURE SYSTEM.HIT_CPU ( P_LOOP NUMBER ) IS V_BEGIN DATE; V NUMBER; BEGIN V_BEGIN := SYSDATE; FOR I IN 1..P_LOOP*10000 LOOP V := SQRT(I); END LOOP; DBMS_OUTPUT.PUT_LINE('ELAPSED TIME: ' || ROUND((SYSDATE-V_BEGIN)*24*60*60,2 )|| ' seconds'); END HIT_CPU; / 2 3 4 5 6 7 8 9 10 11 12 Procedure created. |
PDB HIPOFISE2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | [oracle@quiasma admin]$ sqlplus system/oracle@HIPOFISE2 SQL*Plus: Release 18.0.0.0.0 - Production on Thu Jun 10 05:41:05 2021 Version 18.13.0.0.0 Copyright (c) 1982, 2018, Oracle. All rights reserved. Last Successful login time: Thu Jun 10 2021 05:38:26 -03:00 Connected to: Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production Version 18.13.0.0.0 SQL> CREATE OR REPLACE PROCEDURE SYSTEM.HIT_CPU ( P_LOOP NUMBER ) IS V_BEGIN DATE; V NUMBER; BEGIN V_BEGIN := SYSDATE; FOR I IN 1..P_LOOP*10000 LOOP V := SQRT(I); END LOOP; DBMS_OUTPUT.PUT_LINE('ELAPSED TIME: ' || ROUND((SYSDATE-V_BEGIN)*24*60*60,2 )|| ' seconds'); END HIT_CPU; / 2 3 4 5 6 7 8 9 10 11 12 Procedure created. |
Agora, conectado no CDB$ROOT, vamos criar o primeiro plano, onde a prioridade de CPU Time resource é igualmente distribuída entre os 2 PDBs:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | [oracle@quiasma admin]$ sqlplus / as sysdba SQL*Plus: Release 18.0.0.0.0 - Production on Thu Jun 10 05:42:27 2021 Version 18.13.0.0.0 Copyright (c) 1982, 2018, Oracle. All rights reserved. Connected to: Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production Version 18.13.0.0.0 SQL> EXEC DBMS_RESOURCE_MANAGER.CLEAR_PENDING_AREA(); PL/SQL procedure successfully completed. SQL> EXEC DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA(); PL/SQL procedure successfully completed. SQL> EXEC DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN('BALANCEADO', 'One share to HIPOFISE1 and HIPOFISE2'); PL/SQL procedure successfully completed. SQL> EXEC DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN_DIRECTIVE('BALANCEADO', 'HIPOFISE1', shares => 1); PL/SQL procedure successfully completed. SQL> EXEC DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN_DIRECTIVE('BALANCEADO', 'HIPOFISE2', shares => 1); PL/SQL procedure successfully completed. |
Criando o segundo plano, onde o PDB HIPOFISE1 tem prioridade 3 vezes maior que o PDB HIPOFISE2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | SQL> EXEC DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN('DESBALANCEADO', 'HIPOFISE1 tem prioridade'); PL/SQL procedure successfully completed. SQL> EXEC DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN_DIRECTIVE('DESBALANCEADO', 'HIPOFISE1', shares => 3); PL/SQL procedure successfully completed. SQL> EXEC DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN_DIRECTIVE('DESBALANCEADO', 'HIPOFISE2', shares => 1); PL/SQL procedure successfully completed. SQL> EXEC DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA(); PL/SQL procedure successfully completed. SQL> EXEC DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA(); PL/SQL procedure successfully completed. |
Confirmando a existência dos 2 planos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | SQL> col plan format a20 SQL> SELECT Plan from CDB_CDB_Rsrc_Plans WHERE CON_ID = 1 AND PLAN IN ('BALANCEADO','DESBALANCEADO') ORDER BY 1; PLAN -------------------- BALANCEADO DESBALANCEADO SQL> col pluggable_database format a30 SQL> SELECT PLAN, PLUGGABLE_DATABASE, SHARES FROM CDB_CDB_RSRC_PLAN_DIRECTIVES WHERE CON_ID = 1 AND PLAN IN ('BALANCEADO','DESBALANCEADO') ORDER BY 1, 2; PLAN PLUGGABLE_DATABASE SHARES -------------------- ------------------------------ ---------- BALANCEADO HIPOFISE1 1 BALANCEADO HIPOFISE2 1 BALANCEADO ORA$AUTOTASK BALANCEADO ORA$DEFAULT_PDB_DIRECTIVE 1 DESBALANCEADO HIPOFISE1 3 DESBALANCEADO HIPOFISE2 1 DESBALANCEADO ORA$AUTOTASK DESBALANCEADO ORA$DEFAULT_PDB_DIRECTIVE 1 8 rows selected. |
Habilitando o primeiro plano:
1 2 3 4 5 6 7 8 9 10 | SQL> ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = BALANCEADO; System altered. SQL> col name format a20 SQL> SELECT NAME FROM V$RSRC_PLAN WHERE CON_ID = 1; NAME -------------------- BALANCEADO |
Agora, vou abrir 2 sessões de Putty, logando como system no PDB HIPOFISE1, e mais 2 sessões conectando como system no PDB HIPOFISE2:

Com o “SET SERVEROUTPUT ON”, vou disparar a execução do comando “EXEC HIT_CPU(10000)” nas 4 sessões, o mais rápido possível, para rodarem em paralelo:

Podemos perceber que os tempos ficaram muito próximos (120,121,117 e 118 segundos), o que nos mostra que a distribuição de recurso de CPU Time foi uniforme aos 2 PDBs:

Alterando o plano do Resource Manager, para que passe a utilizar o que dá mais prioridade ao PDB HIPOFISE1:
1 2 3 4 5 6 7 8 9 10 11 | SQL> conn / as sysdba Connected. SQL> ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = DESBALANCEADO; System altered. SQL> SELECT NAME FROM V$RSRC_PLAN WHERE CON_ID = 1; NAME -------------------------------- DESBALANCEADO |
Disparando o mesmo teste, de forma simultânea, percebemos que as sessões do HIPOFISE1 tiveram prioridade (78 e 79 segundos), se comparadas com as sessões do HIPOFISE2 (116 e 117 segundos). Percebemos também que a diferença de tempo não é de 3 vezes, porém devemos considerar que uma vez finalizada o processamento necessário no HIPOFISE1, o Resource Manager pode engajar mais recursos para o processamento do HIPOFISE2. A priorização só acontece quando existe a concorrência de um contra o outro.

Alterando o CDB$ROOT para não utilizar nenhum plano customizado por nós:
1 2 3 4 5 6 7 8 9 10 11 12 | SQL> conn / as sysdba Connected. SQL> ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = ''; System altered. SQL> col name format a30 SQL> SELECT NAME FROM V$RSRC_PLAN WHERE CON_ID = 1; NAME ------------------------------ ORA$INTERNAL_CDB_PLAN |
Deletando os 2 planos usados neste artigo:
1 2 3 4 5 6 7 8 9 10 11 | SQL> begin DBMS_RESOURCE_MANAGER.CLEAR_PENDING_AREA(); DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA(); DBMS_RESOURCE_MANAGER.DELETE_CDB_PLAN('BALANCEADO'); DBMS_RESOURCE_MANAGER.DELETE_CDB_PLAN('DESBALANCEADO'); DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA(); DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA(); end; / 2 3 4 5 6 7 8 9 PL/SQL procedure successfully completed. |
Obs: Este procedimento foi criado pelo senhor Ahmed Baraka (www.ahmedbaraka.com) e foi apenas reproduzido por mim em um laboratório pessoal para fins de aprendizado.
Obrigado pelo post Bruno, top! Queria entender o que que eh* ‘shares’.
* desculpa nao instalei teclado pt-br no laptop do trabalho
Cheers from the UK
Obrigado por prestigiar o post, Antony!
Esse conceito dos Shares é meio confuso, mas vou tentar explicar de um modo simples:
Imagina que este é um número de proporção usado pelo Resource Manager, para distribuir os recursos do ambiente. Imaginemos que temos um PDB com valor share de 3, outro PDB com valor share de 3, e um último PDB com valor share de 1. Quanto maior este valor, mais prioridade o PDB terá. Neste exemplo, se você soma todos os Shares, temos o número 7 (3 +3 +1). Ou seja, o Oracle vai dividir os recursos do ambiente em 7, e distribuir estes recursos de acordo com o valor de cada PDB. Ou seja, o PDB 1 receberá 3/7 de recurso, o PDB 2 receberá 3/7 de recurso e o último PDB, que tem o menor número, receberá a menor proporção: 1/7.
Abraços e desculpe a demora em retornar!!
Bruno