這篇文章主要講解了“如何理解SQL審核利器goinception”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“如何理解SQL審核利器goinception”吧!
一、goinception簡介
使用過inception的人對SQL審核這塊獲取都比較熟悉,作為DBA,審核SQL是日常工作中的很重要的一塊內容,審核好SQL對于后期項目以及數據庫維護上起著至關重要的作用,好比一座大廈沒有堅實的地基支撐,也就無法長期屹立不倒。
goInception是一個集審核、執行、備份及生成回滾語句于一身的MySQL運維工具, 通過對執行SQL的語法解析,返回基于自定義規則的審核結果,并提供執行和備份及生成回滾語句的功能。
從架構上來說,goinception簡直跟inception一模一樣,SQL提交到goinception,goinception連接到線上MySQL進行審核。執行的時候也是連接到線上MySQL進行執行,goinception提供了備份、回滾的功能,意思就是能夠監聽執行期間的binlog,基于binlog生成反向的回滾SQL。
二、安裝測試
廢話不多說,咱們直接安裝測試一把。
下載、安裝
官方提供了二進制包,簡直安裝部署的一大福利。
下載地址:https://github.com/hanchuanchuan/goInception/releases
下載好對應版本的goinception,直接解壓即可,解壓完成以后在config/config.toml.default有一個默認的配置文件,大概意思也寫得比較清楚了,那我修改的部分已經寫在下面的配置文件中了,其他部分我都沒有修改
# 日志文件 [log.file] filename = "/opt/goinception/logs/goinception.log" max-days = 7 max-backups = 7 [inc] backup_host = "xxxx" backup_port = 3306 backup_user = "goinception" backup_password = "goinception" sql_safe_updates = 1 lang = "zh-CN" [osc] osc_min_table_size = 1024 [ghost] ghost_on = true ghost_chunk_size = 10000 ghost_dml_batch_size = 100
那么,我們啟動goinception
./goInception -config=config/config.toml &
啟動以后,我們可以看到端口4000已經啟動監聽了
[root@VM_0_9_centos ~]# netstat -lntp|grep 4000 tcp6 0 0 :::4000 :::* LISTEN 31404/./goInception
測試
goinception可以沿用inception的調用方法,示例如下:
/*--user=root;--password=root;--host=127.0.0.1;--check=1;--port=3306;*/ inception_magic_start; use test; create table t1(id int primary key); inception_magic_commit;
那么我們構建一個python腳本來進行測試:
#!/usr/bin/env python3 # -*- coding:utf-8 -*- import pymysql import prettytable as pt tb = pt.PrettyTable() sql = '''/*--user=xucl;--password=xuclxucl123;--host=127.0.0.1;--check=1;--port=3308;*/ inception_magic_start; use sbtest; create table t1(id int primary key,c1 int, c2 int); insert into t1(id,c1,c2) values(1,1,1); inception_magic_commit;''' conn = pymysql.connect(host='127.0.0.1', user='', passwd='', db='', port=4000, charset="utf8mb4") cur = conn.cursor() ret = cur.execute(sql) result = cur.fetchall() cur.close() conn.close() tb.field_names = [i[0] for i in cur.description] for row in result: tb.add_row(row) print(tb)
執行后輸出如下:
[root@VM_0_9_centos goinception]# python3 test.py +----------+---------+-------------+-----------------+-----------------+----------------------------------------------------+---------------+--------------+---------------+--------------+---------+-------------+ | ------+---------------+--------------+---------------+--------------+---------+-------------+|order_id|stage|error_ | ------+---------------+--------------+---------------+--------------+---------+-------------+|order_id|stage|error_ | ------+---------------+--------------+---------------+--------------+---------+-------------+|order_id|stage|error_level | ------+---------------+--------------+---------------+--------------+---------+-------------+|order_id|stage|error__status | ------+---------------+--------------+---------------+--------------+---------+-------------+|order_id|stage|error_message | sql | affected_rows | sequence | backup_dbname | execute_time | sqlsha1 | backup_time | +----------+---------+-------------+-----------------+-----------------+----------------------------------------------------+---------------+--------------+---------------+--------------+---------+-------------+ | 1 | CHECKED | 0 | Audit Completed | None | use sbtest | 0 | 0_0_00000000 | None | 0 | None | 0 | | 2 | CHECKED | 2 | Audit Completed | 表 't1' 已存在. | create table t1(id int primary key,c1 int, c2 int) | 0 | 0_0_00000001 | None | 0 | None | 0 | | 3 | CHECKED | 0 | Audit Completed | None | insert into t1(id,c1,c2) values(1,1,1) | 1 | 0_0_00000002 | None | 0 | None | 0 | +----------+---------+-------------+-----------------+-----------------+----------------------------------------------------+---------------+--------------+---------------+--------------+---------+-------------+
可以看到審核結果還是非常清晰的
那如果需要執行的話怎么做呢?我們只需要修改示例中的頭部,將--check=1改成--execute=1即可
/*--user=xucl;--password=xuclxucl123;--host=127.0.0.1;--execute=1;--port=3308;*/
那你如果想備份的話,添加選項--backup=1即可
/*--user=xucl;--password=xuclxucl123;--host=127.0.0.1;--execute=1;--backup=1;--port=3308;*/
三、審核規則
goinception的審核規則可以見文檔:https://hanchuanchuan.github.io/goInception/rules.html
我撿了一些我認為比較重要的審核規則,列成表格如下:
create table
表屬性
| 檢查項 | 相關配置項 |
|---|---|
| 這個表不存在 | |
| 當前庫存在 | |
| 表名、列名、索引名的長度不大于64個字節 | |
| 對象名允許字符[a-zA-Z0-9_] | check_identifier |
| 字符集限制 | enable_set_charset,support_charset |
| 排序規則限制 | enable_set_collation,support_collation |
| 存儲引擎限制 | enable_set_engine,support_engine |
| 不能建立為分區表 | enable_partition_table |
| 只能有一個主鍵 | |
| 表要有主鍵 | check_primary_key |
| 至少有一個列 | |
| 表必須包含某些列 | must_have_columns |
| 不允許create table as 語法 | |
| 禁止使用Foreign key | enable_foreign_key |
列屬性
| 檢查項 | 相關配置項 |
|---|---|
| char長度大于20的時候需要改為varchar(長度可配置) | max_char_length |
| 不能有重復的列名 | |
| 非數值列不能使用自增 | |
| 不允許無效庫名/表名前綴 | |
| 如果是timestamp類型的,則要必須指定默認值。 | check_timestamp_default |
| 如果是datetime類型的,則要必須指定默認值。 | check_datetime_default |
| 不能同時有兩個timestamp類型的列,如果是datetime類型,則不能有兩個指定DEFAULT CURRENT_TIMESTAMP及ON UPDATE CURRENT_TIMESTAMP的列。 | check_timestamp_count,check_datetime_count |
| 只有timestamp或datatime才能指定on update | |
| on update表達式只能為CURRENT_TIMESTAMP |
索引屬性檢查項
| 檢查項 | 相關配置項 |
|---|---|
| 索引必須要有名字 | enable_null_index_name |
| Unique索引必須要以uniq_為前綴 | check_index_prefix |
| 普通索引必須要以idx_為前綴 | check_index_prefix |
| 索引的列數不能超過5個 | max_key_parts |
| 主鍵索引列數限制 | max_primary_key_parts |
| 主鍵列必須使用int或bigint | enable_pk_columns_only_int |
| 建索引時,指定的列必須存在。 | |
| 索引中的列,不能重復 | |
| BLOB列不能建做KEY | |
| 索引長度不能超過767或3072,由實際mysql的innodb_large_prefix決定 | |
| 索引名不能是PRIMARY | |
| 索引名不能重復 |
默認值
| 檢查項 | 相關配置項 |
|---|---|
| BLOB/TEXT類型的列,不能有非NULL的默認值 | enable_blob_not_null |
| 如果默認值為NULL,但列類型為NOT NULL,或者是主鍵列,或者定義為自增列,則報錯。 | |
| JSON列不能設置默認值。 | |
| 每個列都需要定義默認值,除了自增列/主鍵/JSON/計算列/以及大字段列之外 | check_column_default_value |
自增列
| 檢查項 | 相關配置項 |
|---|---|
| 建表時,自增列初始值為1 | check_autoincrement_init_value |
| 如果自增列的名字不為id,說明可能是有意義的,不建議 | check_autoincrement_name |
| 自增列類型必須為int或bigint | check_autoincrement_datatype |
| 自增列需要設置無符號 | enable_autoincrement_unsigned |
ALTER
| 檢查項 | 相關配置項 |
|---|---|
| 表是否存在 | |
| 同一個表的多個ALTER建議合并 | merge_alter_table |
| 列是否存在 | |
| 表屬性只支持對存儲引擎、表注釋、自增值及默認字符集的修改操作。 | |
| 是否允許change column操作 | enable_change_column |
| 是否允許列順序變更 | check_column_position_change |
| 是否允許列類型變更 | check_column_type_change |
DML
INSERT
| 檢查項 | 相關配置項 |
|---|---|
| 表是否存在 | |
| 列必須存在 | |
| 不為null的列,如果插入的值是null,報錯 |
INSERT SELECT
| 檢查項 | 相關配置項 |
|---|---|
| 涉及的所有庫/表/字段必須存在 | |
| 必須指定插入列表,也就是要寫入哪些列,如insert into t (id,id2) select … | check_insert_field |
| 是否允許select * | enable_select_star |
| 必須有where條件 | check_dml_where |
| 不能有order by rand子句 | enable_orderby_rand |
| 使用explain獲取預估行數或select count獲取真實行數 | 調用選項real_row_count,explain_rule |
UPDATE/DELETE
| 檢查項 | 相關配置項 |
|---|---|
| 表必須存在 | |
| 必須有where條件 | check_dml_where |
| 不能有order by語句 | check_dml_orderby |
| 影響行數大于10000條,則報警(數目可配置) | max_update_rows |
| 對WHERE條件這個表達式做簡單檢查,具體包括什么不一一指定 | |
| 多表更新、刪除時,每個表及涉及字段必須要存在 | |
| update 多表關聯時,如果set未指定表前綴,自動判斷 | |
| 多表時判斷未指明表前綴的列是否有歧義 | |
| update多表關聯時,如果set了多個表的字段,同樣支持回滾語句生成 | |
| 使用explain獲取預估行數或select count獲取真實行數 | 調用選項realRowCount,explain_rule |
| mysql版本在5.6之前時,自動將語句轉換為select做explain | |
設置數據庫sql_safe_updates參數 | sql_safe_updates |
| 多表關聯時,審核join語句是否包含on子句 | check_dml_where |
| 條件中的列是否存在隱式類型轉換 | check_implicit_type_conversion |
| update set 判斷set使用了逗號還是and分隔 |
四、使用感受
簡單測試了一下goinception,整體體驗下來感覺還是很不錯的,相比于之前的inception來說,goinception有如下幾個優點:
安裝部署非常簡單,官方直接提供了二進制包
集成了gh-ost無需另外安裝,同時也提供pt-osc方式執行DDL
提供了基于表大小的ALTER執行選項,并且可配置大小
支持關聯更新,inception本身是不支持的
提供了更加豐富的審核規則選項,并且是基于MySQL5.7的,相比于inception來說支持度更好
長期穩定更新,從github上的commit記錄看作者還是更新得很勤奮的
更快的備份功能,之前使用inception的時候經常會碰到需要備份的binlog過大,網絡超時的現象(從文檔上看goinception使用的批量備份,據說速度能快很多)
五、系統集成
到這里,我們已經基本上選擇goinception作為我們的審核引擎了,那么如何集成到現有的自動化系統中是個問題。
先說一下我們公司的情況,我們公司有流程中心,也就是開發會在上面選擇庫,提交SQL,DBA收到工單以后人工審核,手工執行。
在審核過程中,對于DBA來說,肉眼審核也太過于辛酸了,手工執行一不小心就是背黑鍋。所以,基于goinception,我這邊提供了幾個restful的接口,分別如下:
db信息接口,根據用戶權限,返回該用戶所能看到的dbname
SQL檢查接口,用戶提交SQL,調用goinception進行審核,審核通過以后到DBA
SQL執行接口,DBA選擇執行的實例,調用goinception進行SQL執行,執行完成以后通知開發工單完成
開發查看工單,可以下載對應的回滾SQL
感謝各位的閱讀,以上就是“如何理解SQL審核利器goinception”的內容了,經過本文的學習后,相信大家對如何理解SQL審核利器goinception這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。