1. 程式人生 > >MySQL系統執行狀態實時監控(python版本)

MySQL系統執行狀態實時監控(python版本)

昨天的文章,用shell寫了一個簡單的MySQL系統執行狀態實時監控的模版,《MySQL系統執行狀態實時監控(shell版本)》,對於這種操作,任何語言都可以完成,今兒就用python寫一下,寫的不優雅的地方,請各位指正。

首先,為了讓python能連線MySQL資料庫,需要一些第三方的庫,由於我用的是python 2.3版本,因此可以使用mysqldb,(若是python 3.x,則可以使用PyMySQL),可以從以下連結下載壓縮,目前最新版本是1.2.5,

https://pypi.python.org/pypi/MySQL-python/1.2.3


如果不確定本機是否安裝了,可以使用,

python

>>

import MySQLdb

看下是否報錯,若提示了,

ImportError: No module named MySQLdb

則表示未安裝。

解壓MySQL-python-1.2.3.tar.gz,


進入目錄,執行以下命令,完成mysqldb的安裝,

python setup.py install

接下來開始coding,首先定義一個列舉類,方便常量呼叫,此處為五個狀態引數,

def enum(**enums):

return type('Enum', (), enums)

Status=enum(QPS="queries", Commit="com_commit",

Rollback="com_rollback", Threads_con="Threads_connected",

Threads_run="Threads_running")

python連線資料庫,確實比java這些語言,要簡單些,

dbConn=MySQLdb.connect(

host='x.x.x.x',

port=3306,

user='bisal',

passwd='xxxxx',

db='mysql')

cursor=dbConn.cursor()

比如我要檢索QPS這個引數,執行以下SQL,由於是肯定只返回一條資料,所以用了fetchone()函式,為了只要返回值,使用str[a:b]進行了字串擷取。

sql='show global status like \'' + Status.QPS + '\''

cursor.execute(sql)

result=cursor.fetchone()

str= ''.join(result)

q=str[len(Status.QPS):len(str)]

接下來就可以格式化列印,同樣輸出10次,重新打印表頭,顯示sleep一秒,

if (count==0):

print "|QPS        |Commit     |Rollback   |TPS        |Threads_con  |Threads_run |"

print "------------------------------------------------------------------------------"

if (count>=10):

count=0

print "------------------------------------------------------------------------------"

print "|QPS        |Commit     |Rollback   |TPS        |Threads_con  |Threads_run |"

print "------------------------------------------------------------------------------"

print "|%-10s |%-10s |%-10s |%-10s |%-12s |%-12s|" % (q,c,r,c+r,tc,tr)

else:

print "|%-10s |%-10s |%-10s |%-10s |%-12s |%-12s|" % (q,c,r,c+r,tc,tr)

count+=1

time.sleep(1)

另外,記得需要關閉資料庫連線,

cursor.close()

dbConn.close()

整個流程,其實很簡單,就是執行show status語句,進行一些字串處理,格式化輸出,以上完整程式碼,可以下載:

https://github.com/bisal-liu/mysql/blob/master/mysql_per_monitor_1.py

要說可以優化,就是上面這種方法中,對於每一個狀態引數,都要執行一次show status,有些浪費,可以一次執行,多次解析,使用IN子句,實現執行一次SQL,返回不同引數,

sql='show global status where variable_name in (\'' + Status.QPS + '\',\'' + Status.Commit \

+ '\',\'' + Status.Rollback + '\',\'' + Status.Threads_con + '\',\'' + Status.Threads_run + '\')'

由於返回不止一條記錄,因此需要使用for,if中根據字串做匹配,以下寫法中,

1. 若使用了''.join(line),則需要使用q=k1[len(Status.QPS):len(k1)]擷取字串。

2. 若使用了str(line),則需要使用q=k2.split('\'')[3]擷取字串。

for line in result:

k1=''.join(line).lower()

k2=str(line).lower()

if (Status.QPS in k1):

q=k1[len(Status.QPS):len(k1)]

elif (Status.Commit in k1):

c=k1[len(Status.Commit):len(k1)]

elif (Status.Rollback in k1):

r=k1[len(Status.Rollback):len(k1)]

elif (Status.Threads_con in k1):

tc=k1[len(Status.Threads_con):len(k1)]

elif (Status.Threads_run in k1):

tr=k1[len(Status.Threads_run):len(k1)]

if (Status.QPS in k2):

q=k2.split('\'')[3]

elif (Status.Commit in k2):

c=k2.split('\'')[3]

elif (Status.Rollback in k2):

r=k2.split('\'')[3]

elif (Status.Threads_con in k2):

tc=k2.split('\'')[3]

elif (Status.Threads_run in k2):

tr=k2.split('\'')[3]

以上完整程式碼,可以下載,

https://github.com/bisal-liu/mysql/blob/master/mysql_per_monitor_2.py

以上兩種寫法,效果一樣,

1. 每隔1秒,重新整理一次,

2. 每隔10次,重新打印表頭,

如果您覺得此篇文章對您有幫助,歡迎關注微信公眾號:bisal的個人雜貨鋪,您的支援是對我最大的鼓勵!共同學習,共同進步:)