
StarRocks ADD SQLBLACKLIST 语句完全指南正则黑名单拦截高危 SQL【免费下载链接】starrocksThe worlds fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocksSQL 黑名单SQL Blacklist是 StarRocks 提供的一项集群级 SQL 防护能力管理员通过ADD SQLBLACKLIST向黑名单中添加正则表达式匹配该表达式的 SQL 将不被执行并返回错误从而防止特定 SQL 触发集群崩溃、元数据异常或瞬时高并发打爆资源。本文以ADD SQLBLACKLIST语句为核心完整讲解其语法、正则转义规则、7 个可复制的实战示例并结合 FE 端源码SqlBlackList.java、StmtExecutor.java揭示其底层拦截原理、权限要求与适用边界帮助你快速构建一套可靠的 SQL 风控体系。关联文档ADD SQLBLACKLIST配套的管理员完整指南见 Blacklist Management。功能定位与适用场景ADD SQLBLACKLIST用于向 SQL 黑名单添加一条正则表达式用来指定某类禁止执行的 SQL 模式。当 SQL Blacklist 特性开启后StarRocks 会把所有待执行的 SQL 语句与黑名单中的正则逐一比对只要匹配其中任意一条正则该 SQL 就不会被执行并直接向客户端返回错误。这一机制主要解决两类运维痛点规避崩溃与异常行为某些模式复杂、语义特殊的 SQL例如多段EXCEPT组合、极端LIMIT分页可能触发 FE 解析或规划路径上的隐藏缺陷在版本修复前先将其加入黑名单是最快的止血手段抑制瞬时高并发形如select count(*) from .的全表扫描类语句在流量突增时可能拖垮集群通过正则将其整体禁掉可保护核心业务查询的稳定性。黑名单的适用范围有明确的版本边界请务必核对仅对SELECT语句生效从v3.1 起额外支持INSERT语句从v3.4 起额外支持CTASCREATE TABLE AS SELECT语句。这一范围在 FE 执行入口中也有直接印证见下文底层实现原理一节。权限要求ADD SQLBLACKLIST属于集群级管理操作需要SYSTEM 级的BLACKLIST权限拥有ADMIN_PRIV的管理员默认具备该权限普通用户可通过 GRANT 授予BLACKLIST系统权限后执行。在 FE 源码 AuthorizerStmtVisitor.java 中visitAddSqlBlackListStatement会调用Authorizer.checkSystemAction(context, PrivilegeType.BLACKLIST)进行鉴权未授权用户执行会直接抛出权限不足异常。语法ADD SQLBLACKLIST sql_reg_exprADD SQLBLACKLIST命令关键字大小写不敏感sql_reg_expr必须用双引号包裹的正则表达式字符串用于匹配一类 SQL 模式。语法在 ANTLR 文法中有明确定义见 StarRocks.g4ADD SQLBLACKLIST string解析得到的字符串会被封装进AddSqlBlackListStmtAST 节点见 AddSqlBlackListStmt.java随后在StmtExecutor.handleAddSqlBlackListStmt()中被消费执行。参数与转义规则sql_reg_expr用于指定某一类 SQL 模式的正则表达式。核心难点在于转义。SQL 语句自身包含(,),*,.等常用字符而这些字符在正则表达式中都有特殊语义因此需要区分SQL 语义字符和正则语义字符字符在 SQL 中的角色正则中的语义是否需要转义()括号、函数调用分组不需要StarRocks 可自动识别 SQL 语句中的括号*乘法量词零次或多次需要写作\\*-减号字符范围需要写作\\-/除法字面量建议转义写作\\/.小数点任意单字符需要写作\\.加法量词一次或多次需要写作\\规则概括由于(和)在 SQL 中使用过于频繁StarRocks 允许直接书写而无需转义其余 SQL 特殊字符如*、、-则需要在其前加转义符\作为前缀。值得注意的实现细节ADD SQLBLACKLIST传入的字符串在入库前会经过一次归一化处理。在 SqlBlackList.java 的addBlackSql中字符串会先被trim().toLowerCase()转为小写并把\r、\n以及连续空白统一压缩为单个空格随后才调用Pattern.compile(sql)编译成正则若正则本身非法PatternSyntaxException会抛出SemanticException(Sql syntax error: %s)。这意味着黑名单匹配是大小写不敏感的SQL 被转小写换行、多余空格不影响匹配正则必须在编译期合法否则 ADD 操作失败。完整示例可直接复制运行以下 7 个示例覆盖了从简单到复杂的全部典型用法。示例 1禁止count(*)mysql ADD SQLBLACKLIST select count(\\*) from .;这里\\*转义了乘法号*.匹配任意表名。此后任何select count(*) from 任意表形式的查询都会被拒绝。示例 2禁止count(distinct ...)mysql ADD SQLBLACKLIST select count(distinct .) from .;禁止对任意表执行select count(distinct 任意列) from 任意表的精确去重计数。示例 3禁止order by limit x, y1 ≤ x ≤ 75 ≤ y ≤ 7mysql ADD SQLBLACKLIST select id_int from test_all_type_select1 order by id_int limit [1-7], [5-7];正则中的[1-7]、[5-7]分别匹配 1 到 7、5 到 7 的任意整数从而拦截固定范围内的分页偏移。注意跨行书写是允许的——入库时换行会被压缩成空格与示例 3 单行写法select id_int from test_all_type_select1 order by id_int limit [1-7], [5-7]效果完全等价该单行版本同样出现在 Blacklist.md 中。示例 4禁止一段复杂的多段 EXCEPT 查询演示*与-的转义mysql ADD SQLBLACKLIST select id_int \\* 4, id_tinyint, id_varchar from test_all_type_nullable except select id_int, id_tinyint, id_varchar from test_basic except select (id_int \\* 9 \\- 8) \\/ 2, id_tinyint, id_varchar from test_all_type_nullable2 except select id_int, id_tinyint, id_varchar from test_basic_nullable;本例是转义规则的综合示范SQL 中的乘法*写成\\*减法-写成\\-除法/写成\\/而括号()直接书写即可。示例 5禁止所有 INSERT INTO 语句v3.1ADD SQLBLACKLIST (?i)^insert\\sinto\\s.*;(?i)内联标志表示整个正则忽略大小写双保险因为入库前本就会转小写^insert锚定语句开头\\s匹配一个或多个空白SQL 中的空格、制表符等归一化后都是空格.*匹配任意剩余内容。示例 6禁止所有 INSERT INTO ... VALUES 语句ADD SQLBLACKLIST (?i)^insert\\sinto\\s.*values\\s*\\(;在示例 5 基础上用values\\s*\\(精确锚定插入字面值形态\\s*匹配零或多个空白\\(转义后的括号匹配 VALUES 后的左括号。注意此规则不会误伤INSERT INTO ... SELECT形态的语句。示例 7禁止除_statistics_.column_statistics之外的所有 INSERT INTO ... VALUESADD SQLBLACKLIST (?i)^insert\\sinto\\s(?!column_statistics\\b).*values\\s*\\(;使用负向前瞻断言(?!column_statistics\\b)当 INSERT 目标不是系统视图column_statistics\\b为单词边界避免误匹配column_statistics_xxx之类的表名时整条正则才成立。这保证了统计数据回写CBO 分析写入_statistics_.column_statistics不受影响是生产环境中开白名单窗口的典型写法。说明示例 5/6/7 使用(?i)内联忽略大小写标志而示例 1/2/3/4 依赖入库时的自动小写化即可命中两种风格均可正常使用。底层实现原理从语法到拦截语法解析与鉴权阶段ADD SQLBLACKLIST语句的完整链路为词法/语法解析StarRocks.g4文法识别ADD SQLBLACKLIST string见 StarRocks.g4生成AddSqlBlackListStmtAST 节点鉴权AuthorizerStmtVisitor.visitAddSqlBlackListStatement校验 SYSTEM 级BLACKLIST权限见 AuthorizerStmtVisitor.java执行StmtExecutor.handleAddSqlBlackListStmt()调用SqlBlackList.addBlackSql()见 StmtExecutor.java完成正则归一化、编译与入表。匹配与拦截阶段真正拦截发生在所有查询的执行入口 StmtExecutor.java关键代码如下节选逻辑if ((parsedStmt instanceof QueryStatement || parsedStmt instanceof InsertStmt || parsedStmt instanceof CreateTableAsSelectStmt) Config.enable_sql_blacklist !parsedStmt.isExplain() !isProxy) { OriginStatement origStmt parsedStmt.getOrigStmt(); if (context.isStatisticsConnection() || context.isStatisticsJob()) { // 统计信息连接/任务直接信任跳过黑名单检查 } else if (origStmt ! null) { String originSql origStmt.originStmt.trim() .toLowerCase().replaceAll( , ); GlobalStateMgr.getCurrentState().getSqlBlackList().verifying(originSql); // 若开启 SQL Digest 黑名单还会对语句摘要做二次校验 } }从这段代码可以提炼出几个关键事实只有QueryStatementSELECT、InsertStmtINSERTv3.1和CreateTableAsSelectStmtCTASv3.4三类语句参与匹配与官方文档声明一致EXPLAIN语句!parsedStmt.isExplain()不参与黑名单校验便于管理员在禁止前先分析计划从 Follower FE 转发到 Leader 的代理 SQLisProxy不会重复校验因为每个 FE 维护自己的黑名单副本统计信息采集的连接与任务isStatisticsConnection/isStatisticsJob被显式跳过——这是示例 7 中column_statistics放行逻辑之外的第二道保险待校验 SQL 同样经过toLowerCase()与空白压缩与入库时的归一化保持一致确保正则能稳定命中。verifying方法的匹配实现在 SqlBlackList.java对每条规则用Pattern.matcher(...).find()做子串查找非全串匹配命中后递增计数器COUNTER_SQL_BLOCK_HIT_COUNT并抛出ERR_SQL_IN_BLACKLIST_ERROR最终客户端会看到形如下面的报错ERROR 1064 (HY000): Access denied; sql select count (*) from test_all_type_select_2556 is in blacklist存储与持久化黑名单在 FE 内以ConcurrentHashMapString, BlackListSql维护key 为正则字符串value 为(Pattern, id)二元组id 由AtomicLong自增分配每次增删后都会重建一份按 id 排序的不可变快照ruleSnapshot供无锁并发读取见 SqlBlackList.java。持久化方面增删操作会通过EditLog写 WAL 日志并可在 FE image 中以SRMetaBlockID.BLACKLIST_MGR元数据块落盘save()/load()方法保证重启后黑名单不丢失、主从 FE 间保持一致。配套运维命令查看与删除ADD SQLBLACKLIST通常与另外两条命令配合形成完整生命周期管理详见 Blacklist Management查看黑名单SHOW SQLBLACKLIST;输出格式为Index | Forbidden SQL其中Forbidden SQL列展示的是对所有 SQL 语义字符做转义处理后的正则。典型输出mysql show sqlblacklist; ----------------------------------------------------- | Index | Forbidden SQL | ----------------------------------------------------- | 1 | select count\(\*\) from . | | 2 | select id_int \* 4, id_tinyint, id_varchar | | | from test_all_type_nullable except ... | | 3 | select id_int from test_all_type_select1 | | | order by id_int limit [1-7], [5-7] | | 4 | select count\(distinct .\) from . | -----------------------------------------------------删除黑名单DELETE SQLBLACKLIST sql_index_number;sql_index_number为 SQL 编号列表用英文逗号,分隔可一次删除多条。例如删除上表中的第 3、4 条delete sqlblacklist 3, 4;启用开关SQL Blacklist 默认关闭需要管理员开启该开关即 Config.java 中标注ConfField(mutable true)的enable_sql_blacklist配置项默认false支持运行时动态修改admin set frontend config (enable_sql_blacklist true);注意仅开启开关但黑名单为空时所有 SQL 正常放行每个 FE 节点各自持有黑名单副本但通过 EditLog 持久化保持一致开启后对集群全局生效建议先在测试集群验证正则的命中范围再应用到生产避免误伤正常业务查询例如示例 1 会禁掉所有select count(*)请确认业务无此依赖。小结ADD SQLBLACKLIST是 StarRocks 内置 SQL 风控的第一道闸门一条正则即可完成对一类高危 SQL 的全局拦截。掌握三条要点即可熟练运用转义先行()免转义*-/.等 SQL 特殊字符需加\前缀并且匹配大小写不敏感、空白自动归一边界清晰SELECT 全版本生效INSERT 需 v3.1CTAS 需 v3.4且EXPLAIN与统计信息相关语句不参与拦截配套管理SHOW SQLBLACKLIST查看、DELETE SQLBLACKLIST删除、admin set frontend config (enable_sql_blacklist true)开启开关三者与ADD命令构成完整的黑名单生命周期。如需了解权限授予细节可参考 GRANT需要系统了解黑名单整体管理时请阅读 Blacklist Management。【免费下载链接】starrocksThe worlds fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考