查询拦截

本文介绍云数据库 SelectDB 版提供的SQL查询拦截相关功能,帮助您进行SQL管理。

概述

在生产环境的部分场景下,需要对可执行的SQL语句做出限制,例如屏蔽删除或某些已知的高风险查询语句。为满足此类场景需求,SelectDB提供了SQL查询拦截功能。当您在SelectDB上执行的SQL命中了拦截规则,SelectDB将不允许该SQL执行,并返回错误信息。

创建拦截规则

创建SQL拦截规则可用于限制任何SQL语句(包括DDL和DML语句)。支持按数据库账号配置SQL黑名单。

SQL拦截规则可通过以下方式进行配置:

  • 通过正则匹配的方式拒绝指定的SQL。

  • 通过设置partition_num、tablet_num、cardinality,检查一个查询是否达到其中一个限制。这几个查询配置项可以同时设置,一旦查询触发其中任何一个限制,就会触发拦截。

语法

CREATE SQL_BLOCK_RULE rule_name 
[PROPERTIES ("key"="value", ...)];

参数说明

参数名称

必填

参数说明

rule_name

规则名称。

PROPERTIES

具体属性,详细说明请参见下文。

常用的PROPERTIES参数如下。

参数名称

必填

参数说明

sql

匹配规则(基于正则匹配,特殊字符需要转译。如select *使用select \\*),默认值为NULL,最后无需带分号。

sqlHash

SQL Hash值,用于完全匹配。默认值为NULL。fe.audit.log将会记录这个值,这个参数和sql只能二选一。

partition_num

一个扫描节点会扫描的最大Partition数量。默认值为0L,不限制。

tablet_num

一个扫描节点会扫描的最大Tablet数量。默认值为0L,不限制。

cardinality

一个扫描节点粗略的扫描行数。默认值为0L,不限制

global

是否全局(对所有用户)生效。默认值为false

enable

是否开启阻止规则。默认值为true

使用示例

  • 创建一个名称为test_rule的阻止规则,示例如下。

    CREATE SQL_BLOCK_RULE test_rule 
    PROPERTIES(
      "sql"="select \\* from order_analysis",
      "global"="false",
      "enable"="true",
      "sqlHash"=""
    )

    当执行SQL名字上述拦截规则时,会返回如下错误提醒。

    SELECT * FROM order_analysis;
    ERROR 1064 (HY000): errCode = 2, detailMessage = sql match regex sql block rule: order_analysis_rule
  • 创建test_rule2,将最大扫描的分区数量限制在30个,最大扫描基数限制在100亿行,示例如下。

    CREATE SQL_BLOCK_RULE test_rule2 
    PROPERTIES
    (
       "partition_num" = "30",
       "cardinality" = "10000000000",
       "global" = "false",
       "enable" = "true"
    );
    Query OK, 0 rows affected (0.01 sec)
  • 创建包含特殊字符的SQL BLOCK RULE,示例如下。正则表达式中()符号是特殊符号,所以需要转义。

    CREATE SQL_BLOCK_RULE test_rule3
    PROPERTIES
    ( 
        "sql" = "select count\\(1\\) from test_db.test_table"
    );
    
    CREATE SQL_BLOCK_RULE test_rule4
    PROPERTIES
    ( 
        "sql" = "select \\* from db1.tbl1"
    );

查看拦截规则

查看已配置的SQL阻止规则,不指定规则名则为查看所有规则。

语法

SHOW SQL_BLOCK_RULE [FOR RULE_NAME];

参数说明

参数名称

必填

参数说明

rule_name

规则名称。

使用示例

  • 查看所有规则,示例如下。

    SHOW SQL_BLOCK_RULE;
    +------------+------------------------+---------+--------------+-----------+-------------+--------+--------+
    | Name       | Sql                    | SqlHash | PartitionNum | TabletNum | Cardinality | Global | Enable |
    +------------+------------------------+---------+--------------+-----------+-------------+--------+--------+
    | test_rule  | select * from order_analysis | NULL    | 0            | 0         | 0           | true   | true   |
    | test_rule2 | NULL                   | NULL    | 30           | 0         | 10000000000 | false  | true   |
    +------------+------------------------+---------+--------------+-----------+-------------+--------+--------+
    2 rows in set (0.01 sec)
  • 指定规则名查询,示例如下。

    SHOW SQL_BLOCK_RULE FOR test_rule2;
    +------------+------+---------+--------------+-----------+-------------+--------+--------+
    | Name       | Sql  | SqlHash | PartitionNum | TabletNum | Cardinality | Global | Enable |
    +------------+------+---------+--------------+-----------+-------------+--------+--------+
    | test_rule2 | NULL | NULL    | 30           | 0         | 10000000000 | false  | true   |
    +------------+------+---------+--------------+-----------+-------------+--------+--------+
    1 row in set (0.00 sec)

修改拦截规则

修改SQL拦截规则,允许对规则的每一项属性进行修改。

语法

ALTER SQL_BLOCK_RULE rule_name 
[PROPERTIES ("key"="value", ...)];

参数说明

参数名称

必填

参数说明

rule_name

规则名称。

PROPERTIES

具体属性,详细说明请参见上文创建拦截规则

使用示例

  1. 根据SQL属性进行修改,示例如下。

ALTER SQL_BLOCK_RULE test_rule PROPERTIES("sql"="select \\* from test_table","enable"="true")
  1. 如果一个rule设置了partition_num,那么sql或者sqlHash将无法被修改,示例如下。

ALTER SQL_BLOCK_RULE test_rule2 PROPERTIES("partition_num" = "10","tablet_num"="300","enable"="true")

删除拦截规则

删除SQL阻止规则,支持同时删除多条规则。

语法

DROP SQL_BLOCK_RULE test_rule1,...

参数说明

参数名称

必填

参数说明

test_rule1

规则名称。支持多规则,以“,”隔开。

使用示例

删除test_rule1、test_rule2阻止规则,示例如下。

DROP SQL_BLOCK_RULE test_rule1,test_rule2;
Query OK, 0 rows affected (0.00 sec)

拦截规则绑定用户

如果需要为指定数据库账号配置拦截规则,则需要设置规则的属性global为false,然后参考如下语句进行绑定,多个规则使用,分隔。

SET PROPERTY [FOR 'jack'] 'sql_block_rules' = 'test_rule1,test_rule2';