在团队协作或自动化发布流程中,不一致的SQL规范和未经审核的变更操作可能引入数据错误、性能瓶颈甚至生产环境故障。polar_sql_inception插件通过提供一个集审核与执行于一体的自动化SQL审核引擎,解决了这一痛点。您可以通过自定义规则,在开发、测试及发布阶段自动检查SQL,强制执行编码标准,拦截高风险操作,从而保障数据库变更的质量与安全。
适用范围
支持的PolarDB PostgreSQL版的版本如下:
PostgreSQL 16(内核小版本2.0.16.9.9.0及以上)
PostgreSQL 15(内核小版本2.0.15.15.7.0及以上)
PostgreSQL 14(内核小版本2.0.14.19.38.0及以上)
快速入门
本节将通过一个简单的示例,快速展示polar_sql_inception的核心功能:在3分钟内拦截一条不符合规范的建表语句。
安装
polar_sql_inception插件:在您的数据库中执行以下命令。CREATE EXTENSION polar_sql_inception;设置一条审核规则,强制所有新建的表都必须包含主键。执行
SET命令,在当前会话中开启该规则。SET polar_sql_inception.table_rule_check_primary_key = ON;调用审核函数,检查一条不含主键的建表语句。 执行以下查询。将
execute参数设置为FALSE,表示只审核,不执行。SELECT * FROM polar_sql_inception( sql_statements := 'CREATE TABLE users (id INT, name TEXT);', execute := FALSE );预期结果:审核不通过,并返回明确的错误信息。
error_level字段为error,error_message字段清晰地指出了set a primary key的违规原因。这表明该插件已成功拦截了不合规的SQL。sql_id | sql_statement | stage | error_level | error_message | affected_rows --------+----------------------------------------+---------+-------------+-------------------+--------------- 1 | CREATE TABLE users (id INT, name TEXT) | checked | warning | set a primary key+| 0 | | | | |
工作原理
配置模式
您可以根据需求选择不同的方式来配置审核规则。
通过
SET命令在当前数据库中设置参数。此方式灵活便捷,无需重启集群,配置仅对应用范围生效。会话级配置:
-- 仅在当前会话生效 SET polar_sql_inception.dml_rule_check_dml_where = ON;用户级别:
-- 仅在当前用户生效 ALTER username SET polar_sql_inception.dml_rule_check_dml_where = ON;DATABASE级别:
-- 仅在当前数据库生效 ALTER databasename SET polar_sql_inception.dml_rule_check_dml_where = ON;
执行模型
当您调用polar_sql_inception函数并传入多条SQL语句时,它遵循以下处理流程:
串行处理:插件按顺序逐条处理SQL语句,流程为:审核语句A -> (若通过且
execute为TRUE)执行语句A -> 审核语句B -> (若通过且execute为TRUE)执行语句B -> ...。错误中断:在审核或执行过程中,一旦某条语句触发了
error级别的错误,或者触发了warning级别错误且未设置忽略警告(ignore_warning_when_executing = OFF),后续所有语句的执行流程都将被中断。但插件会继续完成对剩余所有语句的审核,并返回完整的审核结果。
执行SQL审核与变更
本节介绍如何通过polar_sql_inception函数执行SQL审核,并根据需要执行变更。
函数定义
polar_sql_inception(
sql_statements TEXT,
execute BOOLEAN DEFAULT FALSE,
schema TEXT DEFAULT NULL
)参数说明
参数 | 说明 | 适用范围 |
| 需要审核的一条或多条SQL语句。 | 同功能适用范围。 |
| 是否在审核通过后执行SQL语句。默认为 |
|
| 指定SQL语句执行时依赖的默认Schema。 说明 此参数效果等同于在本次审核执行的内部临时执行 |
|
操作示例
场景一:仅审核多条SQL语句
检查两句CREATE TABLE语句是否符合必须有主键的规则,但不实际创建表。
-- 开启“表必须有主键”的规则
SET polar_sql_inception.table_rule_check_primary_key = ON;
-- 调用函数进行审核
SELECT * FROM polar_sql_inception(
sql_statements := $$
-- 错误示例:没有主键
CREATE TABLE t1 (id INT);
-- 正确示例:有主键
CREATE TABLE t2 (id INT PRIMARY KEY);
$$,
execute := FALSE
);返回结果:第一条SQL因违反规则而报错,第二条SQL审核通过。
sql_id | sql_statement | stage | error_level | error_message | affected_rows
--------+----------------------------------------------+---------+-------------+---------------------+---------------
1 | +| checked | warning | set a primary key +| 0
| -- 错误示例:没有主键 +| | | |
| CREATE TABLE t1 (id INT) | | | |
2 | +| checked | success | no violations found | 0
| +| | | |
| -- 正确示例:有主键 +| | | |
| CREATE TABLE t2 (id INT PRIMARY KEY) | | | | 场景二:审核并通过后执行
审核一条UPDATE语句是否符合DML必须带WHERE子句的规则,如果符合则执行它。
-- 准备测试数据
CREATE TABLE products (id INT, stock INT);
INSERT INTO products VALUES (1, 100);
-- 开启“DML必须带WHERE”的规则
SET polar_sql_inception.dml_rule_check_dml_where = ON;
-- 调用函数,审核并执行
SELECT * FROM polar_sql_inception(
sql_statements := 'UPDATE products SET stock = 99 WHERE id = 1;',
execute := TRUE
);返回结果:SQL语句审核通过并成功执行(stage: executed且error_level: success),affected_rows字段显示有1行数据被更新。
sql_id | sql_statement | stage | error_level | error_message | affected_rows
--------+---------------------------------------------+----------+-------------+---------------------+---------------
1 | UPDATE products SET stock = 99 WHERE id = 1 | executed | success | no violations found | 1结果集详解
polar_sql_inception函数返回一个结果集,每一行对应您输入的一条SQL语句的审核与执行结果。
字段 | 说明 |
| SQL语句的序号,从1开始。 |
| 当前处理的SQL语句原文。 |
| 表示当前SQL语句的处理阶段:
|
| 表示结果的严重级别:
|
| 详细的审核意见或错误信息。如果有多条违规,信息会用换行符分隔。审核通过时,返回 |
| 受影响的行数。
|
配置模板
为帮助您批量设置规则参数,PolarDB提供以下设置模板。您可以根据实际业务需求,设置对应的规则。
-- 运行配置
SET polar_sql_inception.get_real_affected_rows = OFF;
SET polar_sql_inception.enable_utility_parse_analysis = ON;
SET polar_sql_inception.ignore_warning_when_executing = OFF;
-- 表相关规则
SET polar_sql_inception.table_rule_enable_partition = ON;
SET polar_sql_inception.table_rule_check_primary_key = OFF;
SET polar_sql_inception.table_rule_enable_foreign_key = ON;
SET polar_sql_inception.table_rule_merge_alter_table = OFF;
SET polar_sql_inception.table_rule_must_have_columns ='column1,column2,column3';
-- 列相关规则
SET polar_sql_inception.column_rule_max_char_length = 0;
SET polar_sql_inception.column_rule_enable_text_type = ON;
SET polar_sql_inception.column_rule_enable_json_type = ON;
SET polar_sql_inception.column_rule_check_not_null = OFF;
SET polar_sql_inception.column_rule_enable_timestamp_type = ON;
SET polar_sql_inception.column_rule_check_timestamp_default = OFF;
SET polar_sql_inception.column_rule_check_timestamp_count = OFF;
SET polar_sql_inception.column_rule_check_default_value = OFF;
-- 索引相关规则
SET polar_sql_inception.index_rule_enable_null_index_name = ON;
SET polar_sql_inception.index_rule_max_key_parts = 0;
SET polar_sql_inception.index_rule_max_primary_key_parts = 0;
SET polar_sql_inception.index_rule_check_pk_columns_only_int = OFF;
SET polar_sql_inception.index_rule_max_keys = 0;
-- 命名相关规则
SET polar_sql_inception.naming_rule_check_char = OFF;
SET polar_sql_inception.naming_rule_check_keyword = OFF;
-- DML 相关规则
SET polar_sql_inception.dml_rule_check_insert_field = OFF;
SET polar_sql_inception.dml_rule_check_dml_where = OFF;
SET polar_sql_inception.dml_rule_enable_select_star = ON;
SET polar_sql_inception.dml_rule_enable_orderby_rand = ON;
SET polar_sql_inception.dml_rule_max_update_rows = 0;
SET polar_sql_inception.dml_rule_max_insert_rows = 0;
SET polar_sql_inception.dml_rule_max_delete_rows = 0;
-- 其他规则
SET polar_sql_inception.check_schema_consistency = OFF;配置项参考
运行配置
参数 | 默认值 | 说明 |
|
| 在 |
|
| 在 说明 支持的集群版本如下:
|
|
| 在 说明 支持的集群版本如下:
|
规则配置
表相关规则
规则名称 | 参数 | 默认值 | 触发场景 |
表必须包含主键 |
|
|
|
禁止创建分区表 |
|
|
|
禁止使用外键 |
|
|
|
表必须包含指定列 |
|
|
|
合并多个ALTER TABLE |
|
|
|
创建的表不存在 | 默认规则 | - |
|
只能有一个主键 | 默认规则 | - |
|
LIKE的表不存在 | 默认规则 | - |
|
用户必须有权限 | 默认规则 | - |
|
列相关规则
规则名称 | 参数 | 默认值 | 触发场景 |
CHAR长度限制 |
|
|
|
禁止使用TEXT类型 |
|
|
|
禁止使用JSON类型 |
|
|
|
列必须有NOT NULL约束 |
|
|
|
禁止使用TIMESTAMP类型 |
|
|
|
TIMESTAMP列必须有默认值 |
|
|
|
只能有一个 |
|
|
|
每个列都需要定义默认值,除了 |
|
|
|
不能有重复的列名 | 默认规则 | - |
|
索引相关规则
规则名称 | 参数 | 默认值 | 触发场景 |
索引必须有名称 |
|
|
|
普通索引的列数限制 |
|
|
|
主键索引的列数限制 |
|
|
|
主键列必须为整数类型 |
|
|
|
单表索引总数限制 |
|
|
|
建索引时,指定的列必须存在。 | 默认规则 | - |
|
建索引时,指定的列必须存在。 | 默认规则 | - |
|
索引名不能重复 | 默认规则 | - |
|
用户必须有权限 | 默认规则 | - |
|
命名相关规则
规则名称 | 参数 | 默认值 | 触发场景 |
检查名称字符集 |
|
|
|
检查是否为关键字 |
|
|
|
DML 相关规则
规则名称 | 参数 | 默认值 | 触发场景 |
必须指定插入列表 |
|
|
|
DML必须有WHERE条件 |
|
|
|
禁止使用 |
|
|
|
禁止使用 |
|
|
|
限制UPDATE行数 |
|
|
|
限制INSERT行数 |
|
|
|
限制DELETE行数 |
|
|
|
表、列必须存在 | 默认规则 | - | DML语句中表、列并不存在。 |
用户必须有权限 | 默认规则 | - | DML语句用户对表没有权限。 |
其他规则
规则名称 | 参数 | 默认值 | 触发场景 |
检查Schema一致性 |
|
| 当DML和DDL语句显式指定的Schema与polar_sql_inception函数指定的Schema参数不一致时触发。 说明 支持的集群版本如下:
|