天天看點

自動記錄MySQL慢查詢快照腳本特性快速使用配置項說明使用建議配置檔案示例

python完成的一個小程式,用于殺掉 mysql 上的異常線程,如慢查詢、處于sleep狀态的。

寫這個腳本的初衷是在使用阿裡雲rds的過程中,資料庫出現異常,需要快速恢複。網上有許多類似的kill腳本,都是通過 mysqladmin 實作的。然而 ali-rds 環境有以下限制:

不提供 super 權限的使用者,也就是使用者隻能 kill 自己的線程

當連接配接數暴增時,外部使用者無法登陸,包括控制台

為了解決上午2大問題,該 python 腳本通過在db執行個體上,使用多線程的方式,為每個使用者保留一個連接配接,并實時讀取指令配置檔案 <code>mysqk.ini</code>,發現有 kill 需求時,利用對應使用者已有連接配接找到 <code>information_schema.processlist</code> 中符合條件的線程,并 kill 。

說明:該腳本在9月份做過一次重寫,7月份的版本(分支 old_0.5.0)是每執行個體每使用者,對應一個線程,db執行個體一多線程數也太多,看得始終不太優雅,于是改成了一個db執行個體一個線程,維護同時維護多個使用者的會話。同時新版也加入了更多的功能,如按時間視窗檢查,包含或排除特定連接配接,郵件通知,配置項覆寫。

始終通過 mysql ping 維持一個長連接配接,并有斷開自動重來機制,解決沒有連接配接可用的尴尬局面

每個db執行個體有自己的線程,避免需要單獨登陸個别使用者去kill的繁複操作。

如果你具有 super 權限,也可以簡化配置做到相容

能夠分開應對需要殺死線程的場景:

長時間運作超過 n 秒的

sleep 狀态的事務 (一般不建議,但有時候kill它,可以快速釋放連接配接給管理者使用)

排除一些線程不能kill,如 binlog dump

包含特定關鍵字的線程要kill

出現符合條件的線程時,會對當時的processlist, engine status,lock_wait 做一個快照,并郵件發出

有試運作dry_run模式,即執行所有的檢查過程但不真正kill

支援隻在時間視窗内運作,考慮到晚上一些長任務不檢查

密碼加密

需要pip安裝<code>mysql-python</code>和<code>pycrypto</code>兩個庫,隻在python 2.7上有測試。

在 settings.py 裡面設定連接配接的使用者名和密碼資訊。這裡假設同一批db的要check的認證資訊是一樣的,指定的使用者既用于登入認證,也用于告知腳本哪些使用者需要被檢查。

密碼要通過 <code>prpcryptec.py</code> 加密,加密的密鑰需寫入腳本本身的 <code>key_db_auth</code>變量。(擔心洩露的話,把mysqk.py編譯成 pyc 來跑)

在 mysqk.ini 主配置檔案裡面

<code>db_info</code> 節設定需要被檢查的資料庫位址,如 <code>db01=10.0.200.100:3306</code>

可分别 <code>db01</code>等指定需要kill thread的選項。<code>[id_db01]</code> 則預設複用 <code>[db_commkill]</code> 的選項

<code>db_comconfig</code> 節設定 <code>db_puser</code> 為能檢視到所有processlist的權限使用者,且在 settings.py 的db_auth中已指定

隻想執行檢查,并不想真正kill異常線程,确認 dry_run不等于0

here we go!

<code>mysqk.ini</code>:

郵件通知相關設定,smtp服務位址和認證資訊。

<code>mail_receiver=</code> 設定空,表示不發郵件

設定要檢查kill哪些資料庫執行個體.

格式:<code>&lt;dbid&gt;=&lt;host&gt;:&lt;port&gt;</code>,dbid是唯一表示db執行個體的,後面設定各db需要被kill的選項,小節配置名就是 <code>id_&lt;dbid&gt;</code>;端口必需指定。

在這裡出現的db執行個體都會被執行檢查,可用 ; 注釋,但需要重新開機腳本。

檢查用公共配置,實時生效。

<code>db_puser</code>:指定一個使用者名用于 show processlist,需要的權限:process、information_schema庫檢視。可以認為是一個代表使用者,檢查異常thread,把結果提供給有該thread殺掉權限使用者。

<code>run_max_count</code>:執行檢查的次數,是一個全局控制開關。每次修改這個值都會重新開始檢查,即一個 clean start,讓剛修改的配置生效。

為 0 表示腳本不進行任何檢查,隻簡單維護與資料庫的連接配接存活。存活檢查頻率在 settings.py 由 <code>check_config_interval × check_ping_multi</code>決定

為 999 表示會在背景一緻檢查連接配接線程(但不一定有符合kill條件的),檢查的頻率在 settings.py 裡面 <code>check_config_interval</code> 指定

為其它值時,表示檢查次數滿後停止檢查

<code>dry_run</code>:是否開啟試運作模式,為0表示真實kill,為1或其它值表示試運作。試運作模式可用于監控慢查詢并告警。注意同一會話線程id隻告警一次

<code>run_time_window</code>:運作的檢查的時間視窗,格式如 <code>08:00-22:00</code>,在這個時間以外不執行檢查,留白表示不限制。主要考慮晚上一些統計任務可能出現“異常”線程。

kill用公共配置,實時生效,會被 <code>id_&lt;dbid&gt;</code> 節的選項覆寫。

<code>k_user</code>:很關鍵的一個選項,表示你要檢查并kill哪些資料庫使用者,多個用逗号分隔(不要帶引号)。

為 <code>all</code> 時,表示要檢查 settings.py 裡 db_auth 指定的所有使用者

為 <code>none</code> 時,表示不kill任何異常線程,效果與設定了 dry_run 模式相當

<code>k_longtime</code>:執行超過設定值的sql則認為異常。一般大于 check_config_interval

<code>k_sleep</code>:sleep超過設定秒的sql則認為異常,為 0 表示不殺掉sleep狀态的線程

<code>k_exclude</code>:排除掉那些特定關鍵字的線程,比如複制線程、管理者的連接配接等

<code>k_include</code>:包含這些特定關鍵字的線程,需要被kill。注意,它作用在滿足 k_user 和 k_exclude 的前提之下。

k_exclude與k_include 的值是支援python re子產品正則的格式,不要帶引号

這部分區域的配置項與 db_commconfig 相同,用于針對個别db的kill選項。

兩種組合模式:

設定 <code>dry_run=0</code>,預設 <code>k_user=none</code>,當資料庫出現異常時,主動修改對應db的k_user值,動态kill

設定 <code>dry_run=1</code>,預設 <code>k_user=all</code>,相當于運作在daemon模式,有慢查詢則郵件通知,并且記錄下當時的資訊

當然你也可以<code>dry_run=0</code>,<code>k_user=all</code>,讓程式一直在背景跑并kill,但生産環境極不推薦。

有日志和快照檔案可以檢視。

mysqlk.ini :