---
title: 事务参与者数量过多事务无法推进-OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于 事务参与者数量过多事务无法推进相关的常见问题和使用技巧，帮助您快速解决 事务参与者数量过多事务无法推进的难题。
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

划线反馈

# 事务参与者数量过多事务无法推进

更新时间：2025-03-05 07:36

适用版本： V3.1.x、V3.2.x 内容类型：Troubleshoot  

## 问题现象

OceanBase 数据库在 V3.x 版本前并不支持大事务，用户可以通过配置项 `_max_trx_size` 来控制事务的大小，从 V3.x 版本开始，OceanBase 数据库具有了支持大事务的能力，同时也在 OceanBase 数据库 V3.1.x、V3.2.x（V3.2.4 除外）版本中去掉了事务大小的配置项 `_max_trx_size`。 然而 OceanBase 数据库 V3.x 版本支持大事务的能力具有一定局限性，当超多参与者的事务 * 并发负载 达到 OceanBase 数据库的能力上限时，会导致处在提交阶段的事务本身推进不下去，一直卡在事务的协调者等待事务参与者的消息回复上，最终导致租户队列堆积、request 推入队列 -4019 报错、节点 CPU 飙高、节点网络打爆等异常情况，且一般情况下系统无法自己恢复，系统一旦遇到该问题需要运维介入应急解决。OceanBase 数据库 V3.2.3 BP6 版本对事务的参与者个数处理能力做了一部分提升优化，但整体上还是存在一定的局限性。因此在 OceanBase 数据库 V3.x 版本使用大事务时，需要明确大事务参与者数量的局限性，尽量控制事务参与者数量来规避该问题。

OceanBase 数据库建议的事务参与者数量：

- 单节点上并发的普通事务参与者数量小于 30000 个。
 - 单节点上并发的XA事务参与者数量小于 10000 个（XA 事务因事务消息内容更大，因此参与者数量应更小）。

事务参与者过多可能引发的异常情况举例。

- OceanBase 数据库出现悬挂事务报警，日志含大量 -4019 报错。

  ```shell
  WARN [STORAGE.TRANS] process (ob_trans_rpc.h.219) [182156][0][xxx-xxx-xxx-xxx] [lt=11] [dc=0] transaction rpc error(rcode={code:-4019,msg:"",warnings:[]},pkey={tid:1000,partition_id:1000,part_cnt:1000}, trans_id={hash:xxxxx,inc:80845,addr:"xx.xx.xx.xx:xx",t:xxxxx}, dst="xx.xx.xx.xx:xx", msg_type=7)

  ```
 - 主机上存在租户队列积压（req_queue:total_size 表示租户积压的请求数量）。

  ```shell
  INFO  [SERVER.OMT] ob_multi_tenant.cpp:819 [23311][0][xxx-xxx-xxx-xxx] [lt=17] [dc=0] dump tenant info(tenant={id:1002, compat_mode:0, unit_min_cpu:"8.000000000000000000e+00", unit_max_cpu:"1.200000000000000000e+01", slice:"0.000000000000000000e+00", slice_remain:"0.000000000000000000e+00", token_cnt:42, sug_token_cnt:42, ass_token_cnt:42, lq_tokens:4, used_lq_tokens:0, stopped:false, idle_us:4395011, recv_hp_rpc_cnt:935154, recv_np_rpc_cnt:10925, recv_lp_rpc_cnt:0, recv_mysql_ps_close_cnt:0, recv_mysql_cnt:7780, recv_task_cnt:219, recv_large_req_cnt:1911, tt_large_quries:45177, pop_normal_cnt:71139024, actives:42, workers:42, nesting workers:7, lq waiting workers:0, req_queue:total_size=15264 queue[0]=15262 queue[1]=0 queue[2]=0 queue[3]=0 queue[4]=2 queue[5]=0 , large queued:0, reserve queued:0, multi_level_queue:total_size=0 queue[0]=0 queue[1]=0 queue[2]=0 queue[3]=0 queue[4]=0 queue[5]=0 queue[6]=0 queue[7]=0 , recv_level_rpc_cnt:cnt[0]=0 cnt[1]=0 cnt[2]=1 cnt[3]=0 cnt[4]=0 cnt[5]=390 cnt[6]=0 cnt[7]=0 , group_map:null, rpc_stat_info: pcode=0x750:cnt=204851 pcode=0x701:cnt=3894 pcode=0x521:cnt=3498 pcode=0x51f:cnt=316})

  ```

## 问题原因

- OceanBase 数据库 V3.x 之前的版本不支持大事务，这意味着如果在 OceanBase 数据库 V1.x 或者 V2.x 版本使用大事务，最终会导致内存报错、超时或者是其他错误，事务本身由于上述错误从而会终止并回滚，因此大事务不会对系统级资源存在长久的霸占持有，进而对系统整体造成风险。（当然使用 OceanBase 数据库 V1.x、OceanBase 数据库 V2.x 前，通常也需要做相应地适配调整。）
 - 从 V3.x 版本开始，OBServer 具有了支持大事务的能力，同时也在 OceanBase 数据库 V3.1.x、V3.2.x（V3.2.4 除外）版本中去掉了事务大小的配置项 `_max_trx_size`。然而 OceanBase 数据库 V3.x 版本支持大事务的能力具有一定局限性，当事务参与者数量达到 OceanBase 数据库的能力上限时，会导致处在提交阶段的事务本身推进不下去，一直卡在事务的协调者等待事务参与者的消息回复上，最终导致租户队列堆积 hang 死等一系列严重情况。

