RDS MySQL 8.0 Statement queue

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: 【7】Statement Queue 背景 MySQL 的 server 层和引擎层在 statement 并发执行过程中,有很多串行化的点,在 DML 语句中,事务锁冲突比较常见,InnoDB 中事务锁的最细粒度是行级锁,如果语句针对相同行进行并发操作,会导致冲突比较严重,系统吞吐量会随着并发的增加而递减。

【7】Statement Queue

背景

MySQL 的 server 层和引擎层在 statement 并发执行过程中,有很多串行化的点,在 DML 语句中,事务锁冲突比较常见,InnoDB 中事务锁的最细粒度是行级锁,如果语句针对相同行进行并发操作,会导致冲突比较严重,系统吞吐量会随着并发的增加而递减。
AliSQL 设计了针对语句的排队机制,相同的行或者不同的语句进行分桶排队,尽可能的把具有相同冲突可能的在一个桶内排队,减少 conflict 的开销。 

语法

变量

系统提供了两个变量来定义 CCL queue 的 bucket 数量和大小。

1. ccl_queue_bucket_count

表示:一共有多少个bucket, 默认值:4,取值范围:[1, 64]

2. ccl_queue_bucket_size

表示:一个 bucket 允许并发数是多少, 默认值:64, 取值范围:[1, 4096]

Hint

系统支持两个 hint语法:

  1. CCL_QUEUE_VALUE

根据 value 的值进行 HASH 分桶

 语法:
    /*+ CCL_QUEUE_VALUE([INT | STRING)] */
                
 例子:
  UPDATE /*+ ccl_queue_value(1) */ t 
    SET c=c+1
   WHERE id = 1;
  
  UPDATE /*+ ccl_queue_value('xpchild') */ t
    SET c=c+1 
   WHERE name = 'xpchild';
  1. CCL_QUEUE_FIELD

根据 where 条件中的 field 指定的值进行 hash 分桶

语法:
    /*+ CCL_QUEUE_FIELD(STRING) */
  
例如:
  UPDATE /*+ ccl_queue_field("id") */ t
    SET c=c+1                                                                         
   WHERE id = 1 AND name = 'xpchild';
 
  在 WHERE 条件中查找 id 字段指定的条件常量值来进行分桶

 注意: CCL_QUEUE_FIELD 填入的字段名字, 在 WHERE 条件的查找过程中:

  1. 只支持对裸字段的二元运算符的条件
  2. 二元运算的右值必须是数字或者字符串

接口

系统支持两个接口进行查询当前的状态:

  1. dbms_ccl.show_ccl_queue()
mysql> call dbms_ccl.show_ccl_queue();   
+------+-------+-------------------+---------+---------+----------+
| ID   | TYPE  | CONCURRENCY_COUNT | MATCHED | RUNNING | WAITTING |
+------+-------+-------------------+---------+---------+----------+
|    1 | QUEUE |                64 |       1 |       0 |        0 |
|    2 | QUEUE |                64 |   40744 |      65 |        6 |
|    3 | QUEUE |                64 |       0 |       0 |        0 |
|    4 | QUEUE |                64 |       0 |       0 |        0 |
+------+-------+-------------------+---------+---------+----------+
4 rows in set (0.01 sec)

CONCURRENCY_COUNT: 最大并发数
MATCHED: 命中规则的累积数量
RUNNING:当前并发的数量
WAITTING: 当前等待的数量

  1. dbms_ccl.flush_ccl_queue()

清理内存中的状态, 重新加载

mysql> call dbms_ccl.flush_ccl_queue();                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       Query OK, 0 rows affected (0.00 sec)

mysql> call dbms_ccl.show_ccl_queue();
+------+-------+-------------------+---------+---------+----------+
| ID   | TYPE  | CONCURRENCY_COUNT | MATCHED | RUNNING | WAITTING |
+------+-------+-------------------+---------+---------+----------+
|    1 | QUEUE |                64 |       0 |       0 |        0 |
|    2 | QUEUE |                64 |       0 |       0 |        0 |
|    3 | QUEUE |                64 |       0 |       0 |        0 |
|    4 | QUEUE |                64 |       0 |       0 |        0 |
+------+-------+-------------------+---------+---------+----------+
4 rows in set (0.00 sec)

效果

针对单行进行并发 update 的场景下,目前进行的测试,相比较原生的 MySQL, AliSQL 有接近 4 倍的提升。

配合 outline 在线修改

为了能够快速在线修改 SQL statement 的并发控制,而不介入冗长的应用业务代码的修改,这里可以使用 AliSQL 提供的 Outline 来配合, 下面使用 sysbench 的 update_non_index 作为一个例子:

