首批通过分布式安全可靠测评,为关键业务系统打造
普通用户连接时遇到报错 ERROR 1040 (08004): Too many connections
更新时间:2026-06-04 01:56
问题现象
普通业务租户的普通用户直连 OceanBase 数据库的 2881 端口时遇到报错 ERROR 1040 (08004): Too many connections。通过该业务租户的管理员 SYS 用户连接则无此问题。

问题原因
客户的应用程序连接 OceanBase 数据库时,最大支持的并发连接数同时受下面几个因素限制。
如果客户通过 OBProxy 进行连接,首先在 OBProxy 这一层,最大支持的并发连接数受 OBProxy 的参数
client_max_connections限制,默认值为 8192,可动态调整生效。MySQL [oceanbase]> show proxyconfig like 'client_max_connections'; +------------------------+-------+---------------------------------------------------+-------------+---------------+-------+--------------+ | name | value | info | need_reboot | visible_level | range | config_level | +------------------------+-------+---------------------------------------------------+-------------+---------------+-------+--------------+ | client_max_connections | 8192 | client max connections for one obproxy, [0, +∞] | false | USER | [0,] | LEVEL_GLOBAL | +------------------------+-------+---------------------------------------------------+-------------+---------------+-------+--------------+ 1 row in set (0.01 sec)如果客户未通过 OBProxy 连接,或者在 OBProxy 这一层的并发连接数未超过限制,在 OBServer 这一层,最大支持的并发连接数受业务租户的内存规格、
_resource_limit_max_session_num、max_connections、max_user_connections等几个因素共同限制,实际的并发连接总数超过其中任何一个限制都会导致连接报错。租户级别的配置项
_resource_limit_max_session_num默认值为 0,当取值为 0 时,实际生效值根据对应业务租户内存规格(需要扣掉相关 Meta 租户的内存大小)计算,计算公式如下。_resource_limit_max_session_num = max(100, memory_size * 0.05/100K)以用户创建出来的一个 memory_size='2GB' 的 OceanBase 数据库 V4.x 版本租户为例,该业务租户实际可用的内存规格为 2GB - 1GB(Meta租户的内存大小),因此该业务租户支持的最大并发连接数为:
>>> 1 * 1024 * 1024 * 0.05 / 100 524.288当租户级别的配置项
_resource_limit_max_session_num取值不为 0 时,实际生效值即为对应的取值。注意
SYS 租户或者用户租户的管理员用户(root 或 SYS)不受
_resource_limit_max_session_num上限的约束。-- the maximum number of sessions that can be created concurrently。OceanBase 数据库 V4.0 版本新增的隐藏参数,OceanBase 数据库 V2.x/V3.x 中均无此参数。默认值:0,TENANT 租户级别/DYNAMIC_EFFECTIVE MySQL [oceanbase]> select * from gv$ob_parameters where name='_resource_limit_max_session_num';其它两个租户变量的默认值如下。
MySQL [(none)]> show variables like '%connections%'; +----------------------+------------+ | Variable_name | Value | +----------------------+------------+ | max_connections | 2147483647 | | max_user_connections | 0 | <== 0代表无限制 +----------------------+------------+ 2 rows in set (0.00 sec) obclient(SYS@oracle)[SYS]> show variables like '%connections%'; +----------------------+-------+ | VARIABLE_NAME | VALUE | +----------------------+-------+ | max_user_connections | 0 | <== 0代表无限制 +----------------------+-------+ 1 row in set (0.004 sec)注意
SYS 租户或者用户租户的管理员用户(root 或 SYS)也会受到上面两个租户变量的约束。
综上总结如下。
如果当前租户同时设置了
_resource_limit_max_session_num、max_user_connections和max_connections的值,则对于某个普通用户,其并发连接数只要达到其中一个值,即无法再建立新的连接。对于管理员用户(root 或 SYS),其并发连接数只要达到
max_user_connections或max_connections的其中一个值,即无法再建立新的连接。
问题的风险及影响
客户应用连接失败。
影响租户
影响 OceanBase 数据库中的 SYS 租户和 Oracle 租户以及 MySQL 租户。
适用版本
OceanBase 数据库 V4.0 及之后版本。
OBProxy 所有版本。
解决方法
针对客户这边的连接报错,排查后发现,客户自己误设了 _resource_limit_max_session_num=100,导致最多支持的并发连接数为 100。
对应的 observer.log 日志中存在如下的告警。
[errcode=-5271] too much sessions(ret=-5271, tenant_id=1004, cur_connections=101, max_sess_num=100, tenant_name_=XCGN, user_name_=xxx)
问题根因定位后,解决方法也很简单,只需要将该租户级别的隐藏参数重置为默认值 0 即可。
obclient [SYS]> show variables like '%conn%';
+--------------------------+-------------+
| VARIABLE_NAME | VALUE |
+--------------------------+-------------+
| character_set_connection | utf8mb4 |
| collation_connection | utf8mb4_bin |
| connect_timeout | 10 |
| init_connect | NULL |
| max_user_connections | 0 |
+--------------------------+-------------+
5 rows in set (0.003 sec)
obclient [SYS]> select * from gv$ob_parameters where name='_resource_limit_max_session_num';
+----------------+----------+-------+--------+-----------+---------------------------------+-----------+-------+-----------------------------------------------------------------+----------------+-------------------+
| SVR_IP | SVR_PORT | ZONE | SCOPE | TENANT_ID | NAME | DATA_TYPE | VALUE | INFO | SECTION | EDIT_LEVEL |
+----------------+----------+-------+--------+-----------+---------------------------------+-----------+-------+-----------------------------------------------------------------+----------------+-------------------+
| xxx.xxx.xxx.xx | 2882 | zone1 | TENANT | 1004 | _resource_limit_max_session_num | NULL | 100 | the maximum number of sessions that can be created concurrently | RESOURCE_LIMIT | DYNAMIC_EFFECTIVE |
+----------------+----------+-------+--------+-----------+---------------------------------+-----------+-------+-----------------------------------------------------------------+----------------+-------------------+
1 row in set (0.013 sec)
obclient [SYS]> alter system set "_resource_limit_max_session_num"=0;
Query OK, 0 rows affected (0.026 sec)
obclient [SYS]> select * from gv$ob_parameters where name='_resource_limit_max_session_num';
+----------------+----------+-------+--------+-----------+---------------------------------+-----------+-------+-----------------------------------------------------------------+----------------+-------------------+
| SVR_IP | SVR_PORT | ZONE | SCOPE | TENANT_ID | NAME | DATA_TYPE | VALUE | INFO | SECTION | EDIT_LEVEL |
+----------------+----------+-------+--------+-----------+---------------------------------+-----------+-------+-----------------------------------------------------------------+----------------+-------------------+
| xxx.xxx.xxx.xx | 2882 | zone1 | TENANT | 1004 | _resource_limit_max_session_num | NULL | 0 | the maximum number of sessions that can be created concurrently | RESOURCE_LIMIT | DYNAMIC_EFFECTIVE |
+----------------+----------+-------+--------+-----------+---------------------------------+-----------+-------+-----------------------------------------------------------------+----------------+-------------------+
1 row in set (0.002 sec)
规避方式
无。