---
title: "热点行更新的最佳实践 - OceanBase 最佳实践 | OceanBase 文档中心"
description: 热点行更新的最佳实践 在数据库中，热点行指的是被频繁访问和修改的特定行数据。随着在线交易、电商行业的发展，业务系统的热点并发压力逐渐成为一种挑战。热点账户短时间内余额大量更新，或者热门商品在营销活动中限时抢购，都是这种场景的直接体现。热点更新的本质是短时间内对数据库中的同一行数据的某些字段值进行高并发的修改（余额，库…
image: https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*OSPzQ6GUQF4AAAAAQHAAAAgAeiGDAQ/original
---
切换语言

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

# 热点行更新的最佳实践

更新时间：2026-07-28

[编辑](https://github.com/oceanbase/best-practices-doc/edit/master/zh-CN/1000.Performance-Tuning/500.design-of-hot-rows-in-database-tables.md) 适用产品： OceanBase 数据库 适用场景： 性能调优  

在数据库中，热点行指的是被频繁访问和修改的特定行数据。随着在线交易、电商行业的发展，业务系统的热点并发压力逐渐成为一种挑战。热点账户短时间内余额大量更新，或者热门商品在营销活动中限时抢购，都是这种场景的直接体现。热点更新的本质是短时间内对数据库中的同一行数据的某些字段值进行高并发的修改（余额，库存等），这其中的瓶颈主要在于关系型数据库为了保持事务一致性，对数据行的更新都需要经过 “加锁 > 更新 > 写日志提交 > 释放锁” 的过程，而这个过程实质上是串行的。所以，提高热点行更新能力的关键在于如何尽可能缩短持有锁的时间。

虽然学术界很早就提出了 “提前解行锁（ELR，Early Lock Release）” 的方案，但是因为 ELR 的异常处理场景非常复杂，业界很少有成熟的工业实现。OceanBase 数据库在这个问题上通过持续的探索，提出了一种基于分布式架构的实现方式，提升类似业务场景中单行并发更新的能力，作为 OceanBase 数据库 “可扩展的 OLTP” 中的关键能力之一。

本文将介绍热点行更新的最佳实践，包括技术背景、性能压测和注意事项。

## 技术背景

### 优化前

在用户发起 `COMMIT` 操作后，数据库（DB）端会触发日志的持久化流程。这个过程包括以下几个步骤：

1. 将内存中的数据序列化并提交给本地的 `buffer manager`。
 2. 数据库将日志数据发送到所有备机。
 3. 等待多数备机同步日志成功后，数据库才认为日志持久化成功。
 4. 最终解锁事务，并向客户端返回事务提交成功的应答。

在此流程中，一个事务的持锁时间包含以下几个部分：数据写入、日志序列化、同步备机的网络通信、日志刷盘的时间。对于三地五中心部署或者磁盘性能较差的情况，持锁时间较长，容易对热点行产生显著的性能影响。

### 优化后

在数据库优化方案中，整体提交流程基本保持不变，但对解锁时机进行了调整。在新的流程中，当日志序列化完成并提交给 `buffer manager` 后，立即触发解锁操作，而不再等待多数备机的日志刷盘完成。这样可以有效减少事务的持锁时间。事务解锁后，允许后续事务对同一行进行操作，实现了多个事务并发更新同一行的效果，从而提升了系统的吞吐量。

#### 性能分析

基于上述优化方案，热点行场景下的性能可以通过以下公式计算：

𝑇𝑃𝑆=1/一个事务内热点行的持锁耗时。

其中，持锁耗时指的是从加锁开始到事务提交完成的时间间隔。

在三地五中心的场景下，由于 SQL 的整体执行耗时为 30ms，事务的 `COMMIT` 响应时间（RT）约为 30ms。通过该优化，性能基本能够与同城部署保持一致。

## 性能压测

在进行热点行更新的最佳实践之前，需要进行性能测试来评估当前系统的性能状况，并在优化后进行对比测试。

### 环境信息

部署环境包括一台使用 ecs.g6.8xlarge 配置的 ODP（OceanBase 数据库），和一台使用 ecs.r6.4xlarge 配置的 OBServer。为了提升性能和可靠性，存储系统采用三块独立的 ESSD PL1 云盘，分别进行配置和部署。这种分开部署的方式使得数据存储、日志存储和重做日志存储能够分开管理，从而优化磁盘 I/O 性能和故障恢复能力。

`deploy.yaml` 的具体内容如下：

```shell
oceanbase-ce:
  version: 4.2.0.0
  servers:
    - name: server1
      ip: xxx.xx.xxx.01
  global:
    devname: eth0
    memory_limit: 120G # The maximum running memory for an observer
    log_disk_percentage: 90
    datafile_disk_percentage: 90
    enable_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: obcluster
    root_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/observer
    data_dir: /data/3/ob/obd/storage
    redo_dir: /data/2/ob/obd/redo
    zone: zone1
obproxy-ce:
  version: 4.2.0.0
  depends:
    - oceanbase-ce
  servers:
    - xxx.xx.xxx.02
  global:
    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/obproxy
    enable_cluster_checkout: false
    skip_proxy_sys_private_check: true
    enable_strict_kernel_release: false

```

### 配置信息

租户规格 15C/95G。

### 测试方法

#### 步骤一：创建测试表，插入测试数据

基于 sysbench 标准 benchmark 工具，建表涉及的 schema 如下：

```sql
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"：

```shell
non_index_updates = {
    "UPDATE sbtest1 SET k=k+1 WHERE id=1",
    {t.CHAR, 120}, t.INT},

```

#### 步骤三：数据库端参数配置调整

在系统租户（sys 租户）中执行以下命令，优化热点行场景性能：

```sql
ALTER SYSTEM SET enable_sql_audit=false;
ALTER SYSTEM SET enable_perf_event=false;

```

#### 注意

热点行场景配置项非常关键，下面代码框中给定的参数不建议调整。

```sql
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';

```

在普通租户下执行以下命令，关闭租户级跟踪功能：

```sql
CALL DBMS_MONITOR.OB_TENANT_TRACE_DISABLE;

```

#### 步骤四：统计压测数据

qps/95 RT/平均 RT

| **并发数** | **OceanBase 默认参数** | **OceanBase 调参** |
| --- | --- | --- |
| 8 | 2990.36/1.93/2.78 | 3283.19/1.96/2.68 |
| 16 | 3191.89/2.35/5.05 | 3775.30/2.03/4.42 |
| 32 | 3445.89/29.72/0.62 | 4409.73/3.68/7.52 |
| 64 | 3639.10/106.75/17.90 | 5323.44/102.97/12.61 |
| 128 | 3842.81/207.82/31.37 | 6347.05/110.66/20.69 |
| 256 | 5006.01/325.98/51.84 | 8026.34/211.60/32.14 |
| 512 | 6243.97/530.08/82.22 | 10016.74/320.17/50.71 |
| 1024 | 6334.96/802.05/162.51 | 10337.51/559.50/106.93 |
| 2048 | 4790.85/1506.29/413.44 | 7536.00/1109.09/289.70 |

## 注意事项

以下是热点行性能验证、测试、调优最重要的三个点：

- 热点行场景配置项非常关键，上述 **步骤三：数据库端参数配置调整** 中给定的参数，除了前两个（`enable_sql_audit` 和 `enable_perf_event`）之外不建议调整，其他需要上生产环境。
 - 事务内热点行表的操作顺序比较重要，原则：凡是热点行表的操作，越靠近 `COMMIT` 性能越高。
 - 主、备副本如果网络延迟比较高，客户端需要增加吞吐，能达到到跟单机房一致的性能。

 上一篇 下一篇 ![有帮助](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) 咨询热线
