OceanBase 单机租户最多能支持多少分区?

作者何文超通过实例分析了OceanBase单机环境下租户创建分区时遇到的错误,指出单机允许的最大分区数量受内存限制,计算得出在给定条件下为30011。文章强调了合理分区的重要性,避免对业务产生影响。

OceanBase 单机租户允许创建的最大分区数是多少?作者通过分区超限错误排查,计算出单机允许创建的最大分区数量。

作者:何文超,爱可生南区交付服务部 DBA 团队成员,主要负责 MySQL 故障处理,MySQL 高可用架构改造,OceanBase 相关技术支持。爱好足球,羽毛球。

爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文共 1200 字,预计阅读需要 3 分钟。

背景

ERROR 1499 (HY000): Too many partitions (including subpartitions) were defined

创建表报错,虽然是内部错误,但是错误信息是指:创建了太多了分区。

[root@observer04 ~]# mysql -h10.186.64.125 -P2883 -uroot@wenchao_mysql#hwc_cluster:1682755171 -p"xxxx"  
MySQL [lss]> CREATE TABLE `wms_order` (
  `A1` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'A1',
  `A2` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'A2',
  `A3` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'A3',
  `A4` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'A4',
  `A5` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'A5',
  `A6` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'A6',
  `A7` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'A7',
  `A8` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'A8',
  `A9` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'A9',
  `A10` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'A10'
) DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.0' REPLICA_NUM = 3 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 COMMENT = '物流订单表'
MySQL [lss]> ERROR 1499 (HY000): Too many partitions (including subpartitions) were defined

接下来我们分析一下问题的原因。

排查

2.1 检查参数

  1. 检查每个 OBServer 上可以创建最大的分区数量,当前是 500000。
[root@observer04 ~]# mysql -h10.186.64.125 -P2883 -uroot@sys#hwc_cluster:1682755171 -p"xxxx" -A oceanBase

MySQL [oceanBase]> select * from __all_virtual_sys_parameter_stat where name like '%_max_partition_%';
+-------+----------+---------------+----------+-------------------------------+-----------+--------+--------------+---------------------------------------------+-------------+----------+---------------+---------+---------+-------------------+
| zone  | svr_type | svr_ip        | svr_port | name                          | data_type | value  | value_strict | info                                        | need_reboot | section  | visible_level | scope   | source  | edit_level        |
+-------+----------+---------------+----------+-------------------------------+-----------+--------+--------------+---------------------------------------------+-------------+----------+---------------+---------+---------+-------------------+
| zone1 | observer | 10.186.64.122 |     2882 | _max_partition_cnt_per_server | NULL      | 500000 | NULL         | specify max partition count on one observer |        NULL | OBSERVER | NULL          | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
+-------+----------+---------------+----------+-------------------------------+-----------+--------+--------------+---------------------------------------------+-------------+----------+---------------+---------+---------+-------------------+
  1. 检查当前分区数量的和,目前并没有超过这个限制(500000)。
MySQL [oceanBase]> select count(*) from v$partition;
+----------+
| count(*) |
+----------+
|   421485 |
+----------+

2.2 检查回收站

  1. 检查回收站是否开启?
[root@observer04 ~]# mysql -h10.186.64.125 -P2883 -uroot@wenchao_mysql#hwc_cluster:1682755171 -p"xxxx"

MySQL [lss]> show variables like '%recy%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| recyclebin    | ON    |
+---------------+-------+
1 row in set (0.01 sec)
  1. 检查回收站中是否存在未删除的分区表?
MySQL [lss]> show recyclebin;
+-----------------------------------------+---------------+-------+----------------------------+
| OBJECT_NAME                             | ORIGINAL_NAME | TYPE  | CREATETIME                 |
+-----------------------------------------+---------------+-------+----------------------------+
| __recycle_$_1682755171_1689139725669688 | mytable_1     | TABLE | 2023-07-12 13:28:45.687379 |
| __recycle_$_1682755171_1689139737584112 | mytable_1     | TABLE | 2023-07-12 13:28:57.584660 |
| __recycle_$_1682755171_1689139750594392 | t1            | TABLE | 2023-07-12 13:29:10.594118 |
+-----------------------------------------+---------------+-------+----------------------------+
3 rows in set (0.01 sec)

如果存在,需要和业务侧沟通是否可以清理。回收站的表清理后,发现分区表数量减少,但是创建表依旧报错。

  1. 查看回收站中中对象保留天数。 ``` MySQL [lss]> SHOW PARAMETERS LIKE 'recyclebin_object_expire_time'\G;

*** 1. row *** zone: zone1 svr_type: observer svr_ip: 10.186.64.122 svr_port: 2882 name: recyclebin_object_expire_time data_type: NULL value: 0s info: recyclebin object expire time, default 0 that means auto purge recyclebin off. Range: [0s, +∞) section: ROOT_SERVICE scope: CLUSTER source: DEFAULT edit_level: DYNAMIC_EFFECTIVE 1 row in set (0.02 sec)


配置项 `recyclebin_object_expire_time` 的取值说明如下:
- 当其值为 0s 时,表示关闭自动 Purge 回收站功能。
- 当其值不为 0s 时,表示回收一段时间前进入回收站的 Schema 对象。


## 2.3 检查租户内存

1. 找到分区数最多的 10 个租户。
```shell
[root@observer04 ~]# mysql -h10.186.64.125 -P2883 -uroot@sys#hwc_cluster:1682755171 -p"xxxx"