测试环境:

测试表结构:

CREATE TABLE `sbtest1` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `k` int(10) unsigned NOT NULL DEFAULT '0',
  `c` char(120) NOT NULL DEFAULT '',
  `pad` char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `k_1` (`k`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 MAX_ROWS=1000000;

测试语句:

UPDATE sbtest1 SET c='xpchild' WHERE id=0;

测试脚本:

./sysbench 
--mysql-host= {$ip}
--mysql-port= {$port}
--mysql-db=test 
--test=./sysbench/share/sysbench/update_non_index.lua 
--oltp-tables-count=1 
--oltp_table_size=1 
--num-threads=128
--mysql-user=u0

测试过程

1. 在线增加 outline 

mysql> CALL DBMS_OUTLN.add_optimizer_outline('test', '', 1, 
                                             ' /*+ ccl_queue_field("id") */ ',
                          "UPDATE sbtest1 SET c='xpchild' WHERE id=0");
Query OK, 0 rows affected (0.01 sec)

2. 查看 outline 并验证 

mysql> call dbms_outln.show_outline();
+------+--------+------------------------------------------------------------------+-----------+-------+------+--------------------------------+------+----------+---------------------------------------------+
| ID   | SCHEMA | DIGEST                                                           | TYPE      | SCOPE | POS  | HINT                           | HIT  | OVERFLOW | DIGEST_TEXT                                 |
+------+--------+------------------------------------------------------------------+-----------+-------+------+--------------------------------+------+----------+---------------------------------------------+
|    1 | test   | 7b945614749e541e0600753367884acff5df7e7ee2f5fb0af5ea58897910f023 | OPTIMIZER |       |    1 |  /*+ ccl_queue_field("id") */  |    0 |        0 | UPDATE `sbtest1` SET `c` = ? WHERE `id` = ? |
+------+--------+------------------------------------------------------------------+-----------+-------+------+--------------------------------+------+----------+---------------------------------------------+
1 row in set (0.00 sec)

3. 验证 outline 生效

mysql> explain UPDATE sbtest1 SET c='xpchild' WHERE id=0;
+----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table   | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra       |
+----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
|  1 | UPDATE      | sbtest1 | NULL       | range | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | Using where |
+----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> show warnings;
+-------+------+-----------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message                                                                                                                     |
+-------+------+-----------------------------------------------------------------------------------------------------------------------------+
| Note  | 1003 | update /*+ CCL_QUEUE_FIELD('id') */ `test`.`sbtest1` set `test`.`sbtest1`.`c` = 'xpchild' where (`test`.`sbtest1`.`id` = 0) |
+-------+------+-----------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

4. 查看 ccl queue 初始状态  

mysql> call dbms_ccl.show_ccl_queue();
+------+-------+-------------------+---------+---------+----------+
| ID   | TYPE  | CONCURRENCY_COUNT | MATCHED | RUNNING | WAITTING |
+------+-------+-------------------+---------+---------+----------+
|    1 | QUEUE |                64 |       0 |       0 |        0 |
|    2 | QUEUE |                64 |       0 |       0 |        0 |
|    3 | QUEUE |                64 |       0 |       0 |        0 |
|    4 | QUEUE |                64 |       0 |       0 |        0 |
+------+-------+-------------------+---------+---------+----------+
4 rows in set (0.00 sec)

5. 开启测试  

sysbench 
--mysql-host= {$ip}
--mysql-port= {$port}
--mysql-db=test 
--test=./sysbench/share/sysbench/update_non_index.lua 
--oltp-tables-count=1 
--oltp_table_size=1 
--num-threads=128
--mysql-user=u0

6. 验证测试效果  

mysql> call dbms_ccl.show_ccl_queue();
+------+-------+-------------------+---------+---------+----------+
| ID   | TYPE  | CONCURRENCY_COUNT | MATCHED | RUNNING | WAITTING |
+------+-------+-------------------+---------+---------+----------+
|    1 | QUEUE |                64 |   10996 |      63 |        4 |
|    2 | QUEUE |                64 |       0 |       0 |        0 |
|    3 | QUEUE |                64 |       0 |       0 |        0 |
|    4 | QUEUE |                64 |       0 |       0 |        0 |
+------+-------+-------------------+---------+---------+----------+
4 rows in set (0.03 sec)

ccl queue 显示命中了10996 次排队, 当前运行并发63个,排队等待4个。 

mysql> call dbms_outln.show_outline();
+------+--------+-----------+-----------+-------+------+--------------------------------+--------+----------+---------------------------------------------+
| ID   | SCHEMA | DIGEST    | TYPE      | SCOPE | POS  | HINT                           | HIT    | OVERFLOW | DIGEST_TEXT                                 |
+------+--------+-----------+-----------+-------+------+--------------------------------+--------+----------+---------------------------------------------+
|    1 | test   | xxxxxxxxx | OPTIMIZER |       |    1 |  /*+ ccl_queue_field("id") */  | 115795 |        0 | UPDATE `sbtest1` SET `c` = ? WHERE `id` = ? |
+------+--------+-----------+-----------+-------+------+--------------------------------+--------+----------+---------------------------------------------+
1 row in set (0.00 sec)

outline 显示命中了115795 次。 

Ccl queue 可以配合着 outline 进行在线修改业务,方便快捷。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
2月前
|
存储 SQL 关系型数据库
RDS DuckDB技术解析一:当 MySQL遇见列式存储引擎
RDS MySQL DuckDB分析实例以​列式存储与向量化计算​为核心,实现​复杂分析查询性能百倍跃升​,为企业在海量数据规模场景下提供​实时分析能力​,加速企业数据驱动型决策效能。​​
|
5月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
1月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
|
1月前
|
关系型数据库 分布式数据库 数据库
阿里云数据库收费价格:MySQL、PostgreSQL、SQL Server和MariaDB引擎费用整理
阿里云数据库提供多种类型,包括关系型与NoSQL,主流如PolarDB、RDS MySQL/PostgreSQL、Redis等。价格低至21元/月起,支持按需付费与优惠套餐,适用于各类应用场景。
|
1月前
|
SQL 关系型数据库 MySQL
Mysql数据恢复—Mysql数据库delete删除后数据恢复案例
本地服务器,操作系统为windows server。服务器上部署mysql单实例,innodb引擎,独立表空间。未进行数据库备份,未开启binlog。 人为误操作使用Delete命令删除数据时未添加where子句,导致全表数据被删除。删除后未对该表进行任何操作。需要恢复误删除的数据。 在本案例中的mysql数据库未进行备份,也未开启binlog日志,无法直接还原数据库。
|
1月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎,提供高性价比、稳定安全的云数据库服务,适用于多种行业与业务场景。
|
1月前
|
关系型数据库 MySQL 数据库
云时代MySQL:RDS与自建数据库的抉择
在云计算时代,选择合适的数据库部署方案至关重要。本文深入对比了AWS RDS与自建MySQL的优劣,帮助您在控制权、运维成本和业务敏捷性之间找到最佳平衡点。内容涵盖核心概念、功能特性、成本模型、安全性、性能优化、高可用方案及迁移策略,为您提供全面的决策参考。
|
2月前
|
关系型数据库 MySQL 程序员
从自建MySQL到阿里云RDS:程序员的数据库减负革命
如果你正在为自建MySQL数据库的高成本运维发愁,为凌晨三点的主从同步故障告警而崩溃,为开发团队频繁索要新测试库的要求感到窒息——是时候开启一场数据库的自我救赎了。 程序员更需构建"技术敏锐度+工程落地能力+跨域协作"的三维竞争力,通过创建技术组合形成差异化优势。企业应建立持续学习机制,提供AI沙盒环境促进技术转化。
|
5月前
|
存储 关系型数据库 MySQL
【免费动手教程上线】阿里云RDS MySQL推出大容量高性能存储:高性能本地盘(最高16TB存储空间)、高性能云盘(最高64TB存储空间)
阿里云RDS MySQL提供高性能本地盘与高性能云盘等存储方案,满足用户大容量、低延迟需求。高性能本地盘单盘最大16TB,IO延时微秒级;高性能云盘兼容ESSD特性,支持IO性能突发、BPE及16K原子写等能力。此外,阿里云还提供免费动手体验教程,帮助用户直观感受云数据库 RDS 存储性能表现。
|
6月前
|
负载均衡 算法 关系型数据库
大数据新视界--大数据大厂之MySQL数据库课程设计:MySQL集群架构负载均衡故障排除与解决方案
本文深入探讨 MySQL 集群架构负载均衡的常见故障及排除方法。涵盖请求分配不均、节点无法响应、负载均衡器故障等现象,介绍多种负载均衡算法及故障排除步骤,包括检查负载均衡器状态、调整算法、诊断修复节点故障等。还阐述了预防措施与确保系统稳定性的方法,如定期监控维护、备份恢复策略、团队协作与知识管理等。为确保 MySQL 数据库系统高可用性提供全面指导。

热门文章

最新文章

推荐镜像

更多