## 问题的风险及影响

会导致租户中的事务呈现无法向前推进，最终消耗资源，租户请求没有相应，具体有可能造成队列堆积、`observer.log` 中 -4019 报错、CPU 高或者是网络资源打爆等问题。且一般情况下系统无法自己恢复，需要进行运维介入才有可能恢复系统。

## 影响的版本

OceanBase 数据库企业版 V3.x 版本。

## 解决方法及规避方式

### 预防监控（核心）

1. 控制单表分区数目，减降本身不必要的分区。

   比如一种常见的问题场景是：事务中包含了查询、更新、插入某个或者某几个分区数量非常多的表，有可能因为索引选择或者是表分区设置等原因导致 SQL 裁剪后请求还是落入到了非常多分区或者是全表扫，最终导致事务参与者数量非常多。因此在初始使用 OBServer 时需要评估单表的分区数目，针对过百甚至是过千的分区表，尽量进行降分区和控制分区数的操作。
 2. 增加对事务参与者个数的监控，当出现参与者过多的SQL时及时进行调优。

   对于本身系统中存在了比较多分区表的环境，且无法有效地降低分区数时，需要在 OCP 中实时监控系统中是否存在参与者过多的事务。

      1. OCP 在 topsql 页面 monitor 访问分区过多的 SQL（15天的数据量）:进入租户管理后 topsql > 列管理 > 勾选访问分区数。
      2. 从 OCP V3.3.4 版本对多个参与者的 SQL（大于 2 个）会作为可疑 SQL 暴露出来，直接出现在：租户管理 > SQL诊断 > 可疑 SQL 中。
      3. 如果想要直接监控事务参与者个数，可以黑屏监控下面的 SQL。

        ```shell
        SELECT count(*) FROM oceanbase.__all_virtual_trans_stat where part_trans_action > 2 GROUP BY trans_id;

        ```
      4. 增加参与者过多时的日志 WARN 监控优化（适用于 V3.2.3 BP5 与 V3.1.2 BP10 Hotfix 及以上版本的 OBServer）：在 OCP上告警 > OB 日志告警 > 增加过滤关键字增加 "too many partitipants for 2pc" 关键日志的告警。
 3. V3.2.4 版本又找回了配置项 `_max_trx_size`，因此在业务允许（不会对其他事务造成影响）可以配置该参数控制事务大小。

### 问题发生后的确认与处理

#### 问题确认

当 OceanBase 数据库发生与 “问题现象” 中类似的异常情况，且怀疑与本问题有关时，可在 sys 租户下使用以下 SQL 辅助判断。

```shell
SELECT count(*), trans_id FROM oceanbase.__all_virtual_trans_stat where part_trans_action > 2 GROUP BY trans_id order by count(*) desc limit 30;

```

返回结果如下（可见：事务参与者数量达 13398 * 5 = 66990 个）。

```shell
+----------+---------------------------------------------------+
| count(*) | trans_id                                          |
+----------+---------------------------------------------------+
|  13398   |  {hash:xxx,inc:xxx,addr:"xx-xx-xx-xx:2882",t:xxx} |
|  13398   |  {hash:xxx,inc:xxx,addr:"xx-xx-xx-xx:2882",t:xxx} |
|  13398   |  {hash:xxx,inc:xxx,addr:"xx-xx-xx-xx:2882",t:xxx} |
|  13398   |  {hash:xxx,inc:xxx,addr:"xx-xx-xx-xx:2882",t:xxx} |
|  13398   |  {hash:xxx,inc:xxx,addr:"xx-xx-xx-xx:2882",t:xxx} |
+----------+---------------------------------------------------+

```

#### 问题处理

当发现事务无法推进的情况后，可以先检查分区 leader 情况，也就是检查是否存在分区无主。如果确定事务所涉及的分区均存在 leader 的情况下，可以尝试采用以下措施来恢复系统。

1. 在系统租户下，调大参数 `trx_2pc_retry_interval`，命令如下。

   ```shell
   obclient> ALTER SYSTEM SET trx_2pc_retry_interval = '5s';

   ```

   执行完成后，可以通过查看虚拟表 `__all_virtual_trans_stat` 来观察事务提交的推进情况。
 2. 如推进依旧缓慢，可对事务协调者所在的分区切主。

   ```shell
   obclient> ALTER SYSTEM SET primary_zone=xxx;

   ```
 3. 如依旧无效果，可尝试重启集群。

   ```shell
   obclient> ALTER SYSTEM start '节点 IP:PORT';

   ```

上一篇

[悬挂事务与长事务](https://www.oceanbase.com/knowledge-base/oceanbase-database-20000001003)

下一篇

[OceanBase MySQL 模式和 MySQL 数据库显式加行锁表现差异](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000210012) ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
