在高并发场景下,批量更新或删除数据(如批量更新订单状态、清理过期数据)时,长时间的行锁等待和锁竞争是常见的性能瓶颈。PolarDB MySQL版提供Snapshot Update特性,专为优化此类范围更新场景设计,通过减少锁持有时间,提升QPS并显著降低行锁等待时间。本文为您介绍Snapshot Update的工作原理、适用场景、使用方法、性能表现及相关风险,帮助您安全、高效地利用此特性优化业务性能。
核心原理与代价
工作原理
传统UPDATE/DELETE操作在扫描数据时会全程对记录加锁,在高并发下容易造成阻塞。Snapshot Update采用“先无锁预检,再加锁确认”的两阶段机制,有效地缩短了锁的持有时间。
第一阶段(无锁预检):利用当前事务的MVCC(Multi-Version Concurrency Control,多版本并发控制)快照视图,扫描并筛选出可能满足
WHERE条件的记录。此过程不获取行锁,不会阻塞其他事务的读写操作。第二阶段(加锁更新):仅对第一阶段筛选出的候选记录逐一加锁。加锁后,再次验证该记录是否仍然满足
WHERE条件。这是因为在两个阶段之间,数据可能已被其他并发事务修改。只有再次验证通过的记录,才会被执行更新或删除。
收益与代价
维度 | 描述 |
主要收益 | 显著降低锁冲突:通过大幅缩短行锁的持有时间,有效减少高并发下的锁等待和死锁,从而提升 |
主要代价 | 增加CPU开销:两阶段机制引入了额外的 |
核心风险 | Undo日志堆积:长时间运行的事务会持有旧的快照视图,阻止 |
适用范围
在使用此特性前,请确认您的环境和待优化的SQL语句是否满足以下条件。
集群版本:
产品系列:集群版、标准版。
内核版本:MySQL 8.0.2,且修订版本需为8.0.2.2.32及以上版本。
事务隔离级别:数据库事务隔离级别需为读已提交(Read Committed)或可重复读(Repeatable Read)。
特定SQL语句:此特性仅对特定类型的
UPDATE/DELETE语句生效。适用条件:执行计划使用主键(PRIMARY KEY)进行范围扫描(range scan)。您可以通过
EXPLAIN命令进行判断,在EXPLAIN结果中,如果key字段为PRIMARY,且type字段为range,则该SQL满足优化条件。不适用场景:
仅使用主键等值条件的UPDATE/DELETE操作。
执行计划使用二级索引的
UPDATE/DELETE操作。多表更新(MULTI-TABLE UPDATE)场景。
高并发下的热点行更新场景,此时建议使用热点行优化。
开启Snapshot Update功能
通过设置loose_innodb_polar_use_snapshot_update参数来控制此优化功能的行为。
PolarDB集群参数在控制台与会话中修改方式存在差异,详细区别如下:
在PolarDB控制台上修改:
兼容性说明:部分集群参数在PolarDB控制台上均已添加MySQL配置文件的兼容性前缀loose_。
操作方法:找到并修改这些带
loose_前缀的参数。
在数据库会话中修改(使用命令行或客户端):
操作方法:当您连接到数据库,使用
SET命令修改参数时,请去掉loose_前缀,直接使用参数的原始名称进行修改。
建议采用会话级别配置方式,针对特定类型的SQL语句定向开启Snapshot Update功能,以实现精准的性能优化。
参数名称 | 级别 | 描述 |
| Global/Session | 控制
|
性能测试报告
以下是在Sysbench范围更新(range-update)场景下的测试结果,展示了Snapshot Update功能带来的性能提升。
测试环境:PolarDB MySQL版集群版,MySQL 8.0.2,128核64 GB节点规格。
测试数据:8张表,每张表100万条记录。
测试负载:基于Sysbench的
UPDATE sbtest%u SET c=? WHERE id BETWEEN ? AND ? AND mod(k, ?) = 0范围更新模型。参数配置:
MySQL Native:
innodb_polar_use_snapshot_update = OFF
innodb_lock_wait_timeout=50
Snapshot Update:
innodb_polar_use_snapshot_update = ON
innodb_lock_wait_timeout=50
测试结果
QPS对比:开启Snapshot Update后,QPS从约260,303提升至约362,615,性能提升约1.39倍。

行锁等待时间对比:开启Snapshot Update后,行锁等待时间从约18.6 ms降低至接近10.1 ms。