// 1. 找到分区数最多的 10 个租户
SELECT t2.tenant_name,t2.tenant_id, t1.replica_count
FROM
 (SELECT tenant_id, COUNT(*) AS replica_count
  FROM __all_virtual_partition_info
  GROUP BY tenant_id
  ORDER BY replica_count DESC
  LIMIT 10) t1
JOIN
 (SELECT tenant_id, tenant_name
  FROM __all_tenant) t2
ON t1.tenant_id=t2.tenant_id
ORDER BY replica_count DESC;
+-------------------+-----------+---------------+
| tenant_name       | tenant_id | replica_count |
+-------------------+-----------+---------------+
| wenchao_mysql     |      1100 |        107853 |
| wenchao_01        |      1088 |         99846 |
| wenchao_02        |      1104 |         15873 |
| wenchao_03        |         1 |          3867 |
| wenchao_04        |      1044 |          3270 |
| wenchao_05        |      1066 |          2811 |
| wenchao_06        |      1079 |          2658 |
| wenchao_07        |      1103 |          2103 |
| wenchao_08        |      1057 |          2040 |
| wenchao_09        |      1016 |          1950 |
+-------------------+-----------+---------------+
10 rows in set (0.13 sec)
  1. 查找租户有多少表。
select count(*),svr_Ip from __all_virtual_meta_table where tenant_id=1100 and role=1 group by svr_ip;
+----------+-------------+
| count(*) | svr_Ip      |
+----------+-------------+
|   11921  |10.186.64.103|
|   11868  |10.186.64.104|
|   12013  |10.186.64.105|
+----------+-------------+
3 rows in set (0.35 sec)
  1. 计算租户需要扩容内存大小。
  • 租户当前分区总数 num=107853/副本数
  • 租户可用内存上限=(1-memstore_limit_percentage)*租户 unit 的内存大小 =(1-0.8)*24GB=4.8GB
  • 单个副本分区所需总内存 partition_mem=128k*(107853/3)+max(1000,(107853/3)/10)*400k=5.75GB

注意:单个副本分区所需总内存 > 租户可用内存上限,租户所需内存超限,需要对租户内存进行扩容。

  1. 根据租户内存计算最大分区数量。
  • 单机租户允许创建的最大分区数量=(max_memory-memstore_limit)/partition_mem_n
  • 单机租户允许创建的最大分区数量=(24-24*0.8)/(5.75/(107853/3))=4.8/(5.75/(107853/3))=30011
  • partition_mem_n:指的是单个分区所需总内存

临时处理方案: 扩容租户内存。

根源治理: 不可能无限扩内存;给出业务方合理的分区数量限制,建议业务侧合理使用分区表,制定合理的定期清理策略。

总结

根据上述计算得出:单机租户允许创建的最大分区数量为 30011,建议业务侧注意控制分区数量,以免超限,对业务造成影响。

更多技术文章,请访问:https://opensource.actionsky.com/

关于 SQLE

爱可生开源社区的 SQLE 是一款面向数据库使用者和管理者,支持多场景审核,支持标准化上线流程,原生支持 MySQL 审核且数据库类型可扩展的 SQL 审核工具。

SQLE 获取

