
# 添加SQL防御规则
用户可以在CloudTable StarRocks集群详情界面添加SQL防御规则，系统会对触发规则的SQL请求进行提示、拦截或阻断操作。
![](https://support.huaweicloud.com/usermanual-cloudtable/public_sys-resources/notice_3.0-zh-cn.png)
为StarRocks集群添加或者修改SQL防御规则时需结合业务场景进行规则是否开启以及对应规则阈值是否合理的评估，不合理的防御规则对相关SQL请求进行拦截或阻断后，可能会对上层业务造成影响。
#### 前提条件
- 已[创建StarRocks集群](https://support.huaweicloud.com/usermanual-cloudtable/cloudtable_01_0489.html)。
- 已[安装MySQL客户端](https://support.huaweicloud.com/usermanual-cloudtable/cloudtable_01_0494.html#cloudtable_01_0494__section531737153320)。
 
#### 添加SQL防御规则
1. 登录[表格存储服务控制台](https://console.huaweicloud.com/cloudtable)。
2. 进入"集群管理"页面，单击目标集群进入集群详情页面。
3. 在左侧导航栏选择"SQL防御"，进入SQL防御规则管理页面，可单击页面左上角的"规则说明"按钮查看当前集群支持的所有SQL防御规则介绍。
4. 单击规则列表页面左上角的"新建规则"，打开新建规则页面。
5. 配置相关参数后，单击"确定"添加规则。 
   ![](https://support.huaweicloud.com/usermanual-cloudtable/public_sys-resources/notice_3.0-zh-cn.png)
   - 单次最多支持添加10条规则。
   
   - 同一对象不支持多次配置相同规则ID和拦截动作。
   
   - 拦截阈值需大于提示阈值。
    
   表1添加规则 
   | 参数                                                                                                                                                                                                                                                                                             | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
   |:---|:---|
   | 规则名称                                                                                                                                                                                                                                                                                           | 自定义SQL防御规则名称，支持大小写英文字母、数字和下划线，但必须以字母开头，长度不超过64个字符。 规则名称仅用于标识，允许重名。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
   | 规则ID                                                                                                                                                                                                                                                                                           | 选择规则ID。 不同ID对应的防御规则含义信息可参考[表 SQL防御规则]。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
   | 生效对象                                                                                                                                                                                                                                                                                           | 当前仅支持用户。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
   | 对象名称                                                                                                                                                                                                                                                                                           | 防御规则绑定的用户名。绑定用户后，该规则将作用于该用户对应的SQL。 说明： 防御规则不支持绑定带IP地址的用户名。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
   | - 提示及阈值  - 拦截及阈值  - 熔断及阈值   | 单击按钮启用提示、拦截或熔断SQL防御规则，并配置对应的阈值参数。防御规则及阈值参数详细说明请参见[表2]。 SQL请求满足防御规则后，系统的处理操作有以下类型： - 提示：配置系统对SQL请求满足防御规则后，是否进行提示处理，可以通过SQL命令**show warnings;**查看提示信息。  - 拦截：配置系统对SQL请求满足防御规则后，是否进行拦截处理。  - 熔断：配置系统对SQL请求满足防御规则后，是否进行熔断处理。   说明： 对于规则类型为静态拦截、动态拦截的SQL防御规则，系统支持"提示"、"拦截"操作。对于规则类型为运行熔断的SQL防御规则，系统支持"熔断"操作。 |
   | 操作                                                                                                                                                                                                                                                                                             | 删除当前待添加的规则。如果当前仅有一条规则，则无法执行删除操作。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
      
   
   
6. 规则添加成功后，可以在"SQL防御"界面查看已添加的防御规则。防御规则动态生效，可能存在三分钟延迟。 
   如需对当前规则进行调整，可单击对应规则所在"操作"列的"修改"或删除，可修改规则相关参数或删除该规则，删除规则时需要进行二次确认。
   图1查看SQL防御规   
   ![](https://support.huaweicloud.com/usermanual-cloudtable/zh-cn_image_0000002536898510.png "点击放大")
   
   

7. 验证SQL防御规则是否生效。例如： 
   1. 给用户**admin** 设置了**static_0001**的防御规则，提示和拦截的阈值分别为1和2，该规则是检查SQL中count(distinct)出现的次数是否超过配置的阈值。
   
   2. 使用MySQL客户端连接StarRocks集群，具体操作请参见[使用MySQL客户端连接StarRocks普通集群](https://support.huaweicloud.com/usermanual-cloudtable/cloudtable_01_0494.html)。
   
   3. 执行**select** 命令，查询字段分别包含2、3个**count(distinct)** ，验证是否触发static_0001的提示和拦截动作。
      - 触发提示动作：
        ```
        select c_custkey, c_name, count(distinct c_address), count(distinct c_nationkey) from customer group by c_custkey, c_name, c_nationkey limit 5;
        ```
        执行完**select**命令后，再执行以下命令，查看是否生成提示信息：
        ```
        show warnings;
        ```
        图2查看提示信息   
        ![](https://support.huaweicloud.com/usermanual-cloudtable/zh-cn_image_0000002536848952.png "点击放大") 
      
      - 触发拦截动作：
        ```
        select c_custkey, c_name, count(distinct c_address), count(distinct c_nationkey), count(distinct c_phone) from customer group by c_custkey, c_name limit 5;
        ```
        命令执行后，SQL会被拦截。
        图3命令被拦截   
        ![](https://support.huaweicloud.com/usermanual-cloudtable/zh-cn_image_0000002567681063.png "点击放大") 
      
      
      ![](https://support.huaweicloud.com/usermanual-cloudtable/public_sys-resources/note_3.0-zh-cn.png)
      还可以使用**admin** 用户在MySQL客户端执行以下命令查看已生效的防御规则：
      ```
      show proc '/sql_defend_rule';
      ```
      图4查看已生效的防御规则   
      ![](https://support.huaweicloud.com/usermanual-cloudtable/zh-cn_image_0000002599076741.png "点击放大") 
   
   
   
   
 
#### SQL防御规则
 表2SQL防御规则 
| 规则ID         | 规则描述                                                                                           | 规则变量参数                                                                | 阈值取值范围           | SQL语句示例                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | 影响分析                                                                                     |
|:---|:---|:---|:---|:---|:---|
| static_0001  | SQL中count(distinct)出现次数超限。                                                                     | count(distinct)出现次数阈值。 建议配置值：10 | \[1-10000\]      | SELECT COUNT(DISTINCT deviceId), COUNT(DISTINCT collDeviceId) FROM table GROUP BY deviceName, collDeviceName, collCurrentVersion;                                                                                                                                                                                                                                                                                                                                                                                                            | select count(distinct)语法是一个计算密集型操作，尤其在处理高基数（即不同值很多）和高并发场景时，会成为性能瓶颈 ，有时还会存在数据倾斜，导致节点负载不均。 |
| static_0002  | SQL中是否使用了not in \<subquery\>语句。 但如果主查询或子查询的表为空表，则不会触发拦截操作。 | N/A                                                                   | N/A              | SELECT \* FROM Orders o WHERE Orders.Order_ID not in (Select Order_ID FROM HeldOrders h where h.order_id = o.order_id);                                                                                                                                                                                                                                                                                                                                            | not in子查询性能差，如果not in子句的列表值包含null值，会导致结果中不会返回任何数据。                                       |
| static_0003  | SQL中的join次数超限制。                                                                                | join次数阈值。 建议配置值：20                | \[1-10000\]      | N/A                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | join的表越多，扫描的文件、分区、数据量越多，会导致SQL内存占用过多，影响集群稳定性。                                            |
| static_0004  | SQL中的union all次数超限制。                                                                           | union all次数阈值。 建议配置值：20         | \[1-10000\]      | select \* from tables t1 union all select \* from tables t2 union all select \* from tables t3 union all select \* from tables t4 union all select \* from tables t5 union all select \* from tables t6 union all select \* from tables t7 union all select \* from tables t8 union all select \* from tables t9; | 大量union all可能产生超大结果集，占用大量资源。                                                             |
| static_0005  | 子查询嵌套层数超限制。                                                                                    | 子查询的嵌套层数。 建议配置值：20               | \[1-10000\]      | select \* from ( with temp1 as (select \* from tables) select \* from temp1);                                                                                                                                                                                                                                                                                                                                                                                                                                                               | SQL嵌套层数过多，多次生成临时数据，且SQL不易维护修改，建议优化SQL，避免多重嵌套查询，提升执行效率和SQL可维护性。                           |
| static_0006  | SQL语句字符串长度超限制。                                                                                 | SQL字符串长度，单位为KB。 建议配置值：10          | \[1-1048576\]    | N/A                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | SQL字符串过长，代表SQL有可能过于复杂，会带来内存和性能问题，且SQL不易维护。                                               |
| static_0007  | 多表关联时存在笛卡尔积。                                                                                   | N/A                                                                   | N/A              | select \* from A,B;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | 笛卡尔积会导致数据膨胀，任务运行时可能大量占用集群资源，影响其他任务的执行。                                                   |
| dynamic_0001 | 已扫描的tablet数超限制。                                                                                | 计划/已经扫描的tablet数量阈值。 建议配置值：100000  | \[1-10000000\]   | SELECT ss_ticket_number FROM store_sales WHERE ss_ticket_number=72291252 LIMIT 10;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | SQL扫描大量tablet时，可能占用大量集群资源，影响其他任务正常运行。                                                    |
| dynamic_0002 | 对单个表操作（select、delete、update、alter）涉及的分区数超限制。                                                   | 表操作所涉及的分区数量阈值。 建议配置值：10000       | \[1-10000000\]   | DELETE FROM table_name WHERE column_name = value                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | 扫描分区量过多可能对服务造成压力，导致服务慢SQL。                                                               |
| running_0001 | Select类型的SQL语句向客户端返回的结果行数超限制。                                                                  | 查询返回结果的行数阈值。 建议配置值：100000        | \[1-1000000000\] | select \* from table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | 一次性返回的查询结果过多会导致服务端临时内存开销过大，产生OOM异常，影响服务端稳定性，同时，一次性查询结果集过大也会导致查询效率低。                      |
| running_0002 | SQL的占用内存峰值超绝对值限制。                                                                              | SQL运行占用内存阈值，单位为MB。                                                    | \[1-1024000\]    | N/A                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | 大任务会长时间占用集群CPU和内存资源，影响其他任务执行，影响集群整体性能。                                                   |
| running_0003 | SQL已经运行的时长超限制。                                                                                 | SQL运行时长阈值，单位为秒。                                                       | \[1-259200\]     | N/A                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | 任务长时间运行将持续占用集群资源，影响集群资源利用率，并且可能产生大量中间数据，不符合预期的任务需要及时调整。                                  |
| running_0004 | SQL已经发生的数据扫描量超过阈值。                                                                             | SQL扫描数据量，单位为GB。                                                       | \[1-10000000\]   | N/A                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | 扫描过多的数据量会占用大量的集群计算资源和IO资源，影响其他任务的正常执行。                                                   |
   
