MySQL語句的審覈,在業界都已經基本被認同了,實際上也是對MySQL語句寫法的統一化,標準化,而以前的人工審覈,針對標準這個問題實際上是很吃力的,標準越多,DBA越累,開發也越累。 那麼在這個都追求自動化運維的時代,審覈也必需要跟上步伐,所以Inception誕生了。而Inception能夠作的工做遠不止是一個自動化審覈工具,同時還具有執行,生成對影響數據的回滾語句(相似閃回的功能),這樣一條龍服務的工具,將會給DBA的工做帶來翻天覆地的變化,DBA今後就從繁重的審覈、登上去執行,出錯了很難回滾(若是提早沒有備份的話)的被動局面解放了出來,忽然發現,作DBA原來能夠這麼輕鬆,工做能夠不飽和了,那就有更多的自由時間學習、進一步向自動化運維平臺的實現等更智能化的方向去發展,是具備里程碑意義的。 python
Inception是集審覈、執行、回滾於一體的一個自動化運維繫統。它是根據MySQL代碼修改過來的。mysql
相對於應用程序(上層審覈流程系統等)而言,它是一個服務器,在鏈接時須要指定linux
安裝依賴項c++
yum install cmake ncurses-devel gcc gcc-c++ openssl-devel
移除bison較新的版本git
yum remove bison –y
從http://ftp.gnu.org/gnu/bison/ 路徑,下載 bison-2.6.1.tar.gz 指定版本。下載後,上傳至服務器。github
解壓並安裝bisonsql
tar zxvf bison-2.6.1.tar.gz cd bison-2.6.1 ./configure && make && make install
下載數據庫
wget https://github.com/qunarcorp/inception/archive/master.zip
解壓服務器
unzip master.zip
cd inception-master
./inception_build.sh debug [Xcode]
指定路徑下建立inc.cnf網絡
touch /data/Inception/inc.cnf
初始化
/data/Inception/inception-master/debug/mysql/bin/Inception --defaults-file=/data/Inception/inc.cnf &
(##Inception 最佳啓動方式是經過nohup後臺啓動
nohup /data/Inception/inception-master/debug/mysql/bin/Inception --defaults-file=/data/Inception/inc.cnf &
)
找到初始化後的Inception
關閉Inception
kill -9 7927
[inception] general_log=1 general_log_file=inc.log port=6669 socket=/tmp/inc.socket character-set-client-handshake=0 character-set-server=utf8 inception_remote_system_password=備份庫密碼 inception_remote_system_user=備份庫帳號 inception_remote_backup_port=備份庫實例端口 inception_remote_backup_host=備份庫IP inception_support_charset=utf8mb4,utf8,latin1 inception_enable_nullable=0 inception_check_primary_key=1 inception_check_column_comment=1 inception_check_table_comment=1 inception_osc_min_table_size=1 inception_osc_bin_dir=/data/temp inception_osc_chunk_time=0.1 inception_ddl_support=1 inception_enable_blob_type=1 inception_check_column_default_value=1
(若是執行 ./inception_build.sh debug [Xcode] 命令報錯,可將inception-master目錄刪除,從新解壓,而後用
./inception_build.sh build linux 替代。固然,此時的可執行文件 在 /data/Inception/inception-master/build/mysql/bin/Inception
更多的安裝知識,可參閱 https://qunarcorp.github.io/inception/install/)
經過mysql 客戶端鏈接
執行 代碼驗證
inception get variables;
參數名 | 是否須要參數 | 是否可選 | 功能描述 |
--host | 是 | 否 | 須要操做的這部分語句塊對應的數據庫地址。指定方式能夠是IP地址、機器名或DNS域名等,只能惟一解析到這個機器便可。 |
--port | 是 | 否 | 與上面的--host選項對應,指定機器名,必然要再指定一個MySQL實例的端口。 |
--user | 是 | 否 | 經過--user指定的用戶名來鏈接須要操做SQL語句的MySQL實例。 |
--password | 是 | 否 | 與上面的--user選項對應。 |
--sleep | 是 | 是 | 這個參數用來指定在執行完每一條語句後,暫停多少毫秒,這樣能夠適當控制對線上數據庫的衝擊,特別是針對大量的寫入操做, 單位是毫秒,最小值爲0,也就是不暫停,最大值爲100秒,也就是100000毫秒。若是設置的值超過了100000毫秒, Inception會自動將其設置爲100000毫秒。這個參數能夠和其餘參數一塊兒設置,可是隻有在--enable-execute爲1的狀況下,才起做用。 |
--enable-check | 否 | 否 | 告訴Inception當前要作什麼操做,是審覈仍是執行,這個參數與下面的--enable-execute智能指定一個。enable-check就是要告訴Inception, 當前的請求是要作審覈操做,審覈完成後就返回結果集。 |
--enable-execute | 否 | 否 | 若是執行的選項是--enable-execute,則Inception在執行前還會作一次實時的審覈,這個審覈和前面指定的--enable-check時的 審覈是基本相同的,這是此次在審覈完成後,還會繼續進行。由於相同的語句在不一樣的時間審覈可能會產生不一樣的審覈結果(環境有可能變了), 因此有必要再作一次審覈。若是審覈發現了錯誤(而不是警告),就不會被執行,此時會提早返回告知錯誤;若是審覈發現的是警告, 而且沒有指定--enable-ignore-warnings,則有警告也不會執行。 |
--enable-ignore-warnings | 否 | 是 | Inception採起嚴格的分階段處理方式,先對全部的語句進行審覈,審覈完成以後,會執行全部的語句,以後再會執行全部語句的備份操做。 在三個階段的過渡過程當中,若是審覈有問題則不會繼續進行,此時若是人爲肯定想要跳過這些警告,則能夠選擇這個參數, 告訴Inception跳過這個警告的檢查,繼續執行。 |
--enable-force | 否 | 是 | 批量導入時,有可能會報主鍵衝突的問題,而DBA能夠肯定的是,出現主鍵衝突不是問題,能夠繼續執行,那麼此時能夠經過選項 --enable-force告訴Inception,在執行過程當中碰到一個錯誤時,能夠先保存錯誤信息並繼續下一條語句。此參數需謹慎使用。 |
--enable-remote-back | 否 | 是 | Inception支持備份並生成對應的回滾語句,這是默認的,但當有些影響行數不少且明確不須要回滾的時候,爲了提升執行效率, 能夠指定在執行時不作備份,指定方式是經過disable來禁用它,即disable-remote-backup。 |
--enable-split | 否 | 是 | 這個參數用來拆分要執行的語句塊。若是在語句塊中存在對同一個表的DDL操做和DML操做,那麼在分析Binlog來生成回滾語句時, 因爲表結構已經發生改變,會致使Inception沒有辦法處理,因此使用這個參數將這些語句分紅多批,而後再分別執行。這是在執行前 必需要作的一個操做,否則可能會產生不可預知的錯誤。固然在執行前的最後一次審覈中,若是檢查到這樣的混用狀況, 則會返回報錯,而不是警告。 |
--enable-query-print | 否 | 是 | 這個參數用來打印SQL語句在被Inception分析以後的執行樹結構,已JSON的形式提供,目的是爲了能夠在Inception的基礎上, 對已經結構化的(JSON)語句再次分析,能夠對Inception內置支持的規則進行擴展,作個性化定製,好比使用到哪些列、 哪些語句類型等信息。 |
返回列 | 詳細描述 |
ID | 用來表示結果集中記錄序號的,也就是被審覈的語句在語句塊中的序號,按位置排序,計數從1開始。 |
stage | 顯示當前語句已經進行到哪一步了,包括四個值:CHECKED、EXECUTED、RERUN和NONE。CHECKED表示這個語句只作審覈,而沒有再進行下一步操做;EXECUTED表示已經執行過, 若是執行失敗,也是用這個狀態表示,RERUN表示的是,對於影響上下文的語句,已經執行成功了,可是爲了與EXECUTED區分,用RERUN表示,主要是由於在執行過程當中,若是某一條語句 執行失敗了,則上層可能須要將沒有執行的語句提取出來,再次執行,那麼影響上下文的語句就是須要加上的,因此用RERUN來表示。Inception目前支持兩種影響上下文的語句,分別是 set names charset 語句和use database語句。NONE表示沒有作過任何處理,有可能前面有語法錯誤直接提早返回。 |
errlevel | 總共有三個值,分別是0、一、2。若是爲0,則說明當前語句審覈沒有任何問題;若是爲1,則說明當前語句審覈時發現有些寫法不符合Inception定義的內置規則,屬於警告;若是值爲2,則說明 當前語句審覈時,發現了嚴重錯誤,不管如何都不能經過的。 |
stagestatus | 該列用來描述當前語句的階段結果,與列stage對應。若是是審覈階段,而且完成,則返回Audit completed。若是是執行階段,而且執行成功則返回Execute Successfully,不然返回Execute failed。若是是備份階段,而且備份成功,則在執行描述信息後面追加Backup successfully,不然追加Backup failed。 |
errormessage | 用來表示出錯的錯誤信息,這裏包括一條語句中的全部錯誤信息,用換行符分隔,但有時候若是某一個錯誤致使不能繼續分析了,好比表不存在等問題,在這種狀況下,若是語句還有其餘錯誤, 就不能被審覈出來了。若是當前語句沒有任何錯誤,則這個列值爲NONE。對於執行及備份操做,由於對於一條語句,這樣的錯誤只會有一次,那麼執行錯誤會在執行後面追加:「execute:具體 的執行錯誤緣由」,若是是備份出錯,則在後面追加「backup:具體的錯誤緣由」。在執行時,有時候還會出現Warning。 |
SQL | 用來表示當前檢查的是那條SQL語句,這一列存儲的值就是這條SQL語句的文本內容。 |
affected_rows | 審覈時,用來表示當前語句預計影響的行數,這個行數通常是經過EXPLAIN來獲取的。在執行時,該列輸出的是執行時真實影響的行數。 |
sequence | 該列與Inception備份功能有關,其實就是與$_$Inception_backup_information$_$表中的列opid_time一一對應,這就爲自動化運維平臺針對某一條語句作回滾操做找到了入口。 |
backup_dbname | 該列表示的是當前語句產生的備份信息,存儲在備份服務器的那個數據庫中。若是是不須要備份的語句,則返回字符串NONE。 |
excute_time | 該列表示當前語句的執行時間,單位是秒,精確到小數點後兩位。列類型是字符串。若是隻是審覈而不執行,則該列返回的值爲0. |
SQLSHA1 | 這一列用來存儲當前這條語句的一個HASH值,用來標識這個語句是否會使用OSC功能,若是返回信息中有值,則表示這條語句在執行時會使用OSC。 |
Inception在作DML操做時,具備備份功能。它會將全部當前語句修改的行對應生成回滾語句並備份下來,同時也會將全部操做的任務備份下來,一塊兒存儲到一個指定的庫中。
參數 | 說明 |
inception_remote_backup_host | 指定遠程備份MySQL實例的地址。 |
inception_remote_backup_port | 指定遠程備份MySQL實例的端口。 |
inception_remote_system_user | 備份時,鏈接備份MySQL實例時所需的用戶名,這個用戶須要有相應的權限,通常包括Create、Insert和Select權限。 |
inception_remote_system_password | 備份時,鏈接備份庫時所須要的用戶對於的密碼。 |
由於線上機器有不少,而備份機器只有一臺,因此爲了防止在備份數據庫實例中存在庫名衝突的問題,備份機器的庫名是將線上機器IP地址的點換成下劃線,再加上端口號及庫名。
例如:
169_169_167_167_3306_testDB.
主要有兩類,一種針對線上每個表生產一個備份表,即與線上的表是一一對應的,表名相同,可是表結構不同。備份表主要用來存儲全部對錶修改的回滾語句。
主要有如下3列:
列名 | 說明 |
id | 標識列 |
rollback_statement | 當某一行被修改後,生成的對應的回滾語句。由於Binlog必須爲Row模式,因此,不論是什麼語句,產生的回滾語句都是針對被修改的行記錄的。 若是一條語句的執行,影響了多行,那麼這裏就會有多條回滾語句。 |
opid_time |
執行SQL語句時獲取的一個序列號。序列號由三部分組成:timestamp(int值,是語句執行的時間點)、線上服務器執行時所產生的thread_id及 當前這條語句在全部被執行語句塊中的一個序號。序列號在指定的備庫中是惟一的。針對同一條語句影響多行的狀況、在產生的多行回滾語句中, 該列的值是相同的。 |
還有一類表,其實這個表每一個庫中只有一個,$_$Inception_backup_information$_$。該表主要用來記錄全部對當前庫的操做,它是爲該庫中全部表服務的,對線上這個庫的全部的表的操做,都會被存儲在這裏面。
參數 | 說明 |
opid_time | 該列與上面備份表中的列opid_time是一一對應的,由於這個表中的每一行對應的是在線上執行的實際的一條SQL語句。 opid_time從各個備份表中查找這條語句對應的回滾語句,是一對多的關係。 |
start_binlog_file | 表示執行這條語句前Binlog所在的位置的文件名。這個值是經過 show master status 獲取的,在數據庫併發比較高的狀況下, 這個值不必定準確。這個值只能是這條語句產生Binlog前面的某個位置。同理。下面三個位置信息也是同樣。 |
start_binlog_pos | 該列與上面的列對應,表示的是上面指定文件的位置信息。 |
end_binlog_file | 該列表示的是執行當前語句以後,Binlog所在的文件名。 |
end_binlog_pos | 該列與上面的列對應,表示執行完成後,Binlog在文件end_binlog_file中的偏移位置。 |
sql_statement | 該列存儲的是當前這個被執行的SQL語句。 |
host | 表示在線上的哪一個數據庫實例上執行了該語句。 |
dbname | 表示執行當前語句時所處的環境變量,指的是數據庫名。 |
tablename | 表示當前語句影響的表的表名,經過這個名字對應到備份表名。 |
port | 與host對應,表示執行時數據庫的端口號。 |
time | 表示當前語句的執行時間 |
type | 表示操做類型,如今只支持INSERT、UPDATE、DDELETE、CREATEDB、CREATETABLE、ALTERTABLE、DROPTABLE等類型。 |
測試環境
類別 | ServerIP | Port |
線上數據庫 | XXX.XXX.XXX.9 | 3306 |
Inception | XXX.XXX.XXX.8 | 6669 |
備份數據庫 | XXX.XXX.XXX.9 | 3307 |
測試python腳本
#!/usr/bin/python #-*- coding:utf-8 -*- import MySQLdb sql='''/*--user=數據庫帳號;--password=相應密碼;--host=XXX.XXX.XXX.9;--execute=1;--port=3306;*/\ inception_magic_start;\ use dbtest;\ CREATE TABLE table_test(id int comment 'test' primary key) engine=innodb DEFAULT CHARSET=utf8mb4 comment '測試';\ inception_magic_commit;''' try: conn=MySQLdb.connect(host='XXX.XXX.XXX.8',user='',passwd='',db='',port=6669) cur=conn.cursor() ret=cur.execute(sql) result=cur.fetchall() num_fields = len(cur.description) field_names = [i[0] for i in cur.description] print field_names for row in result: print row[0], "|",row[1],"|",row[2],"|",row[3],"|",row[4],"|",row[5],"|",row[6],"|",row[7],"|",row[8],"|",row[9],"|",row[10] cur.close() conn.close() except MySQLdb.Error as e: print "Mysql Error %d: %s" % (e.args[0], e.args[1])
執行結果以下:
去備份庫上查看,備份狀況以下:
若是在測試的過程當中,發現沒有實現備份,能夠從如下幾個方面去檢查
(1)線上服務器必需要打開Binlog,在啓動時須要設置參數log_bin、log_bin_index等關於Binlog的參數。否則不會備份及生成回滾語句,由於Inception的生成回滾語句是經過解析Binlog來作的。
(2)參數必須binlog_format必須設置爲mixed或者row模式。若是是statement模式,則不作備份及回滾語句的生成。可經過語句set global binlog_format=ROW來設置。
(3)將binlog_row_image設置爲full ,該配置項默認爲 full ,可是若是爲了減小binlog的size改爲minimal的話,則Inception沒法生成回滾語句。
(4)參數server_id必須設置爲非0非1,經過語句set global server_id=server_id;來設置,否則在備份時報錯。由於在獲取Binlog時,須要經過server_id在主庫上註冊Inception。
(5)被修改表須要有主鍵:執行時,被影響的表若是沒有主鍵的話,就不會作備份了。這樣更簡單而且備份時間及數據都會少一點,否則回滾語句的where條件就會將全部列寫進去,這樣會影響性能且沒有太大意義,因此在where條件中,只須要主鍵便可。
(6)備份相關的四個參數須要設置好,而且對應的用戶在備份數據庫實例中有足夠的權限。
1執行 Python驗證,報錯信息。
ImportError: No module named MySQLdb
解決方案:
yum install MySQL-python
2.有時候執行Python腳本報錯:invalid source infomation。
這時候須要去檢查Inception鏈接數據庫的參數配置。
其數據存儲在備份實例上的inception數據庫上statistic表中,此庫自動生成。
主要字段的說明以下:
列名 | 字段描述 |
deleting | 包括普通的刪除操做及多表刪除操做。 |
inserting | 包括單行插入、多行插入及查詢插入。 |
updating | 包括普通單表更新及多表的更新。 |
renaming | 指的是ALTER table語句中的rename操做。 |
createindex | 指的是ALTER table語句中的add index操做。 |
dropindex | 指的是ALTER table語句中的drop index操做。 |
alteroption | 指的是ALTER table語句中的修改表屬性的操做,好比存儲引擎、自增值及字符集中操做。 |
alterconvert | 指的是ALTER table語句中修改表字符集的操做。 |
-----主要內容參考梳理於網絡知識和《MySQL運維內參》,此短文僅爲學習筆記,在此原創做者感謝!