热点行性能优化

热点行是指在数据库中那些会被频繁执行修改操作的数据行。高并发场景下对热点行的更新会造成严重的行锁竞争与等待,影响系统性能。因此PolarDB针对此场景在数据库内核层进行了创新性的优化,极大地提升了系统性能。

背景信息

热点行面临以下问题:

  • 当一个事务对一行数据进行更新时,会对目标数据行加锁,直到事务提交或回滚时才释放。在同一时段内,针对同一数据行,只有一个事务能够进行更新,而其他事务则需要等待。由此可见,对于单一热点行的更新请求实际上是串行执行的,传统的分库分表策略在性能提升方面并不会有太大帮助。

  • 在电商平台业务中,限购、秒杀是常用的促销手段。在这些场景下,大量对热点行的更新请求在极短时间间隔内到达后台数据库系统,必然造成严重的行锁竞争和等待,影响系统性能。如果一个更新请求等待执行的时间变长,将会对业务层面产生显著负面影响。

针对上述问题,单纯提高计算机硬件配置已经无法满足这样的低延迟需求。因此PolarDB在数据库内核层进行了创新性的优化,不但能够自动识别热点行更新请求,而且将一定时间间隔内对同一数据行的更新操作进行分组,不同分组采用流水线的方式并行处理,通过这些优化,极大地提升了系统的性能。

技术方案

  • 串行处理变流水线处理

    为了提升数据库系统的性能,最直接的方法是使用并行处理,但是对同一热点行的更新操作很难做到完全并行。PolarDB创新性地使用了流水线处理方式,最大限度地将热点行更新操作并行化。

    image

    热点行更新操作所使用的SQL语句会用autocommit或者COMMIT_ON_SUCCESS进行标记。优化后的MySQL内核层会自动识别带此类标记的更新操作,在一定的时间间隔内,将收集到的更新操作按照主键或者唯一键进行Hash,对于Hash到同一个桶中的更新操作,会将它们按照到达的先后顺序分组分批地进行处理和提交。

    为了使用流水线方式处理这些更新操作,需要使用两个执行单元对它们进行分组。当第一个分组收集完毕准备提交时,第二个分组立即开始收集更新操作。当第二个分组收集完毕准备提交时,第一个分组已经提交完毕并开始收集新一批的更新操作,两个分组不断切换,并行执行。

    现如今多核CPU的使用已经非常普遍。这样的流水线式的处理方式能够充分利用硬件资源,提升CPU的使用率和数据库系统的并行处理能力,从而最大限度地提升数据库系统的吞吐量。

  • 消除申请行锁时的等待

    为了保证数据的逻辑一致性,对一个数据行进行更新时,首先会对该数据行加锁。如果加锁请求无法立刻满足,则进入等待状态。这样一来,不但增加了处理延迟,还会触发死锁检测,导致额外的资源消耗。

    前面提到,我们会按照时间顺序将对同一数据行的更新操作进行分组。组内第一个更新操作为Leader,其读取目标数据行并且加锁。后续更新操作为Follower,其对目标数据行加锁时,如果发现Leader已经持有行锁,无需等待,直接获得行锁。

    通过这个优化,能够减少行锁的加锁次数和时间开销,整个数据库系统的性能显著提升。

  • 减少B-tree索引的遍历

    MySQL是以B-tree索引的方式管理数据的。每次执行查询时,都需要遍历索引才能定位到目标数据行,数据表越大,索引层级越多,遍历时间就越长。

    在前面提到的对更新操作进行分组的机制中,只有每组的Leader遍历索引定位数据行,之后把更新后的数据行缓存(Row Cache)在内存中。同组的Follower加锁成功后,直接从内存中读取目标数据行,不需要再次遍历索引。

    这样一来,从整体上减少了索引遍历的次数和时间开销。

前提条件

  • PolarDB集群数据库引擎需为以下版本之一:

    • MySQL 5.6,且内核小版本需为20200601及以上版本。

    • MySQL 5.7,且内核小版本需为5.7.1.0.17及以上版本。

    • MySQL 8.0,且内核小版本需为8.0.1.1.10及以上版本。

  • PolarDB MySQL版集群已开启Binlog

  • 集群参数rds_ic_reduce_hint_enable处于关闭状态。

说明

使用限制

