首批通过分布式安全可靠测评,为关键业务系统打造
高并发 select for update 场景 hang 死
更新时间:2026-05-28 02:06
问题现象
程序高并发使用 select for update 执行 SQL,出现程序 hang 住的情况,租户线程打满;由于 select for update 是对行进行加锁的操作,可能和行锁冲突有关,因此去观测 __all_virtual_trans_lock_stat,发现锁的持有者事务 ID 是在一直变化的。
关键诊断信息
触发条件
同时满足以下3个条件。
OceanBase 数据库版本小于等于 V3.2.x。
开启
ps cursor(比如 JDBC 链接参数包含useCursorFetch=true或者useServerPrepStmts=true或者开启二合一协议等场景下,select 语句走ps cursor)。对同一个表高并发执行
select for update触发 -6005(6C 20GB 租户大概 100 并发访问)。
事前巡检
业务避免 ps cursor 路径高并发执行 select for update(即破坏上述三个必要触发条件)。
事后诊断
查看任意一条请求的日志发现走了
inner sql connection接口(OceanBase 数据库在 V3.2.x 之前的ps cursor走的是inner sql connection)。发现日志中有大量 -6005 报错。

在
dbms_cursor_open函数中会打印失败重试相关日志。
问题原因
请求遇到行锁冲突 -6005 的场景下需要对请求进行重试。 当前重试有两种方式:local retry 和 packet retry。其中 packet retry 是将整个请求重新放回请求队列中进行重新调度,这个过程会释放当前占用的线程;local retry 是一种更加轻量化的重试方案,发现失败之后当即在当前线程中重试。 JDBC 链接串参数 useCursorFetch=true 的时候 select 语句会走 ps cursor 路径,这个路径上不会 packet retry,因此对 -6005 错误一直占用当前线程 local retry 直到超时,请求长时间占用线程资源导致数据库响应慢。
问题的风险及影响
高并发场景下数据库响应慢,CPU 使用率飙升,影响业务可用性及稳定性。
影响租户
影响 OceanBase 数据库中的 Oracle 租户,对于 SYS 租户和 MySQL 租户无影响。
影响版本
OceanBase 数据库企业版 V2.2.77 GA(oceanbase-2.2.77-20210508211731)及之后版本、V3.1.2 GA(oceanbase-3.1.2-20210618150922)及之后版本、V3.2.2 GA(oceanbase-3.2.2-20211130225726)及之后版本、V3.2.3 GA(oceanbase-3.2.3.0-20220418212020)及之后版本、V3.2.4 GA(oceanbase-3.2.4.0-100000072022102819)及之后版本。
解决方法及规避方式
解决方法:
升级至问题已修复版本。目前已修复的版本包括 OceanBase 数据库 V4.2.0 GA(oceanbase-4.2.0.0-100010082023083014)及之后版本。
临时关闭
ps cursor(将useCursorFetch置为 false,注意该操作在大查询场景会导致内存膨胀,可以考虑建立两个连接分别开启、关闭ps cursor)。降低业务并发度。
规避方式:
业务避免
ps cursor路径下高并发执行select for update。