在数据库中,热点行是指那些被频繁访问和修改的特定行数据。随着在线交易和电商行业的蓬勃发展,业务系统面临的热点并发压力日益加剧。例如,热点账户的余额在短时间内频繁更新,或是热门商品在营销活动中遭遇抢购热潮,都是这种场景的直接体现。
热点更新的核心在于,短时间内对数据库中的同一行数据的某些字段(如余额、库存等)进行高并发的修改操作。然而,这一过程的瓶颈在于关系型数据库为确保事务一致性,对数据行的更新都需要经过 “加锁 > 更新 > 写日志提交 > 释放锁” 的过程,而这个过程实质上是串行的。因此,缩短持有锁的时间成为提升热点行更新能力的关键所在。
尽管学术界早已提出“提前解除行锁(ELR,Early Lock Release)”的策略,但由于ELR的异常处理场景极为复杂,业界鲜有成熟的工业级实现。对此,OceanBase数据库通过不断探索,提出了一种基于分布式架构的解决方案,有效提升了类似业务场景下单行并发更新的能力,成为OceanBase数据库“可扩展OLTP”能力的关键一环。
一、热点行更新的技术背景
(一)优化前
在用户发起 COMMIT 操作后,数据库(DB)端会触发日志的持久化流程。这个过程包括以下几个步骤:
👉 将内存中的数据序列化并提交给本地的 buffer manager。
👉 数据库将日志数据发送到所有备机。
👉 等待多数备机同步日志成功后,数据库才认为日志持久化成功。
👉 最终解锁事务,并向客户端返回事务提交成功的应答。
在此流程中,一个事务的持锁时间包含以下几个部分:数据写入、日志序列化、同步备机的网络通信、日志刷盘的时间。对于三地五中心部署或者磁盘性能较差的情况,持锁时间较长,容易对热点行产生显著的性能影响。
(二)优化后
在数据库优化方案中,整体提交流程基本保持不变,但对解锁时机进行了调整。在新的流程中,当日志序列化完成并提交给 buffer manager 后,立即触发解锁操作,而不再等待多数备机的日志刷盘完成。这样可以有效减少事务的持锁时间。事务解锁后,允许后续事务对同一行进行操作,实现了多个事务并发更新同一行的效果,从而提升了系统的吞吐量。
基于上述优化方案,热点行场景下的性能可以通过以下公式计算:
𝑇𝑃𝑆=1/一个事务内热点行的持锁耗时。
其中,持锁耗时指的是从加锁开始到事务提交完成的时间间隔。
在三地五中心的场景下,由于 SQL 的整体执行耗时为 30ms,事务的 COMMIT 响应时间(RT)约为 30ms。通过该优化,性能基本能够与同城部署保持一致。
二、热点行更新的性能压测
在进行热点行更新的最佳实践之前,需要进行性能测试来评估当前系统的性能状况,并在优化后进行对比测试。
(一)环境信息
部署环境包括一台使用 ecs.g6.8xlarge 配置的 ODP(OceanBase 数据库代理),和一台使用 ecs.r6.4xlarge 配置的 OBServer。为了提升性能和可靠性,存储系统采用三块独立的 ESSD PL1 云盘,分别进行配置和部署。这种分开部署的方式使得数据存储、日志存储和重做日志存储能够分开管理,从而优化磁盘 I/O 性能和故障恢复能力。
deploy.yaml 的具体内容如下:
oceanbase-ce:version: 4.2.0.0servers:- name: server1ip: xxx.xx.xxx.01global:devname: eth0memory_limit: 120G # The maximum running memory for an observerlog_disk_percentage: 90datafile_disk_percentage: 90enable_syslog_wf: false # Print system logs whose levels are higher than WARNING to a separate log file. The default value is true.enable_syslog_recycle: true # Enable auto system log recycling or not. The default value is false.max_syslog_file_count: 1000 # The maximum number of reserved log files before enabling auto recycling. The default value is 0.appname: obclusterroot_password: ******server1:mysql_port: 2881 # External port for OceanBase Database. The default value is 2881. DO NOT change this value after the cluster is started.rpc_port: 2882 # Internal port for OceanBase Database. The default value is 2882. DO NOT change this value after the cluster is started.home_path: /data/1/ob/obd/observerdata_dir: /data/3/ob/obd/storageredo_dir: /data/2/ob/obd/redozone: zone1obproxy-ce:version: 4.2.0.0depends:- oceanbase-ceservers:- xxx.xx.xxx.02global:listen_port: 2886 # External port. The default value is 2883.prometheus_listen_port: 2887 # The Prometheus port. The default value is 2884.home_path: /root/obproxyenable_cluster_checkout: falseskip_proxy_sys_private_check: trueenable_strict_kernel_release: false
(二)配置信息
租户规格为 15C/95G。
(三)测试方法
👨💻 步骤一:创建测试表,插入测试数据
基于 Sysbench 标准 Benchmark 工具,建表涉及的 Schema 如下:
CREATE TABLE `sbtest1` (`id` int(11) NOT NULL AUTO_INCREMENT,`k` int(11) NOT NULL DEFAULT '0',`c` char(120) NOT NULL DEFAULT '',`pad` char(60) NOT NULL DEFAULT '',PRIMARY KEY (`id`));INSERT INTO sbtest1 VALUES(1,0,'aa','aa');
👨💻 步骤二:调整压测 SQL
基于主键的 ID 只更新 id = 1 的这一行。改造 Sysbench 进行测试,修改 oltp_common.lua 脚本中的 non_index_updates 为固定查询语句,"UPDATE sbtest1 SET k=k+1 WHERE id=1":
non_index_updates = {"UPDATE sbtest1 SET k=k+1 WHERE id=1",{t.CHAR, 120}, t.INT},
👨💻 步骤三:数据库端参数配置调整
ALTER SYSTEM SET enable_sql_audit=false;ALTER SYSTEM SET enable_perf_event=false;
🧡 注意:
热点行场景配置项非常关键,下面代码框中给定的参数不建议调整。
ALTER SYSTEM SET syslog_level='PERF';ALTER SYSTEM SET enable_record_trace_log=false;ALTER SYSTEM SET _enable_defensive_check=false;ALTER SYSTEM SET _lcl_op_interval = '0ms';ALTER SYSTEM set_tp tp_no = 2100, error_code = 4001, frequency = 1;ALTER SYSTEM SET _trace_control_info='' tenant=all;
👨💻 步骤四:统计压测数据
qps/95 RT/平均 RT

三、热点行更新的注意事项
以下是热点行性能验证、测试、调优最重要的三个点:
🚩 热点行场景配置项非常关键,上述 步骤三:数据库端参数配置调整 中给定的参数,除了前两个(enable_sql_audit 和 enable_perf_event)之外不建议调整,其它需要上生产环境。
🚩 事务内热点行表的操作顺序比较重要,原则:凡是热点行表的操作,越靠近 COMMIT 性能越高。
🚩 主、备副本如果网络延迟比较高,客户端需要增加吞吐,能达到与单机房一致的性能。
热点行更新是当今高并发业务场景中的一大挑战,尤其是在电商、金融等需要频繁更新同一行数据的领域。OceanBase 数据库通过优化事务提交流程,特别是调整解锁时机,显著减少了事务的持锁时间,从而提升了系统的并发处理能力,能够在三地五中心等复杂部署环境中保持高效的性能表现,为业务系统提供强有力的支持。




