添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Statement Concurrency Control

Statement Concurrency Control

为了确保 MySQL 实例在面对突发请求流量、高资源消耗语句和 SQL 访问模型变化时的稳定运行,阿里云提供了基于语句规则的并发控制(CCL)及相应的工具包(DBMS_CCL)。通过 DBMS_CCL,您可以限制特定类型 SQL 语句的最大并行执行数量。当指定 SQL 的并行执行数达到设定的限额后,额外的 SQL 语句则会进入等待状态,直到 SQL 的并行数量小于设定的限额。

前提条件

实例版本如下:

  • MySQL 8.0(内核小版本 20190816 或以上)

  • MySQL 5.7(内核小版本 20200630 或以上)

参数说明

参数

说明

ccl_max_waiting_count

命中同一条 CCL 规则的 SQL 中,最多能处于 Concurrency control waiting 状态的 SQL 数量。超过此限制后,SQL 将执行失败并返回错误码 ERROR 7534 (HY000): Concurrency control waiting count exceed max waiting count 。默认值为 0,表示没有限制。

ccl_wait_timeout

处于 Concurrency control waiting 状态的 SQL 能够等待的最长时间。超过此限制后,SQL 会继续执行,不再受 CCL 的限制。默认值为 86400 秒。

注意事项

  • CCL 的操作不产生日志,所以 CCL 的操作只影响当前实例。例如主实例进行 CCL 操作,不会同步到备实例、只读实例或灾备实例。

  • CCL 提供超时机制以应对 DML 导致事务锁死锁,等待中的线程也会响应事务超时和线程 KILL 操作以应对死锁。

功能设计

CCL 规则定义了如下四个维度的特征:

  • SQL command

    SQL 命令类型,例如 SELECT、UPDATE、INSERT、DELETE 等。

  • Object

    SQL 命令操作的对象,例如 TABLE、VIEW 等。

  • keywords

    SQL 命令的关键字。

  • Template

    SQL 命令的模板。

创建 CCL 规则表

AliSQL 设计了一个系统表(concurrency_control)保存 CCL 规则,系统启动时会自动创建该表,无需您手动创建。这里提供表的创建语句供您参考:

CREATE TABLE `concurrency_control` (
  `Id` bigint NOT NULL AUTO_INCREMENT,
  `Type` enum('SELECT','UPDATE','INSERT','DELETE','TEMPLATE') CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'SELECT',
  `Schema_name` varchar(64) COLLATE utf8mb3_bin DEFAULT NULL,
  `Table_name` varchar(64) COLLATE utf8mb3_bin DEFAULT NULL,
  `Concurrency_count` bigint NOT NULL,
  `Keywords` text COLLATE utf8mb3_bin,
  `State` enum('N','Y') CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'Y',
  `Ordered` enum('N','Y') CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'N',
  `Digest` varchar(64) COLLATE utf8mb3_bin DEFAULT NULL,
  `SQL_template` longtext COLLATE utf8mb3_bin,
  PRIMARY KEY (`Id`)
) /*!50100 TABLESPACE `mysql` */ ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0 COMMENT='Concurrency control'

参数

说明

Id

CCL 规则 ID。

Type

SQL command,即 SQL 命令类型。

Schema_name

数据库名。

Table_name

数据库内的表名。

Concurrency_count

并发数。当并发数设置为 0,会拒绝所有匹配该规则的 SQL 执行并返回错误码 ERROR 7535 (HY000): Concurrency control refuse to execute query

Keywords

关键字,多个关键字用英文分号(;)分隔。

State

本规则是否启用。

Ordered

Keywords 中多个关键字是否按顺序匹配。

Digest

根据 SQL_template 进行 Hash 计算得到的 64 字节的 Hash 字符串。

SQL_template

SQL 语句的模板。

管理 CCL 规则