在以下场景中,热点行性能优化将不会被使用:

  • 热点行所属的数据表是分区表。

  • 热点行所属的数据表上定义了触发器(Trigger)。

  • 热点行使用了Statement Queue机制。

  • 在全局Binlog开启的情况下,若会话级别的Binlog关闭,执行UPDATE语句将不会使用热点行性能优化。

使用说明

  1. 开启热点行性能优化功能。

    您可以在PolarDB控制台上修改以下参数,以开启或关闭热点行性能优化功能。

    参数

    说明

    hotspot

    热点行性能优化功能总开关。取值范围如下:

    1. ON:开启。

    2. OFF(默认):关闭。

    说明
  2. 使用Hint语法来使用热点行性能优化功能。

    Hint

    是否必选

    说明

    COMMIT_ON_SUCCESS

    必选

    更新成功时提交。

    ROLLBACK_ON_FAIL

    可选

    更新失败时回滚。

    TARGET_AFFECT_ROW(1)

    可选

    显式指定该请求只会更新一行,若不符合则更新失败。

    说明

    由于Hint语法生效会自动提交事务,因此Hint需要位于事务的最后一条SQL语句。

    示例:更新sbtest表中c列的数值。

    UPDATE /*+ COMMIT_ON_SUCCESS ROLLBACK_ON_FAIL TARGET_AFFECT_ROW(1) */ sbtest SET c = c + 1 WHERE id = 1;

相关操作

自定义参数配置

PolarDB控制台不支持对以下参数进行修改。如果您需要进行修改,请前往配额中心,在配额名称为PolarDB热点行参数调整操作列,单击申请

参数

说明

hotspot_for_autocommit

autocommit模式下的UPDATE语句是否使用热点行性能优化功能。取值范围如下:

  • ON:开启。

  • OFF(默认):关闭。

hotspot_update_max_wait_time

行数据分组批量更新(Group Update)过程中Leader等待Follower加入该分组的等待时间。

  • 单位:微秒(us)。

  • 默认值:100us。

hotspot_lock_type

行数据分组批量更新(Group Update)过程中是否使用新类型的行锁。取值范围如下:

  • ON:开启。

  • OFF(默认):关闭。

说明
  • 在该参数开启的情况下,对于相同热点行的更新操作进行申请行锁时,无需等待,直接获得行锁,从而可以提升性能。

  • 新类型的行锁:指的是上述说明中无需等待,直接获得的行锁。

查看参数配置

您可以使用如下命令查看热点行性能优化功能的参数配置。

SHOW variables LIKE "hotspot%";

返回结果示例:

+------------------------------+-------+
|Variable_name                 | Value |
+------------------------------+-------+
|hotspot                       | OFF   |
|hotspot_for_autocommit        | OFF   |
|hotspot_lock_type             | OFF   |
|hotspot_update_max_wait_time  | 100   |
+------------------------------+-------+

查看使用情况

您可以使用如下命令查看热点行性能优化功能的使用情况。

SHOW GLOBAL status LIKE 'Group_update%';

性能测试

  • 测试所需的数据表定义和测试语句如下:

    • 数据表定义

      CREATE TABLE sbtest (id INT UNSIGNED NOT NULL, c BIGINT UNSIGNED NOT NULL, PRIMARY KEY (id));
    • 测试语句

      UPDATE /*+ COMMIT_ON_SUCCESS ROLLBACK_ON_FAIL TARGET_AFFECT_ROW(1) */ sbtest SET c = c + 1 WHERE id = 1;
  • 测试工具:Sysbench。

  • 测试场景和测试结果。

    • 测试场景1:单个热点行加8核CPU。

      测试结果:在单热点行加8核CPU的场景下,引入热点行性能优化后,库存热点性能在高并发时提升近64倍。

      2

    • 测试场景2:单个热点行加32核CPU。

      测试结果:在单热点行加32核CPU的场景下,引入热点行性能优化后,峰值QPS提升了63倍。高并发为8000时,性能提升了46倍。

      2

    • 测试场景3:8个热点行加32核CPU 。

      测试结果:在多热点行(8个)加32核CPU的场景下,引入热点行性能优化后,峰值QPS提升了20倍。

      且当高并发达到16000时,在未使用热点行性能优化功能的情况下,更新操作会导致数据库出现故障无法返回更新操作结果。但使用热点行性能优化后,更新操作可以正常返回,且QPS维持稳定。

      4