tencent cloud

文档反馈

SQL限流

最后更新时间:2024-10-28 17:38:28

    使用限制

    注意:
    重启和 HA 及大版本升级后,规则不在内存,将失效,需要重新加载。
    不支持直接配置扩展协议(Extended Query Protocol)的 SQL 配置限流规则,更多扩展协议的说明请参考 官方文档
    SQL 限流功能当前仅支持内核版本在 v14.11_r1.23、v15.6_r1.12、v16.2_r1.6及以上的云数据库 PostgreSQL 实例,如您需要,请 升级小版本升级大版本
    当限流规则被加载到内存时才生效,新增规则时默认将规则持久化到表 tencentdb_sql_throttling.persistent_rules_table 中,重启或者 HA 后可重新将规则加载进内存。

    创建插件

    说明:
    如您需要使用 SQL 限流功能,请您 提交工单 联系我们添加 shared_preload_libraries 参数。修改 shared_preload_libraries 参数会重启实例,请确保业务有重连机制。
    检查 shared_preload_libraries 参数中已经加入 tencentdb_sql_throttling:
    postgres=> show shared_preload_libraries;
    shared_preload_libraries
    -------------------------------------------------------------------------------------------------------
    ----------------------------------------------
    pg_stat_statements,pg_stat_log,wal2json,decoderbufs,decoder_raw,pg_hint_plan,rds_server_handler,tencen
    tdb_pwdcheck,pgaudit,tencentdb_sql_throttling
    (1 row)
    创建 tencentdb_sql_throttling 插件,并检查创建完成:
    postgres=> create extension tencentdb_sql_throttling; CREATE EXTENSION postgres=> select * from pg_extension where extname='tencentdb_sql_throttling';
    oid | extname | extowner | extnamespace | extrelocatable | extversion | extconfig | extcondition
    -------+--------------------------+----------+--------------+----------------+------------+-----------+--------------
    16415 | tencentdb_sql_throttling | 16385 | 2200 | t | 1.0 | |
    (1 row)

    新增限流规则

    云数据库 PostgreSQL 支持通过 query_id 和 SQL 来新增限流规则。其中 query_id 是内核将 query 语句规范化后哈希得到的64位整数,是一个用于标识查询的唯一标识符,更多 query_id 的详细说明请参考 官方文档

    通过 query_id 新增限流规则

    如您需要获取 SQL 语句的 query_id,您可通过查询 pg_stat_statements 或 pg_stat_activity 得到。本文是通过查询 pg_stat_activity 得到。
    postgres=> select datname,usename,client_addr,state,query_id,query from pg_stat_activity where usename='dbadmin' and client_addr='172.16.76.48' limit 10; datname | usename | client_addr | state | query_id | query ----------+---------+---------------+--------+--------------------+-------------------------------- postgres | dbadmin | 172.16.76.48 | active | 497939862935121343 | SELECT id FROM t WHERE id = 1 postgres | dbadmin | 172.16.76.48 | active | 497939862935121343 | SELECT id FROM t WHERE id = 53 postgres | dbadmin | 172.16.76.48 | active | 497939862935121343 | SELECT id FROM t WHERE id = 54 postgres | dbadmin | 172.16.76.48 | active | 497939862935121343 | SELECT id FROM t WHERE id = 4 postgres | dbadmin | 172.16.76.48 | active | 497939862935121343 | SELECT id FROM t WHERE id = 52 postgres | dbadmin | 172.16.76.48 | active | 497939862935121343 | SELECT id FROM t WHERE id = 51 postgres | dbadmin | 172.16.76.48 | active | 497939862935121343 | SELECT id FROM t WHERE id = 7 postgres | dbadmin | 172.16.76.48 | active | 497939862935121343 | SELECT id FROM t WHERE id = 10 postgres | dbadmin | 172.16.76.48 | active | 497939862935121343 | SELECT id FROM t WHERE id = 11 postgres | dbadmin | 172.16.76.48 | active | 497939862935121343 | SELECT id FROM t WHERE id = 8 (10 rows)
    在获取到 query_id 之后,我们可基于 query_id 新增限流规则。云数据库 PostgreSQL 提供了一个函数供您使用,函数定义如下:
    tencentdb_sql_throttling.add_rule_with_queryid(
    queryid bigint,
    work_node int,
    max_concurrency int,
    is_enabled boolean,
    memory_only boolean,
    query_string text
    );
    add_rule_with_queryid 函数的参数解释如下:
    说明:
    queryid:将 query 语句规范化后哈希得到的64位整数,可通过 pg_stat_statements 或 pg_stat_activity 查询得到;
    work_node:限流规则生效的节点,0表示主实例和只读实例都生效,1表示只有主实例生效,2表示只有只读实例生效;
    max_concurrency:该限流规则允许的最大并发数量;
    is_enabled:当前规则是否生效,取值为 true 和 false;
    memory_only:可选,是否需要将规则持久化到表中,重启或者 HA 后可使用命令重新将规则加载进内存以生效;
    query_string:可选,可以将 query 语句加入规则中,此时不对此 query_string 计算 queryid 进行校验,该限流规则以 queryid 为准。若不提供此参数,内核将自动在 pg_stat_statements 视图中查找该 queryid 对应的 sql 语句,并将结果记录在该规则中。
    work_node:限流规则生效的节点,0 表示主实例和只读实例都生效,1 表示只有主实例生效,2 表示只有只读实例生效;
    max_concurrency:该限流规则允许的最大并发数量;
    is_enabled:当前规则是否生效;
    memory_only:可选,是否需要将规则持久化到表中,重启或者 HA 后可使用命令重新将规则加载进内存以生效;
    query_string:可选,可以将 query 语句加入规则中,此时不对此 query_string 计算 queryid 进行校验,该限流规则以 queryid 为准。若不提供此参数,内核将自动在 pg_stat_statements 视图中查找该 queryid 对应的 sql 语句,并将结果记录在该规则中。SQL 限流示例如下 SQL 限流示例如下:
    postgres=> SELECT tencentdb_sql_throttling.add_rule_with_queryid(497939862935121343,0,10,true); add_rule_with_queryid ----------------------- (1 row)

    通过 SQL 语句新增限流规则

    说明:
    暂时不支持扩展协议的 SQL 语句的限流。
    如果 SQL 语句中的数据库对象已经存在限流规则,则无法新增规则。
    云数据库 PostgreSQL 提供了限流的函数供您使用,函数定义如下:
    tencentdb_sql_throttling.add_rule_with_query(
    query_string text,
    work_node int,
    max_concurrency int,
    is_enabled boolean,
    memory_only boolean
    )
    add_rule_with_query 函数的参数解释如下,该函数返回值为限流的 SQL 语句的 query_id:
    说明:
    query_string:需要限流的 SQL 语句;
    work_node:限流规则生效的节点,0表示主实例和只读实例都生效,1表示只有主实例生效,2表示只有只读实例生效;
    max_concurrency:该限流规则允许的最大并发数量;
    is_enabled:当前规则是否生效,取值为 true 和 false;
    memory_only:可选,是否需要将规则持久化到表中,重启或 HA 后可使用命令重新将规则加载进内存;
    SQL 限流示例如下:
    postgres=# select tencentdb_sql_throttling.add_rule_with_query('select pg_sleep(1);',0,1,true);
    add_rule_with_query
    ----------------------
    -3416356442043621232
    (1 row)
    限流规则设置完成后可查看限流规则,请参考 查看限流规则

    删除限流规则

    通过 query_id 删除规则

    在获取到 query_id 之后,我们可基于 query_id 删除限流规则。云数据库 PostgreSQL 提供了一个函数供您使用,函数定义如下:
    tencentdb_sql_throttling.drop_rule(
    queryid bigint,
    memory_only boolean
    );
    drop_rule 函数的参数解释如下:
    说明:
    queryid:将 query 语句规范化后哈希得到的64位整数,可通过 pg_stat_statements 或 pg_stat_activity 查询得到;
    memory_only
    memory_only 为 true 时,只删除内存中的规则,持久化表中的规则不受影响,可看作从内存中卸载限流规则;
    memory_only 为 false 时,将同时删除内存和表中的规则,如果无法删除,将打印 WARNING 日志。 只读实例只能删除内存中的规则。
    删除示例如下:
    postgres=> SELECT tencentdb_sql_throttling.drop_rule(497939862935121343,true); -[ RECORD 1 ] drop_rule |
    当需要删除某些没有加载到内存中的 SQL 限流规则时,您可直接删除持久化表格中对应的 SQL 限流规则数据即可

    删除所有规则

    当您需要删除所有 SQL 限流规则时,云数据库 PostgreSQL 提供了一个函数供您使用,函数定义如下:
    tencentdb_sql_throttling.drop_all_rules(
    memory_only boolean
    );
    drop_all_rules 函数的参数解释如下:
    说明:
    memory_only
    memory_only 为 true 时,只删除内存中的规则,持久化表中的规则不受影响,可看作从内存中卸载限流规则;
    memory_only 为 false 时,将同时删除内存和表中的规则,如果无法删除,将打印 WARNING 日志。 只读实例只能删除内存中的规则。
    删除示例如下:
    postgres=> select tencentdb_sql_throttling.drop_all_rules(true);
    drop_all_rules
    ----------------
    (1 row)

    加载限流规则

    加载限流规则是指将存储在磁盘中的 SQL 限流规则加载到内存中,并使之生效。

    通过 query_id 加载限流规则

    在获取到 query_id 之后,我们可基于 query_id 加载限流规则。云数据库 PostgreSQL 提供了一个函数供您使用,函数定义如下:
    tencentdb_sql_throttling.load_rule(queryid bigint);
    load_rule 函数的参数解释如下:
    说明:
    queryid:将 query 语句规范化后哈希得到的64位整数,可通过 pg_stat_statements 或 pg_stat_activity 查询得到;
    加载示例如下:
    postgres=> SELECT tencentdb_sql_throttling.load_rule(497939862935121343); -[ RECORD 1 ] load_rule | postgres=> SELECT * FROM tencentdb_sql_throttling.rules; -[ RECORD 1 ]-------+----------------------------------- queryid | 497939862935121343 work_node | 0 max_concurrency | 10 is_enabled | t query_string | SELECT id FROM t WHERE id = 594017 current_concurrency | 10 total_hit_count | 4760 reject_count | 4713 postgres=>

    加载所有限流规则

    当您需要加载所有限流规则时,云数据库 PostgreSQL 提供了一个函数供您使用,函数定义如下:
    tencentdb_sql_throttling.load_all_rules();
    加载示例如下:
    postgres=> select tencentdb_sql_throttling.load_all_rules();
    load_all_rules
    ----------------
    (1 row)

    持久化限流规则

    持久化是指在讲内存中的 SQL 限流规则存储到表格中,以便后续可以直接加载生效,不需要重新设置。

    通过 query_id 持久化限流规则

    在获取到 query_id 之后,我们可基于 query_id 持久化限流规则。云数据库 PostgreSQL 提供了一个函数供您使用,函数定义如下:
    tencentdb_sql_throttling.dump_rule(queryid bigint);
    dump_rule 函数的参数解释如下:
    说明:
    queryid:将 query 语句规范化后哈希得到的64位整数,可通过 pg_stat_statements 或 pg_stat_activity 查询得到;
    持久化示例:
    postgres=> select tencentdb_sql_throttling.dump_rule(440101247839410938);
    dump_rule
    -----------
    (1 row)

    持久化所有限流规则

    如您需要持久化所有的限流规则,云数据库 PostgreSQL 提供了一个函数供您使用,函数定义如下:
    tencentdb_sql_throttling.dump_all_rules();
    持久化所有 SQL 限流规则示例:
    postgres=> select tencentdb_sql_throttling.dump_all_rules();;
    dump_all_rules
    ----------------
    (1 row)
    如果已持久的规则被再次持久化会报错,请知悉,具体报错如下图所示。
    postgres=> SELECT tencentdb_sql_throttling.dump_all_rules(); NOTICE: duplicate key value violates unique constraint "persistent_rules_table_pkey" NOTICE: duplicate key value violates unique constraint "persistent_rules_table_pkey" dump_all_rules ---------------- (1 row)

    查看限流规则

    您可以使用 SQL 语句SELECT * FROM tencentdb_sql_throttling.rules;来查看当前内存中的限流规则,输出的字段解释如下:
    说明:
    queryid:限流 SQL 的 queryid,将 query 语句规范化后哈希得到的64位整数;
    work_node:规则生效的节点,0表示主实例和只读实例都生效,1表示只有主实例生效,2表示只有只读实例生效;
    max_concurrency:允许的最大并发数;
    is_enabled:限流规则是否生效,取值为 true 和 false;
    query_string:限流规则对应的 SQL 语句;
    current_concurrency:当前该 SQL 语句的并发量;
    total_hit_count:该限流规则被命中的次数,该值为建立 SQL 限流规则以来的累积值,只有删除规则之后重新加载才能清空;
    reject_count:该规则总共限流了多少次,该值为建立 SQL 限流规则以来的累积值,只有删除规则之后重新加载才能清空;
    查看内存中的限流规则示例:
    postgres=> SELECT * FROM tencentdb_sql_throttling.rules; -[ RECORD 1 ]-------+-------------------------------- queryid | 497939862935121343 work_node | 0 max_concurrency | 10 is_enabled | t query_string | SELECT id FROM t WHERE id = 553 current_concurrency | 0 total_hit_count | 91 reject_count | 81 postgres=>
    您可以使用 SQL 语句SELECT * FROM tencentdb_sql_throttling.persistent_rules_table;来查看当前存储中的限流规则,输出的字段解释如下:
    说明:
    queryid:限流 SQL 的 queryid,将 query 语句规范化后哈希得到的64位整数;
    work_node:规则生效的节点,0表示主实例和只读实例都生效,1表示只有主实例生效,2表示只有只读实例生效;
    max_concurrency:允许的最大并发数;
    is_enabled:限流规则是否生效,取值为 true 和 false;
    query_string:限流规则对应的 SQL 语句。
    查看持久化到表格中的规则示例:
    postgres=> SELECT * FROM tencentdb_sql_throttling.persistent_rules_table; -[ RECORD 1 ]---+----------------------------------- queryid | 497939862935121343 work_node | 0 max_concurrency | 10 is_enabled | t query_string | SELECT id FROM t WHERE id = 594017

    修改限流规则

    云数据库 PostgreSQL 提供了函数 change_rule_status 来修改限流规则,函数定义如下:
    tencentdb_sql_throttling.change_rule_status(
    queryid bigint,
    is_enabled boolean,
    max_concurrency int
    );
    函数参数解释如下:
    说明:
    queryid:限流 SQL 的 queryid,将 query 语句规范化后哈希得到的64位整数;
    is_enabled:限流规则是否生效,取值为 true 和 false;
    max_concurrency:允许的最大并发数,默认值为-1,代表不修改。
    修改示例:
    postgres=> select tencentdb_sql_throttling.change_rule_status(440101247839410938,true,300);
    change_rule_status
    --------------------
    (1 row)
    当系统出现异常,您可以调用 change_rule_current_concurrency 函数来手动修改某个规则的当前并发数,保障规则继续运行,函数定义如下:
    tencentdb_sql_throttling.change_rule_current_concurrency(
    queryid bigint,
    new_currenct_concurrency int
    );
    change_rule_current_concurrency 参数说明如下:
    说明:
    queryid:限流 SQL 的 queryid,将 query 语句规范化后哈希得到的64位整数;
    new_currenct_concurrency:该规则新的并发数。
    调用示例如下:
    postgres=> SELECT tencentdb_sql_throttling.change_rule_current_concurrency(497939862935121343,20); -[ RECORD 1 ]-------------------+- change_rule_current_concurrency | postgres=> SELECT * FROM tencentdb_sql_throttling.rules; -[ RECORD 1 ]-------+-------------------------------- queryid | 497939862935121343 work_node | 0 max_concurrency | 10 is_enabled | t query_string | SELECT id FROM t WHERE id = 553 current_concurrency | 20 total_hit_count | 286028 reject_count | 283788 postgres=>
    修改规则生效状态且增加并发数,生效:
    postgres=> SELECT * FROM tencentdb_sql_throttling.rules; -[ RECORD 1 ]-------+-------------------------------- queryid | 497939862935121343 work_node | 0 max_concurrency | 10 is_enabled | t query_string | SELECT id FROM t WHERE id = 553 current_concurrency | 20 total_hit_count | 286028 reject_count | 283788 postgres=> SELECT tencentdb_sql_throttling.change_rule_status(497939862935121343,false,20); -[ RECORD 1 ]------+- change_rule_status | postgres=> SELECT * FROM tencentdb_sql_throttling.rules; -[ RECORD 1 ]-------+-------------------------------- queryid | 497939862935121343 work_node | 0 max_concurrency | 20 is_enabled | f query_string | SELECT id FROM t WHERE id = 553 current_concurrency | 20 total_hit_count | 358931 reject_count | 356691
    联系我们

    联系我们,为您的业务提供专属服务。

    技术支持

    如果你想寻求进一步的帮助,通过工单与我们进行联络。我们提供7x24的工单服务。

    7x24 电话支持