从12.2版本开始,Oracle引入了两个参数来限制PDB的磁盘IO量,分别是MAX_IOPS以及MAX_MBPS。
在CDB中存在多个PDB时,如果某一个PDB产生了大量的磁盘IO,那么很可能会影响到其它的PDB。现在可以通过设置MAX_IOPS来限制PDB每秒钟产生的IO请求次数,通过设置MAX_MBPS来限制PDB每秒钟产生多少兆的IO请求。如果同时设置了两个参数,那么两个参数就同时生效。
在不同的级别设置这两个参数会产生不同的效果:
1. 如果只在CDB root里设置这两个参数,那么设置的值就会在所有的PDB中生效。
2. 如果只在application root(这是12.2中的新特性)中设置了这两个参数,那么设置的值就会在所有的application PDB中生效。
3. 如果在CDB root或者PDB level中都设置了这两个参数,那么PDB level设置的值会有更高的优先级。
4. 这两个参数的默认值都是0,也就是默认不限制IO产生的数量。
注意:这两个参数不能设置在non-CDB中;并且只能限制PDB的磁盘IO量,不能限制CDB root的磁盘IO量。
对于PDB的critical IO,比如读写控制文件, 密码文件,重做日志以及DBWR写脏数据,是不受限制的。就算已经达到了上限,这些IO仍能够成功。虽然这些IO操作不受限制,这些IO也会被计算进PDB产生的IO次数及请求中。
在PDB的IO操作超过限制后,相应的Server Process会等待“resmgr: I/O rate limit”等待事件。
注意:虽然等待事件的名字是以resmgr开头的,很类似于resource manager的“resmgr: cpu quantum”等待事件;但是MAX_IOPS和MAX_MBPS并不需要启用resource manager plan。
另外,可以通过查询V$RSRCPDBMETRIC ,V$RSRCPDBMETRIC_HISTORY,DBA_HIST_RSRC_PDB_METRIC相关视图的IOPS, IOMBPS, IOPS_THROTTLE_EXEMPT, IOMBPS_THROTTLE_EXEMPT列来获知PDB的IO指标。
以下是一个真实的测试案列,为了更容易重现场景,我们设置了一个非常小的限制:
1、创建一个包含两个PDB的CDB,PDB的名字分别是PDB1和PDB2:
SQL> select con_id, name from v$pdbs;
CON_ID NAME
---------- ----------------------------------------
2 PDB$SEED
3 PDB1
4 PDB2
2、对pdb1限制每秒钟只可以做3次IO
SQL> alter session set container = pdb1;
Session altered.
SQL> alter system set max_iops = 3;
System altered.
SQL> alter pluggable database pdb1 open;
Pluggable database altered.
3、创建一个新用户,并且登录到pdb1上并创建一个大表来产生大量磁盘IO
SQL> grant dba to feng identified by feng;
Grant succeeded.
SQL> conn feng/[email protected]/pdb1
Connected.
SQL> create table feng.test as select * from dba_source;
<…此时HUNG住了…>
4、另外开启一个窗口连入到CDB root中
SQL> select username,state,con_id,event from v$session where con_id=3 and username='FENG';
USER STATE CON_ID EVENT
---- ------------------- ---------- --------------------------------------------------
FENG WAITING 3 resmgr: I/O rate limit
可以看到那个session正在等待resmgr: I/O rate limit,这就说明了对PDB的IO限制成功生效了。