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的個人雜貨鋪,您的支援是對我最大的鼓勵!共同學習,共同進步:)