当前仅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如下:

  1. Query OK, 0 rows affected (0.01 sec)
  2. mysql> insert into test values (1, 1);
  3. Query OK, 1 row affected (0.01 sec)
  4. mysql> update /*+ commit_on_success */ test set data = data + 1 where id = 1;
  5. Query OK, 1 row affected (0.00 sec)
  6. Rows matched: 1 Changed: 1 Warnings: 0
  7. mysql> select * from test;
  8. +----+------+
  9. +----+------+
  10. | 1 | 2 |
  11. +----+------+
  12. 1 row in set (0.00 sec)
  13. mysql> update /*+ commit_on_success rollback_on_fail target_affect_row(1) */ test set data = data + 1 where id = 1;
  14. Query OK, 1 row affected (0.00 sec)
  15. Rows matched: 1 Changed: 1 Warnings: 0
  16. mysql> select * from test;
  17. +----+------+
  18. | id | data |
  19. +----+------+
  20. | 1 | 3 |
  21. +----+------+
  22. 1 row in set (0.00 sec)

此外也支持select ... from update的语法,可以直接返回更新后的数据。

  1. mysql> show global status like "%Group_update%";
  2. +---------------------------------------+-------+
  3. | Group_update_fail_count | 0 |
  4. | Group_update_follower_count | 0 |
  5. | Group_update_free_count | 1 |
  6. | Group_update_gu_leak_count | 0 |
  7. | Group_update_gu_lock_fail_count | 0 |
  8. | Group_update_ignore_count | 0 |
  9. | Group_update_insert_dup | 0 |
  10. | Group_update_leader_count | 2 |
  11. | Group_update_mgr_recycle_queue_length | 0 |
  12. | Group_update_recycle_queue_length | 0 |
  13. | Group_update_reuse_count | 1 |
  14. | Group_update_total_count | 1 |
  15. +---------------------------------------+-------+
  16. 12 rows in set (0.00 sec)

使用限制

  • 只支持基于主键的单行更新。

性能测试

测试不同并发数下,单行更新性能,统计tps和95%rt。

准备数据:

压测SQL:

  1. UPDATE /*+ commit_on_success rollback_on_fail target_affect_row(1) */ t1 SET data=data+1 WHERE id=1;