为应对突发的数据库请求流量、资源消耗过高的语句访问以及SQL访问模型的变化等问题,PolarDB-X提供了节点级别的SQL限流功能来限制造成上述问题的SQL执行,从而保证实例的持续稳定运行。本文介绍如何使用SQL限流功能。
版本限制
仅计算节点组件版本为5.4.9-16167266及以上的PolarDB-X企业版实例支持SQL限流功能,其中慢SQL限流触发器则需要实例的计算节点组件版本为5.4.11-16251897及以上。
创建限流规则
语法
CREATE CCL_RULE [ IF NOT EXISTS ] `ccl_rule_name`
ON `database`.`table`
TO '<username>'@'<host>'
FOR { UPDATE | SELECT | INSERT | DELETE }
[ filter_options ]
with_options
filter_options:
[ FILTER BY KEYWORD('KEYWORD1', 'KEYWORD2',…) ]
[ FILTER BY TEMPLATE('template_id') ]
with_options:
WITH MAX_CONCURRENCY = value1 [ , WAIT_QUEUE_SIZE = value2 ] [ , WAIT_TIMEOUT = value3 ] [ ,FAST_MATCH = { 0 , 1 }]
参数说明:
参数 | 是否必选 | 说明 | |
限流规则匹配参数 |
| 必选 | 限流规则的名称。 说明 为避免名称与SQL关键字冲突,建议在规则名称前后各加一个反引号(`)。 |
| 必选 | 数据库和数据表的名称,支持使用星号(*)表示任意匹配。 说明 为避免名称与SQL关键字冲突,建议在库表名称前后各加一个反引号(`)。 | |
| 必选 | 账号名称。其中 | |
| 必选 | SQL语句类型。当前支持UPDATE、SELECT、INSERT和DELETE类型。 说明 每条限流规则仅支持传入一种类型的SQL语句。 | |
| 可选 | 过滤条件,支持包括如下两种条件:
| |
限流规则行为控制参数 |
| 必选 | WITH选项中支持如下4个参数来控制限流规则的行为:
说明
|
仅当一个SQL语句满足所有的匹配参数条件时,才会根据该规则的WITH选项进行限流。
示例
假设需要创建一条名为selectrule
的规则,用于限制账号为'ccltest'@'%'
用户发起的,包含cclmatched
关键字的,且对任意表执行SELECT操作的SQL语句,同时将最大并发度设置为10。
规则创建语句如下:
CREATE CCL_RULE IF NOT EXISTS `selectrule` ON *.* TO 'ccltest'@'%'
FOR SELECT
FILTER BY KEYWORD('cclmatched')
WITH MAX_CONCURRENCY=10;
账号ccltest
从任何IP发起的查询(SELECT
语句),且含有cclmatched
关键字,这一类查询语句的最高并发为10。
限流结果
某条SQL匹配到该规则后,根据限流规则中WITH
选项里配置的参数,会出现如下几种结果:
RUN(可运行)
若并发度还未达到最大并发度(即MAX_CONCURRENCY参数值没有达到最大值),该SQL正常执行不会被限流。
WAIT(等待中)
若并发度已经达到最大并发度,但等待队列长度还未达到最大长度(即WAIT_QUEUE_SIZE参数值没有达到最大值),该SQL进入等待状态,直到进入可运行(RUN)状态,或者等待超时(WAIT_TIMEOUT)状态。您可以通过如下命令查看由于匹配到限流规则而等待的SQL语句:
SHOW FULL PROCESSLIST;
结果如下:
+----+---------------+-----------------+----------+-------------------------------+------+-------+-----------------------+-----------------+ | ID | USER | HOST | DB | COMMAND | TIME | STATE | INFO | SQL_TEMPLATE_ID | +----+---------------+-----------------+----------+-------------------------------+------+-------+-----------------------+-----------------+ | 2 | polardbx_root | ***.*.*.*:62787 | polardbx | Query | 0 | | show full processlist | NULL | | 1 | polardbx_root | ***.*.*.*:62775 | polardbx | Query(Waiting-selectrulereal) | 12 | | select 1 | 9037e5e2 | +----+---------------+-----------------+----------+-------------------------------+------+-------+-----------------------+-----------------+ 2 rows in set (0.08 sec)
说明SQL语句
select 1
由于限流规则selectrulereal
而处于等待(Waiting)状态。WAIT_TIMEOUT(等待超时)
SQL语句进入等待状态后,当等待时间超过最长等待时间(
WAIT_TIMEOUT
)时,该语句将会执行失败并返回错误信息。例如:设置了一条最长等待时间为10秒的限流规则,执行SELECT sleep(11)
语句时会因为等待超时而报错,示例如下:ERROR 3009 (HY000): [11a07e23fd800000][30.225.XXX.XX:8527][polardbx]Exceeding the max concurrency 0 of ccl rule selectrulereal after waiting for 10060 ms
KILL(结束)
并发度和等待队列长度均已经达到最大值,客户端将收到超过最大并发度的报错,报错信息中会包含匹配上的限流规则的名称。例如:在并发度和等待队列长度均已经达到最大值后执行
SELECT 1;
命令,会出现如下报错:ERROR 3009 (HY000): [11a07c4425c00000][**.***.***.**:8527][polardbx]Exceeding the max concurrency 0 of ccl rule selectrulereal
说明该SQL语句
SELECT 1;
由于超出了限流规则selectrulereal
设置的最大并发度而执行失败。
查看限流规则
查看指定限流规则
指定规则名称进行查看,多个名称用,
分隔。
语法:
SHOW CCL_RULE `ccl_rule_name1` [, `ccl_rule_name2` ]
示例:
SHOW CCL_RULE `selectrulereal`
结果如下:
NO.: 1
RULE_NAME: selectrulereal
RUNNING: 2
WAITING: 29
KILLED: 0
MATCH_HIT_CACHE: 21374
TOTAL_MATCH: 21406
ACTIVE_NODE_COUNT: 2
MAX_CONCURRENCY_PER_NODE: 1
WAIT_QUEUE_SIZE_PER_NODE: 100
WAIT_TIMEOUT: 600
FAST_MATCH: 1
SQL_TYPE: SELECT
USER: ccltest@%
TABLE: *.*
KEYWORDS: ["SELECT"]
TEMPLATEID: NULL
CREATED_TIME: 2020-11-26 17:04:08
字段说明:
字段 | 说明 |
NO. | 匹配优先级,数字越小,优先级越高。 |
RULE_NAME | 限流规则名称。 |
RUNNING | 匹配到该限流规则且正常执行的SQL语句数量。 |
WAITING | 匹配到该限流规则且正在等待队列里的查询数量。 |
KILLED | 匹配到该限流规则且被KILL的SQL语句数量。 |
MATCH_HIT_CACHE | 匹配到该限流规则且命中Cache的SQL语句数量。 |
TOTAL_MATCH | 匹配到该限流规则命中的总次数。 |
ACTIVE_NODE_COUNT | 计算层中启用了SQL限流的节点数。 |
MAX_CONCURRENCY_PER_NODE | 每个计算节点的并发度。 |
WAIT_QUEUE_SIZE_PER_NODE | 每个计算节点上等待队列的最大长度。 |
WAIT_TIMEOUT | SQL语句在等待队列的最大等待时间。 |
FAST_MATCH | 是否启动缓存加速匹配速度。 |
SQL_TYPE | SQL语句类型。 |
USER | 用户名。 |
TABLE | 数据库表。 |
KEYWORDS | 关键词列表。 |
TEMPLATEID | SQL模板的编号。 |
CREATED_TIME | 创建时间(本地时间),格式为 |
查看所有限流规则
SHOW CCL_RULES;
删除限流规则
被删除的限流规则会立即失效,此时该规则下等待队列中的SQL语句全部会被正常执行。
删除指定限流规则。
指定规则名称进行删除,多个名称用
,
分隔。语法:
DROP CCL_RULE [ IF EXISTS ] `ccl_rule_name1` [, `ccl_rule_name2`, ...]
示例:
DROP CCL_RULE IF EXISTS `selectrulereal`;
删除所有限流规则:
CLEAR CCL_RULES;
慢SQL限流触发器
开启慢SQL限流触发器
当SQL的执行时间超过某一阈值时,系统可以自动为该SQL创建一个限流规则。
语法:
SLOW_SQL_CCL GO ['SQL_TYPE'[MAX_CONCURRENCY] [SLOW_SQL_TIME] [MAX_CCL_RULE]]
示例:
SLOW_SQL_CCL GO 'SELECT' 2 5 2;
参数说明:
SQL_TYPE:取值为ALL,SELECT,UPDATE,INSERT,默认值为SELECT。相同语句类型的命令,有更新作用。
MAX_CONCURRENCY:自动创建的限流规则的最高并发数,默认值为CPU核数的一半。
SLOW_SQL_TIME:慢SQL的执行时间,SQL执行时间超过此值时会执行该触发器,默认值为系统参数SLOW_SQL_TIME的值,单位为毫秒(ms)。
MAX_CCL_RULE:可创建限流规则的个数,默认值为1000。
执行过程:
遍历整个实例的Session,识别出该语句类型慢SQL的TemlateId。
创建针对慢SQL的限流触发器,名称为:_SYSTEM_SLOW_SQL_CCL_TRIGGER_{SQL_TYPE}_。
传递慢SQL的TemplateId给限流触发器,由限流触发器创建限流规则。
KILL(结束)所有超过MAX_CONCURRENCY的该语句类型的慢TemplateId查询。
查看慢SQL限流触发器
SLOW_SQL_CCL SHOW;
结果如下:
字段名 | 值 |
NO. | 1 |
SCHEMA | __cdc__ |
TEMPLATE_ID | 1394f5db |
SQL | SELECT * FROM test |
RULE_NAME | AUTO__SYSTEM_SLOW_SQL_CCL_TRIGGER_SELECT____cdc___1394f5db_9e1c7f6d |
RUNNING | 0 |
WAITING | 0 |
KILLED | 0 |
TOTAL_MATCH | 0 |
ACTIVE_NODE_COUNT | 4 |
MAX_CONCURRENCY_PER_NODE | 2 |
CREATED_TIME | 2025-04-23 00:00:00 |
调整慢SQL的阈值
调整慢SQL的阈值有三种方式,按优先级降序排序如下:
在
SLOW_SQL_CCL GO
语句中设置SLOW_SQL_TIME参数的值。在一键开启SQL限流之前,设置用户变量SLOW_SQL_TIME。
示例:
SET @slow_sql_time=2000; SLOW_SQL_CCL GO;
在控制台上设置系统参数SLOW_SQL_TIME。
关闭慢SQL限流触发器
关闭由SLOW_SQL_CCL GO
创建的限流触发器,会同时删除由限流触发器创建的限流规则。
SLOW_SQL_CCL BACK;