在團隊協作或自動化發布流程中,不一致的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參數不一致時觸發。 說明 支援的叢集版本如下:
|