当前仅RDS for MySQL 5.7三节点企业版1.5.0.4及以上版本支持该功能。
功能设计
“电商秒杀”等业务场景会对某一行数据短时间进行大量并发更新,这种热点操作对数据库的性能有很大的挑战。MySQL传统的更新模式“lock-update-unlock”,性能上基本无法满足实际的需求。业界针对这个问题有很多优化方案:基于缓存的方案不能保证数据一致性,有丢数据和超卖的风险;基于排队的方案仅仅缓解了大并发下的雪崩问题,依然受限于引擎层的lock/unlock性能损耗;预扣减、异步扣减等业务优化,增加了业务逻辑的复杂度,一定程度上也影响了客户体验。
热点组提交功能是RDS三节点企业版自研的特性。用户开启参数后,并为热点更新的SQL添加相关优化器hint,组提交模块会将同一数据行的热点请求自动合并成合适大小的Group,把多次逻辑更新映射成单次物理更新,最终下发到引擎层。该方法彻底的突破了InnoDB引擎层的性能上限,在单行更新的场景下测试,相较原生的MySQL,随着并发数上升,有十倍甚至上百倍的性能提升。
同时需要打开hotspot相关参数:
需要注意的是,只有在打开参数配置的基础上,同时使用commit_on_success的hint,才能激活该功能。 样例SQL如下:
Query OK, 0 rows affected (0.01 sec)
mysql> insert into test values (1, 1);
Query OK, 1 row affected (0.01 sec)
mysql> update /*+ commit_on_success */ test set data = data + 1 where id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test;
+----+------+
+----+------+
| 1 | 2 |
+----+------+
1 row in set (0.00 sec)
mysql> update /*+ commit_on_success rollback_on_fail target_affect_row(1) */ test set data = data + 1 where id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test;
+----+------+
| id | data |
+----+------+
| 1 | 3 |
+----+------+
1 row in set (0.00 sec)
此外也支持select ... from update
的语法,可以直接返回更新后的数据。
mysql> show global status like "%Group_update%";
+---------------------------------------+-------+
| Group_update_fail_count | 0 |
| Group_update_follower_count | 0 |
| Group_update_free_count | 1 |
| Group_update_gu_leak_count | 0 |
| Group_update_gu_lock_fail_count | 0 |
| Group_update_ignore_count | 0 |
| Group_update_insert_dup | 0 |
| Group_update_leader_count | 2 |
| Group_update_mgr_recycle_queue_length | 0 |
| Group_update_recycle_queue_length | 0 |
| Group_update_reuse_count | 1 |
| Group_update_total_count | 1 |
+---------------------------------------+-------+
12 rows in set (0.00 sec)
使用限制
- 只支持基于主键的单行更新。
性能测试
测试不同并发数下,单行更新性能,统计tps和95%rt。
准备数据:
压测SQL:
UPDATE /*+ commit_on_success rollback_on_fail target_affect_row(1) */ t1 SET data=data+1 WHERE id=1;