为了便捷地管理 CCL 规则,AliSQL DBMS_CCL 中定义了四个本地存储规则。详细说明如下:

  • add_ccl_rule

    增加规则。命令如下:

    dbms_ccl.add_ccl_rule('<Type>','<Schema_name>','<Table_name>',<Concurrency_count>,'<Keywords>');

    示例:

    增加 SQL 命令规则,SELECT 语句的并发数为 10。

    mysql> call dbms_ccl.add_ccl_rule('SELECT', '', '', 10, '');

    增加关键字规则,SELECT 语句中出现关键字 key1 的并发数为 20。

    mysql> call dbms_ccl.add_ccl_rule('SELECT', '', '', 20, 'key1');

    增加完整规则,test.t 表且出现关键字 key2 SELECT 语句的并发数为 20。

    mysql> call dbms_ccl.add_ccl_rule('SELECT', 'test', 't', 20, 'key2');
  • add_ccl_template_rule

    增加模板规则。命令如下:

    dbms_ccl.add_ccl_rule('<Type>','<Schema_name>','<Table_name>',<Concurrency_count>,'', 'Template_sql');
    说明
    • Table_name 无需填写。Template_sql 不能为空并且只能填写一条 SQL。

    • 可以通过 STATEMENT_DIGEST_TEXT 内置函数查看 SQL 对应的 SQL 模板。

    • 仅适用于 MySQL 8.0 版本(小版本为 20230630 及之后版本)。

    示例:

    增加模板规则,test 数据库下,SQL 模板为 'SELECT c FROM t1 WHERE id=?' 的并发数为 30。

    call dbms_ccl.add_ccl_rule('TEMPLATE', 'test', '', 30, '', 'SELECT c FROM t1 WHERE id=4');
    说明
    • 在匹配限流规则时,每条 SQL 语句只能匹配一条限流规则。

    • 规则匹配的优先级顺序如下:模板规则 > 完整限流规则 > 关键字规则 > SQL 命令规则。依次检查每个规则集,以确定是否存在匹配的限流规则。

  • del_ccl_rule

    删除规则。命令如下:

    dbms_ccl.del_ccl_rule(<Id>);

    示例:

    删除规则 ID 15 CCL 规则。

    mysql> call dbms_ccl.del_ccl_rule(15);
    说明

    如果删除的规则不存在,系统会报相应的警告,您可以使用 show warnings; 查看警告内容。

    mysql> call dbms_ccl.del_ccl_rule(100);
      Query OK, 0 rows affected, 2 warnings (0.00 sec)
    mysql> show warnings;
    +---------+------+----------------------------------------------------+
    | Level   | Code | Message                                            |
    +---------+------+----------------------------------------------------+
    | Warning | 7514 | Concurrency control rule 100 is not found in table |
    | Warning | 7514 | Concurrency control rule 100 is not found in cache |
    +---------+------+----------------------------------------------------+
  • show_ccl_rule

    查看内存中已启用规则。命令如下:

    dbms_ccl.show_ccl_rule();

    示例:

    ​mysql> call dbms_ccl.show_ccl_rule();
    +------+--------+--------+-------+-------+-------+-------------------+---------+---------+----------+----------+
    | ID   | TYPE   | SCHEMA | TABLE | STATE | ORDER | CONCURRENCY_COUNT | MATCHED | RUNNING | WAITTING | KEYWORDS |
    +------+--------+--------+-------+-------+-------+-------------------+---------+---------+----------+----------+
    |   17 | SELECT | test   | t     | Y     | N     |                30 |       0 |       0 |        0 |          |
    |   16 | SELECT |        |       | Y     | N     |                20 |       0 |       0 |        0 | key1     |
    |   18 | SELECT |        |       | Y     | N     |                10 |       0 |       0 |        0 |          |
    +------+--------+--------+-------+-------+-------+-------------------+---------+---------+----------+----------+​

    关于 MATCHED RUNNING WAITTING 的说明如下。

    参数

    说明

    MATCHED

    规则匹配成功次数。

    RUNNING

    此规则下正在并发执行的线程数。

    WAITTING

    此规则下正在等待执行的线程数。

  • flush_ccl_rule

    如果您直接操作了表 concurrency_control 修改规则,规则不能立即生效,您需要让规则重新生效。命令如下:

    dbms_ccl.flush_ccl_rule();

    示例:

    ​mysql> update mysql.concurrency_control set CONCURRENCY_COUNT = 15 where Id = 18;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    mysql> call dbms_ccl.flush_ccl_rule();
    Query OK, 0 rows affected (0.00 sec)​

功能测试

  • 测试规则

    设计如下三条规则对应三个维度:

    -- SELECT命令操作表sbtest1并发数为3
    call dbms_ccl.add_ccl_rule('SELECT', 'test', 'sbtest1', 3, '');
    -- SELECT命令关键字sbtest2并发数为2
    call dbms_ccl.add_ccl_rule('SELECT', '', '', 2, 'sbtest2');  
    -- SELECT命令并发数为2
    call dbms_ccl.add_ccl_rule('SELECT', '', '', 2, '');
  • 测试场景

    使用 sysbench 进行测试,场景如下:

    • 64 threads

    • 4 tables

    • select.lua

  • 测试结果

    查看规则并发数情况如下:

    ​mysql> call dbms_ccl.show_ccl_rule();
    +------+--------+--------+---------+-------+-------+-------------------+---------+---------+----------+----------+
    | ID   | TYPE   | SCHEMA | TABLE   | STATE | ORDER | CONCURRENCY_COUNT | MATCHED | RUNNING | WAITTING | KEYWORDS |
    +------+--------+--------+---------+-------+-------+-------------------+---------+---------+----------+----------+
    |   20 | SELECT | test   | sbtest1 | Y     | N     |                 3 |     389 |       3 |        9 |          |
    |   21 | SELECT |        |         | Y     | N     |                 2 |     375 |       2 |       14 | sbtest2  |
    |   22 | SELECT |        |         | Y     | N     |                 2 |     519 |       2 |       34 |          |
    +------+--------+--------+---------+-------+-------+-------------------+---------+---------+----------+----------+
    3 rows in set (0.00 sec)​

    查看 RUNNING 列,符合预期的并行数量。