配置 SQL 级资源隔离(Oracle 模式)
Oracle 模式下 SQL 级资源隔离的配置方法。
磁盘性能校准
在控制 IOPS 资源隔离前,需要进行磁盘性能校准。
连接集群
使用 root
用户登录 obcluster 集群的 sys 租户。
obclient -h127.0.0.1 -P2883 -uroot@sys#obcluster -A
对集群内的所有 Zone 触发磁盘校准任务
根据业务使用场景,选择合适的命令,触发磁盘校准任务。对集群内的所有 Zone 触发磁盘校准任务。
ALTER SYSTEM RUN JOB "io_calibration" ZONE = zone1;
ALTER SYSTEM RUN JOB "io_calibration" ZONE = zone2;
ALTER SYSTEM RUN JOB "io_calibration" ZONE = zone3;
查看磁盘 I/O 校准状态
触发磁盘校准任务后,可以通过 GV$OB_IO_CALIBRATION_STATUS
或 V$OB_IO_CALIBRATION_STATUS
视图确认 I/O 校准状态。
SELECT * FROM oceanbase.V$OB_IO_CALIBRATION_STATUS;
输出结果如下:
obclient(root@sys)[(none)]> SELECT * FROM oceanbase.V$OB_IO_CALIBRATION_STATUS;
+--------------+----------+--------------+--------+----------------------------+----------------------------+
| SVR_IP | SVR_PORT | STORAGE_NAME | STATUS | START_TIME | FINISH_TIME |
+--------------+----------+--------------+--------+----------------------------+----------------------------+
| 10.43.139.79 | 2882 | DATA | READY | 2025-09-22 09:17:02.680581 | 2025-09-22 09:18:44.229574 |
+--------------+----------+--------------+--------+----------------------------+----------------------------+
1 row in set (0.041 sec)
磁盘 I/O 校准状态分为以下几种:
-
NOT AVAILABLE
:表示未开始 I/O 校准。 -
IN PROGRESS
:表示正在进行 I/O 校准。 -
READY
:表示 I/O 校准已完成。 -
FAILED
:表示 I/O 校准执行失败。
从查询结果可知,STATUS
字段的值为 IN PROGRESS
,表示正在进行磁盘 I/O 校准。待磁盘 I/O 校准完成后,STATUS
字段的值会变成 READY
,表示磁盘校准已完成,同时 FINISH_TIME
字段中会显示完成时间。
确认磁盘 I/O 校准是否生效
待磁盘 I/O 校准完成后,通过 V$OB_IO_BENCHMARK
视图确认磁盘 I/O 校准是否生效。
SELECT * FROM oceanbase.V$OB_IO_BENCHMARK;
输出结果如下:
obclient(root@sys)[(none)]> SELECT * FROM oceanbase.V$OB_IO_BENCHMARK;
+--------------+----------+--------------+-------+---------+-------+------+---------+
| SVR_IP | SVR_PORT | STORAGE_NAME | MODE | SIZE | IOPS | MBPS | LATENCY |
+--------------+----------+--------------+-------+---------+-------+------+---------+
| 10.43.139.79 | 2882 | DATA | READ | 4096 | 46039 | 179 | 347 |
| 10.43.139.79 | 2882 | DATA | READ | 8192 | 47301 | 369 | 338 |
| 10.43.139.79 | 2882 | DATA | READ | 16384 | 38659 | 604 | 413 |
| 10.43.139.79 | 2882 | DATA | READ | 32768 | 37156 | 1161 | 440 |
| 10.43.139.79 | 2882 | DATA | READ | 65536 | 25979 | 1623 | 616 |
| 10.43.139.79 | 2882 | DATA | READ | 131072 | 11809 | 1476 | 1374 |
| 10.43.139.79 | 2882 | DATA | READ | 262144 | 6354 | 1588 | 2528 |
| 10.43.139.79 | 2882 | DATA | READ | 524288 | 3347 | 1673 | 4804 |
| 10.43.139.79 | 2882 | DATA | READ | 1048576 | 1548 | 1548 | 10431 |
| 10.43.139.79 | 2882 | DATA | READ | 2097152 | 628 | 1256 | 25547 |
| 10.43.139.79 | 2882 | DATA | WRITE | 4096 | 8283 | 32 | 1934 |
| 10.43.139.79 | 2882 | DATA | WRITE | 8192 | 6800 | 53 | 2357 |
| 10.43.139.79 | 2882 | DATA | WRITE | 16384 | 5180 | 80 | 3092 |
| 10.43.139.79 | 2882 | DATA | WRITE | 32768 | 2280 | 71 | 7025 |
| 10.43.139.79 | 2882 | DATA | WRITE | 65536 | 1188 | 74 | 13477 |
| 10.43.139.79 | 2882 | DATA | WRITE | 131072 | 617 | 77 | 25982 |
| 10.43.139.79 | 2882 | DATA | WRITE | 262144 | 315 | 78 | 51300 |
| 10.43.139.79 | 2882 | DATA | WRITE | 524288 | 160 | 80 | 95181 |
| 10.43.139.79 | 2882 | DATA | WRITE | 1048576 | 56 | 56 | 154943 |
| 10.43.139.79 | 2882 | DATA | WRITE | 2097152 | 18 | 36 | 222080 |
+--------------+----------+--------------+-------+---------+-------+------+---------+
20 rows in set (0.010 sec)
将租户的 MAX_IOPS 和 MIN_IOPS 配置为有效值
说明:如果在创建租户所使用的 Unit 规格时,已将 MAX_IOPS
和 MIN_IOPS
设置为 16 KB 读对应的 IOPS 值,或者,不需要控制 IOPS 的资源隔离,请忽略本步骤。
完成磁盘校准后,在配置资源隔离计划前,需要保证租户的资源规格中 MAX_IOPS
和 MIN_IOPS
的值为有效值,这里的有效值指的是以 16 KB 读对应的 IOPS 值作为租户 IOPS 配置的参考值。
查看待进行资源隔离的租户的资源规格
执行以下命令,查看待进行资源隔离的租户的资源规格。
SELECT * FROM oceanbase.DBA_OB_UNIT_CONFIGS;
输出结果如下:
obclient(root@sys)[(none)]> SELECT * FROM oceanbase.DBA_OB_UNIT_CONFIGS;
+----------------+--------------------+----------------------------+----------------------------+---------+---------+-------------+---------------+---------------------+---------------------+-------------+
| UNIT_CONFIG_ID | NAME | CREATE_TIME | MODIFY_TIME | MAX_CPU | MIN_CPU | MEMORY_SIZE | LOG_DISK_SIZE | MAX_IOPS | MIN_IOPS | IOPS_WEIGHT |
+----------------+--------------------+----------------------------+----------------------------+---------+---------+-------------+---------------+---------------------+---------------------+-------------+
| 1 | sys_unit_config | 2025-06-16 17:12:20.916675 | 2025-06-16 17:12:20.916675 | 3 | 3 | 2147483648 | 2147483648 | 9223372036854775807 | 9223372036854775807 | 3 |
| 1002 | oracle_tenant_unit | 2025-06-17 18:52:31.184843 | 2025-06-17 18:52:31.184843 | 1 | 1 | 2147483648 | 6442450944 | 10000 | 10000 | 1 |
+----------------+--------------------+----------------------------+----------------------------+---------+---------+-------------+---------------+---------------------+---------------------+-------------+
2 rows in set (0.016 sec)
根据查询结果,如果该租户的 MAX_IOPS
和 MIN_IOPS
均为默认值 INT64_MAX
(9223372036854775807),则需要对租户可使用的 IOPS 资源重新进行规划。
查看租户id
use oceanbase
select * from dba_ob_tenants ;
输出信息如下:
obclient(root@sys)[oceanbase]> select * from dba_ob_tenants ;
+-----------+---------------+-------------+----------------------------+----------------------------+-------------------+---------------------------------------------+-------------------+--------------------+--------+---------------+--------+-------------+-------------------+------------------+---------------------+---------------------+---------------------+---------------------+--------------+----------------------------+----------+------------+-----------+
| TENANT_ID | TENANT_NAME | TENANT_TYPE | CREATE_TIME | MODIFY_TIME | PRIMARY_ZONE | LOCALITY | PREVIOUS_LOCALITY | COMPATIBILITY_MODE | STATUS | IN_RECYCLEBIN | LOCKED | TENANT_ROLE | SWITCHOVER_STATUS | SWITCHOVER_EPOCH | SYNC_SCN | REPLAYABLE_SCN | READABLE_SCN | RECOVERY_UNTIL_SCN | LOG_MODE | ARBITRATION_SERVICE_STATUS | UNIT_NUM | COMPATIBLE | MAX_LS_ID |
+-----------+---------------+-------------+----------------------------+----------------------------+-------------------+---------------------------------------------+-------------------+--------------------+--------+---------------+--------+-------------+-------------------+------------------+---------------------+---------------------+---------------------+---------------------+--------------+----------------------------+----------+------------+-----------+
| 1 | sys | SYS | 2025-06-16 17:12:20.944405 | 2025-06-16 17:12:20.944405 | RANDOM | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | NULL | MYSQL | NORMAL | NO | NO | PRIMARY | NORMAL | 0 | NULL | NULL | NULL | NULL | NOARCHIVELOG | DISABLED | 1 | 4.3.1.0 | 1 |
| 1005 | META$1006 | META | 2025-06-17 18:57:41.858963 | 2025-06-17 18:58:15.518730 | zone1,zone2,zone3 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | NULL | MYSQL | NORMAL | NO | NO | PRIMARY | NORMAL | 0 | NULL | NULL | NULL | NULL | NOARCHIVELOG | DISABLED | 1 | 4.3.1.0 | 1 |
| 1006 | oracle_tenant | USER | 2025-06-17 18:57:41.860025 | 2025-06-17 18:58:15.590459 | zone1,zone2,zone3 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | NULL | ORACLE | NORMAL | NO | NO | PRIMARY | NORMAL | 0 | 1758504122783716001 | 1758504122783716001 | 1758504122783716001 | 4611686018427387903 | NOARCHIVELOG | DISABLED | 1 | 4.3.1.0 | 1003 |
+-----------+---------------+-------------+----------------------------+----------------------------+-------------------+---------------------------------------------+-------------------+--------------------+--------+---------------+--------+-------------+-------------------+------------------+---------------------+---------------------+---------------------+---------------------+--------------+----------------------------+----------+------------+-----------+
3 rows in set (0.052 sec)
确认租户部署在哪些 OBServer 节点上
执行以下命令,确认租户部署在哪些 OBServer 节点上。
SELECT DISTINCT SVR_IP, SVR_PORT FROM oceanbase.CDB_OB_LS_LOCATIONS WHERE tenant_id = 1006;
输出结果如下:
obclient(root@sys)[oceanbase]> SELECT DISTINCT SVR_IP, SVR_PORT FROM oceanbase.CDB_OB_LS_LOCATIONS WHERE tenant_id = 1006;
+--------------+----------+
| SVR_IP | SVR_PORT |
+--------------+----------+
| 10.43.139.79 | 2882 |
| 10.43.231.92 | 2882 |
| 10.43.51.60 | 2882 |
+--------------+----------+
3 rows in set (0.020 sec)
确认待进行资源隔离的租户所在的 OBServer 节点上的磁盘校准值
执行以下命令,确认待进行资源隔离的租户所在的 OBServer 节点上的磁盘校准值,使用 16 KB 读的磁盘校准值作为该节点 IOPS 设置的上限值。
SELECT * FROM oceanbase.GV$OB_IO_BENCHMARK WHERE MODE='READ' AND SIZE=16384;
输出结果如下:
+--------------+----------+--------------+------+-------+-------+------+---------+
| SVR_IP | SVR_PORT | STORAGE_NAME | MODE | SIZE | IOPS | MBPS | LATENCY |
+--------------+----------+--------------+------+-------+-------+------+---------+
| 10.43.51.60 | 2882 | DATA | READ | 16384 | 38828 | 606 | 416 |
| 10.43.231.92 | 2882 | DATA | READ | 16384 | 38086 | 595 | 420 |
| 10.43.139.79 | 2882 | DATA | READ | 16384 | 38659 | 604 | 413 |
+--------------+----------+--------------+------+-------+-------+------+---------+
3 rows in set (0.013 sec)
根据查询结果,将获取到的各节点的磁盘校准值作为上限值来规划租户可用的 IOPS。由于集群内可能有多个租户部署在相同的 OBServer 节点,可以需要根据业务实际情况来分配这些 IOPS。
假设某集群下有两个租户,且两个租户都部署在相同的 OBServer 节点上,每个 OBServer 节点的 16 KB 读的磁盘 IOPS 基准值均相同,为 20000 IOPS,同时,预计两个租户的负载差不多,则可以将 20000 IOPS 平分给两个租户(具体可根据实际业务情况来为租户划分可用的 IOPS),即每个租户的 MAX_IOPS
和 MIN_IOPS
均配置为 10000,也可以根据业务考虑,将 MIN_IOPS
设置为小于 MAX_IOPS
的某个值。
查询当前 Oracle 租户对应的 unit
SELECT a.UNIT_CONFIG_ID, a.NAME AS UNIT_NAME, b.NAME AS POOL_NAME FROM oceanbase.DBA_OB_UNIT_CONFIGS a,oceanbase.DBA_OB_RESOURCE_POOLS b WHERE b.UNIT_CONFIG_ID=a.UNIT_CONFIG_ID;
输出结果如下:
+----------------+--------------------+--------------------+
| UNIT_CONFIG_ID | UNIT_NAME | POOL_NAME |
+----------------+--------------------+--------------------+
| 1 | sys_unit_config | sys_pool |
| 1002 | oracle_tenant_unit | oracle_tenant_pool |
+----------------+--------------------+--------------------+
2 rows in set (0.006 sec)
修改租户的 MAX_IOPS
和 MIN_IOPS
值
执行以下命令,修改租户的 MAX_IOPS
和 MIN_IOPS
值。
ALTER RESOURCE UNIT oracle_tenant_unit MAX_IOPS = 35000;
ALTER RESOURCE UNIT oracle_tenant_unit MIN_IOPS = 30000;
结束后, 执行 exit
退出数据库。
配置资源隔离计划
将不同的 SQL 条件分别绑定在 big_group
和 small_group
2 个资源组上,再通过资源管理计划 plan_a
来控制不同的 SQL 语句使用不同的 CPU 资源和 IOPS 资源。
使用 sys
用户登录 obcluster 集群的 oracle_tenant
租户
obclient -h127.0.0.1 -P2883 -usys@oracle_tenant#obcluster -A
创建资源隔离所需的 2 个资源组
创建资源隔离所需的 2 个资源组
调用 DBMS_RESOURCE_MANAGER
系统包中的 CREATE_CONSUMER_GROUP
子程序创建资源隔离所需的 2 个资源组。
obclient [SYS]> delimiter //
obclient [SYS]> BEGIN DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP(
consumer_group => 'big_group' ,
COMMENT => 'TP'
);
END; //
obclient [SYS]> BEGIN DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP(
consumer_group => 'small_group' ,
COMMENT => 'AP'
);
END; //
参数说明如下:
-
CONSUMER_GROUP
:定义资源组名称。 -
COMMENT
:填写资源组的备注信息。
查询 DBA_RSRC_CONSUMER_GROUPS
视图确认创建成功
创建成功后,可以查询 DBA_RSRC_CONSUMER_GROUPS
视图进行确认。
select * from DBA_RSRC_CONSUMER_GROUPS//
输出结果如下:
obclient(SYS@oracle_tenant)[SYS]> select * from DBA_RSRC_CONSUMER_GROUPS//
+-------------------+----------------+------------+-------------+--------------+----------+----------+--------+-----------+
| CONSUMER_GROUP_ID | CONSUMER_GROUP | CPU_METHOD | MGMT_METHOD | INTERNAL_USE | COMMENTS | CATEGORY | STATUS | MANDATORY |
+-------------------+----------------+------------+-------------+--------------+----------+----------+--------+-----------+
| 10000 | BIG_GROUP | NULL | NULL | NULL | TP | NULL | NULL | NULL |
| 10001 | SMALL_GROUP | NULL | NULL | NULL | AP | NULL | NULL | NULL |
+-------------------+----------------+------------+-------------+--------------+----------+----------+--------+-----------+
2 rows in set (0.050 sec)
创建资源管理计划
创建资源管理计划
调用 DBMS_RESOURCE_MANAGER
系统包中的 CREATE_PLAN
子程序,创建资源管理计划。
BEGIN DBMS_RESOURCE_MANAGER.CREATE_PLAN(
PLAN => 'plan_a');
END; //
参数说明如下:
-
PLAN
:定义资源管理计划名称。 -
COMMENT
:填写资源管理计划的备注信息。
查询 DBA_RSRC_PLANS
视图确认创建成功
创建成功后,可以查询 DBA_RSRC_PLANS
视图进行确认。
select * from DBA_RSRC_PLANS//
输出结果如下:
obclient(SYS@oracle_tenant)[SYS]> select * from DBA_RSRC_PLANS//
+---------+--------+---------------------+------------+-------------+----------------------+---------------------------+-------------+----------+----------+--------+-----------+
| PLAN_ID | PLAN | NUM_PLAN_DIRECTIVES | CPU_METHOD | MGMT_METHOD | ACTIVE_SESS_POOL_MTH | PARALLEL_DEGREE_LIMIT_MTH | QUEUING_MTH | SUB_PLAN | COMMENTS | STATUS | MANDATORY |
+---------+--------+---------------------+------------+-------------+----------------------+---------------------------+-------------+----------+----------+--------+-----------+
| NULL | PLAN_A | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
+---------+--------+---------------------+------------+-------------+----------------------+---------------------------+-------------+----------+----------+--------+-----------+
1 row in set (0.010 sec)
创建资源管理计划对应的资源管理计划内容
创建资源管理计划对应的资源管理计划内容
调用 DBMS_RESOURCE_MANAGER
系统包中的 CREATE_PLAN_DIRECTIVE
子程序,创建资源管理计划对应的资源管理计划内容,用于启用资源管理计划时,限制资源组所使用的 CPU 资源和 IOPS 资源。
obclient [SYS]> BEGIN DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE(
PLAN => 'plan_a',
GROUP_OR_SUBPLAN => 'big_group',
COMMENT => 'TP 优先',
MGMT_P1 => 90,
UTILIZATION_LIMIT =>60,
MIN_IOPS => 20,
MAX_IOPS => 100,
WEIGHT_IOPS => 20);
END; //
obclient [SYS]> BEGIN DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE(
PLAN => 'plan_a',
GROUP_OR_SUBPLAN => 'small_group' ,
COMMENT => 'AP 优先',
MGMT_P1 => 100,
UTILIZATION_LIMIT =>40,
MIN_IOPS => 10,
MAX_IOPS => 90,
WEIGHT_IOPS => 30);
END; //
参数说明如下:
-
PLAN
:指定该资源管理计划内容所关联的资源管理计划名。 -
GROUP_OR_SUBPLAN
:指定资源组。 -
COMMENT
:填写资源管理计划内容的备注信息,默认值为NULL
。 -
MGMT_P1
:指定系统满负载情况下,承诺分配给本资源组的 CPU 占比。默认值为100
。 -
UTILIZATION_LIMIT
:指定资源组使用的 CPU 资源的上限。该参数的默认值为100
,取值范围为 [0, 100]。100
表示最大可使用租户全部 CPU 资源。如果取值为40
则表示最大可使用租户 40% 的 CPU 资源。 -
MIN_IOPS
:用于出现 IO 争用时,资源组预留的 IOPS 资源,总和不超过 100,默认值为0
。 -
MAX_IOPS
:用于指定资源组最大可使用的 IOPS 资源,总和可以超过 100,默认值为100
。 -
WEIGHT_IOPS
:用于指定 IOPS 的权重值,总和可以超过100,默认值为0
。
查询 DBA_OB_RSRC_IO_DIRECTIVES
视图确认创建成功
创建成功,查询 DBA_OB_RSRC_IO_DIRECTIVES
视图进行确认。
select * from DBA_OB_RSRC_IO_DIRECTIVES//
输出结果如下:
obclient(SYS@oracle_tenant)[SYS]> select * from DBA_OB_RSRC_IO_DIRECTIVES//
+--------+------------------+-----------+----------+----------+-------------+
| PLAN | GROUP_OR_SUBPLAN | COMMENTS | MIN_IOPS | MAX_IOPS | WEIGHT_IOPS |
+--------+------------------+-----------+----------+----------+-------------+
| PLAN_A | BIG_GROUP | TP 优先 | 20 | 100 | 20 |
| PLAN_A | SMALL_GROUP | AP 优先 | 10 | 90 | 30 |
+--------+------------------+-----------+----------+----------+-------------+
2 rows in set (0.010 sec)
创建 SQL 资源隔离匹配规则
调用 DBMS_RESOURCE_MANAGER
系统包中的 SET_CONSUMER_GROUP_MAPPING
子程序,根据实际使用场景,创建 SQL 资源隔离匹配规则。
- 指定当用户执行的一条 WHERE 条件中包含
sys.t1.c3 = 3
的 SQL 语句时,该 SQL 语句绑定到名为big_group
的资源组上执行,并使用该资源组所限制的 CPU 资源和 IOPS 资源。
obclient [SYS]> BEGIN DBMS_RESOURCE_MANAGER.SET_CONSUMER_GROUP_MAPPING(
ATTRIBUTE => 'column',
VALUE => 'sys.t1.c3=3',
CONSUMER_GROUP => 'big_group');
END; //
- 指定当执行的一条 WHERE 条件中包含
t.c3=5
的 SQL 语句时,该 SQL 语句绑定到名为small_group
的资源组上执行,并使用该资源组所限制的 CPU 资源和 IOPS 资源。
obclient [SYS]> BEGIN DBMS_RESOURCE_MANAGER.SET_CONSUMER_GROUP_MAPPING(
ATTRIBUTE => 'column',
VALUE => 't1.c3=5',
CONSUMER_GROUP => 'small_group');
END; //
obclient [SYS]> delimiter ;
参数说明如下:
-
ATTRIBUTE
:指定属性类型,column
表示 SQL 级资源隔离,user
表示用户级 user 资源隔离,function
表示用户级 function 资源隔离,属性名称不区分大小写。 -
VALUE
:指定属性值,包括库名、表名、列名、常量值和用户名等信息。- 库名和用户名为可选,默认库名为当前库名(与用户名同名),如果未指定用户名,则对所有用户生效,包括当前租户中后续新建的用户。
- 表名、列名、常量值为必选项,并且每项只能指定一个值。在指定常量值时,仅支持指定为数值或字符串。
- 在指定表名、列名、用户名时,指定的表、列和用户必须存在。
- 在 OceanBase 数据库的 Oracle 模式中,语句执行成功后,库名、表名、列名和用户名均会自动调整为大写,如果需要保持为小写,可以通过添加双引号的方式避免其变成大写。
-
CONSUMER_GROUP
:指定需要绑定的资源组。表示当 SQL 命中VALUE
中所设置的匹配规则后,需要绑定在哪个资源组上执行该语句。当前仅支持绑定一个资源组。
为资源组启用合适的资源管理计划
由于不同的资源管理计划中,同一个资源组被限制的资源可能不同。您需要为资源组启用合适的资源管理计划。
ALTER SYSTEM SET resource_manager_plan = 'plan_a';
说明:如果不需要对资源进行限制,可以使用 ALTER SYSTEM SET resource_manager_plan = '';
语句禁用所有资源计划。
配置后的注意事项
- 资源隔离匹配规则添加后,如果删除了用户后再重建,则资源隔离匹配规则仍然适用。
- 资源隔离匹配规则添加成功后不是立即生效,预计可能在十秒内开始生效,具体以实际环境为准。
- 用户级资源隔离的优先级低于 SQL 级资源隔离。
- 资源隔离匹配规则添加后,目前仅在
SELECT
、INSERT
、UPDATE
、DELETE
等语句中生效,在 DDL 和 DCL 语句中不生效,在 PL 中也不生效。在 prepareStatement 中可以生效。