类型地址
版本库https://github.com/actiontech/sqle
文档https://actiontech.github.io/sqle-docs/
发布信息https://github.com/actiontech/sqle/releases
数据审核插件开发文档https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse
<think>好的,我现在需要帮助用户了解如何在OceanBase的Oracle租户中查看表索引是否是分区索引。首先,我得回想一下OceanBase的相关文档和Oracle租户的特性。OceanBase的Oracle租户兼容Oracle的语法和部分功能,所以可能和原生Oracle的方法类似,但也有一些差异。 用户的问题核心是判断表索引是否为分区索引。在Oracle中,可以通过查询数据字典视图如ALL_INDEXES、ALL_IND_PARTITIONS等来查看索引的分区信息。但在OceanBase中,可能需要使用特定的系统视图。我需要确认OceanBase是否支持类似的数据字典,或者是否有自己的系统表。 首先,应该考虑用户如何获取索引的基本信息。比如,在OceanBase中,可能有一个类似于DBA_INDEXES或USER_INDEXES的系统视图,用来存储索引的信息。查看这些视图中的分区相关字段,比如PARTITIONED,可能可以判断是否是分区索引。例如,PARTITIONED字段的值是否为YES。 接下来,如果索引是分区的,可能需要进一步查询分区相关的系统视图,比如DBA_IND_PARTITIONS,来查看具体的分区情况。但需要确认OceanBase是否支持这些视图,或者是否有其他替代的视图名称。 另外,可能需要用户有相应的权限才能访问这些系统视图。比如,DBA_权限可能需要DBA角色,而普通用户可能需要查询USER_开头的视图。 此外,可能还需要考虑索引的类型,比如全局索引或局部索引,是否影响分区属性的判断。例如,在Oracle中,全局索引可以是分区的,而局部索引则自动继承表的分区结构。不过,在OceanBase中,分区索引的实现可能有所不同,需要进一步确认。 为了验证思路,我可以先假设OceanBase的Oracle租户支持类似Oracle的系统视图。例如,查询USER_INDEXES视图的PARTITIONED字段: SELECT index_name, partitioned FROM USER_INDEXES WHERE table_name = '表名'; 如果PARTITIONED字段的值是YES,则说明该索引是分区索引。否则,不是。 如果这个字段不存在,可能需要查找其他系统表或视图。比如,检查是否存在ALL_PART_INDEXES这样的视图,或者是否有其他的系统表记录索引的分区信息。 另外,还可以通过查看建表语句来确认索引的分区情况。使用SHOW CREATE TABLE或者类似的命令,观察索引定义中是否包含PARTITION相关的子句。例如: SHOW CREATE TABLE 表名; 这会输出表的定义,包括索引的创建语句。如果索引定义中有PARTITION BY ...的部分,说明是分区索引。 但这种方法依赖于用户能够访问建表语句,并且需要手动检查,可能不够自动化。 此外,可能需要检查OceanBase的官方文档,确认相关系统视图的存在和用法。例如,在OceanBase中,可能使用__all_virtual_table_index之类的内部表,但这对普通用户可能不可见,因此推荐使用兼容Oracle的系统视图。 总结步骤应该是: 1. 使用USER_INDEXES或DBA_INDEXES视图,检查PARTITIONED字段。 2. 如果存在分区索引,进一步查询分区详细信息,比如USER_IND_PARTITIONS。 3. 使用SHOW CREATE TABLE查看表结构,直接观察索引定义。 4. 确保用户有足够的权限查询这些系统视图。 需要注意的是,OceanBase的不同版本可能有差异,某些功能可能在较新版本中支持。因此,建议用户参考对应版本的官方文档,或者进行实际环境测试。 可能还需要提醒用户,如果查询结果中没有PARTITIONED字段,可能需要使用其他方法,比如检查索引是否在分区键上,或者是否存在分区子句。 另外,如果用户无法访问系统视图,可能需要授予相应的权限,如SELECT_CATALOG_ROLE,或者提示用户联系管理员获取权限。 最后,整理这些步骤,以清晰的方式呈现给用户,确保他们能够逐步操作,验证索引是否为分区索引。</think>在OceanBase的Oracle租户中,查看表索引是否为分区索引,可以通过以下步骤实现: --- ### **方法1:通过系统视图 `USER_INDEXES` 或 `DBA_INDEXES`** 1. **查询索引的分区属性** 执行以下SQL,通过 `PARTITIONED` 字段判断索引是否为分区索引(`YES`表示分区索引): ```sql SELECT index_name, partitioned FROM USER_INDEXES WHERE table_name = '表名'; -- 替换为实际表名 ``` - 若结果中 `PARTITIONED` 值为 `YES`,则为分区索引。 - 若使用 `DBA_INDEXES`,需确保用户有DBA权限: ```sql SELECT index_name, partitioned FROM DBA_INDEXES WHERE table_name = '表名'; ``` --- ### **方法2:通过分区索引详情视图 `USER_IND_PARTITIONS`** 若索引已分区,进一步查询分区详情: ```sql SELECT index_name, partition_name FROM USER_IND_PARTITIONS WHERE index_name = '索引名'; -- 替换为实际索引名 ``` - 若能查到记录,则说明该索引是分区索引。 --- ### **方法3:通过 `SHOW CREATE TABLE` 查看表结构** 直接查看表的定义语句,观察索引是否包含分区子句: ```sql SHOW CREATE TABLE 表名; -- 替换为实际表名 ``` - 在输出结果中,若索引定义包含 `PARTITION BY ...`,则为分区索引。 示例: ```sql CREATE TABLE test ( id NUMBER, col1 VARCHAR2(50), PRIMARY KEY(id) ) PARTITION BY HASH(id) PARTITIONS 4; CREATE INDEX idx_col1 ON test(col1) PARTITION BY HASH(col1) PARTITIONS 4; -- 分区索引 ``` --- ### **注意事项** 1. **权限问题** - 使用 `DBA_INDEXES` 或 `DBA_IND_PARTITIONS` 需具备 `DBA` 角色。 - 普通用户建议使用 `USER_INDEXES` 或 `ALL_INDEXES`。 2. **兼容性差异** OceanBase的Oracle租户与原生Oracle存在部分差异,建议通过实际环境验证。 3. **全局索引与局部索引** - 如果索引是“局部索引”(`LOCAL`),则其分区方式与表一致,无需显式指定。 - 全局分区索引需显式定义分区键。 --- ### **总结步骤** 1. 通过 `USER_INDEXES` 检查 `PARTITIONED` 字段。 2. 若为分区索引,通过 `USER_IND_PARTITIONS` 查看分区详情。 3. 通过 `SHOW CREATE TABLE` 直接验证索引定义。 如有权限问题或语法错误,请联系DBA协助排查。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值