通过zabbix监控mysql的tps和qps,我们之前的percona mysql模板是没有关于这两个监控项的,需要我们通过脚本进行统计分析。
一、脚本思路:
#统计qps来源
show global status where Variable_name in('com_select','com_insert','com_delete','com_update');
#统计tps来源
show global status where Variable_name in('com_commit','com_rollback');
1.通过以上两条sql可以统计mysql从启动开始运行至今所有的qps、tps来源,我们每5分钟统计一次,使用(第二次-第一次)/时间差,可以得到qps、tps。
2.为了避免每次读库并提高脚本运行的效率,我们将本次的qps、tps来源存入临时文件,以便下次计算使用
3.由于脚本第一次运行没有临时文件或临时文件为空,因此我们通过延迟1秒读两次库,两次统计之差直接得到本次的qps
4.后续使用临时文件中的数据即可
二、脚本如下:
#!/usr/bin/env python
#-*- coding: utf8 -*-
#date: 2018-04-12
#author: yanggd
#comment: 计算mysql的qps和tps
import MySQLdb
import time
import sys
import os
class Mysql(object):
def __init__(self, host, port, user, passwd, db, unix_socket='/tmp/mysql.sock'):
self.host = host
self.port = port
self.user = user
self.passwd = passwd
self.db = db
self.unix_socket = unix_socket
self.conn = MySQLdb.connect(host=self.host,port=self.port,user=self.user,passwd=self.passwd,db=self.db,unix_socket=self.unix_socket)
self.cursor = self.conn.cursor()
def queryQps(self):
#获取qps来源
sql = "show global status where Variable_name in('com_select','com_insert','com_delete','com_update');"
self.cursor.execute(sql)
return self.cursor.fetchall()
def queryTps(self):
#获取tps来源
sql = "show global status where Variable_name in('com_commit','com_rollback');"
self.cursor.execute(sql)
return self.cursor.fetchall()
def closeDB(self):
self.cursor.close()
self.conn.close()
class Qps(object):
def __init__(self,qps_com):
self.qps_com = qps_com
def getQps(self):
qps_total = 0
for res in self.qps_com:
qps_total += int(res[1])
return qps_total
class Tps(object):
def __init__(self,tps_com):
self.tps_com = tps_com
def getTps(self):
tps_total = 0
for res in self.tps_com:
tps_total += int(res[1])
return tps_total
if __name__ == '__main__':
#时间间隔
diff = 300
#临时存放上次的qps,tps文件
qps_before = '/tmp/qps'
tps_before = '/tmp/tps'
mysql = Mysql('localhost',3306,'root','test','')
if len(sys.argv) <> 2:
print "Usage: " + sys.argv[0] + ' qps|tps'
elif sys.argv[1] == 'qps':
#若临时文件不存在或数据为空,通过延迟1秒,来获取本次的qps;最后将本次的qps来源数据存放到临时文件,供下次使用
if not os.path.exists(qps_before) or os.path.getsize(qps_before) == 0:
qps_com = mysql.queryQps()
qps = Qps(qps_com)
q1 = qps.getQps()
time.sleep(1)
qps_com = mysql.queryQps()
qps = Qps(qps_com)
q2 = qps.getQps()
print (q2-q1)
with open(qps_before, 'w') as f:
f.write(str(q2))
#若临时文件存在且有数据,获取上次qps并计算;最后将本次的qps来源数据存放到临时文件,供下次使用
else:
qps_com = mysql.queryQps()
qps = Qps(qps_com)
qps_cur = qps.getQps()
with open(qps_before) as f:
qps_last=f.read()
print (qps_cur-int(qps_last))/diff
with open(qps_before, 'w') as f:
f.write(str(qps_cur))
elif sys.argv[1] == 'tps':
#若临时文件不存在或数据为空,通过延迟1秒,来获取本次的tps;最后将本次的tps来源数据存放到临时文件,供下次使用
if not os.path.exists(tps_before) or os.path.getsize(tps_before) == 0:
tps_com = mysql.queryTps()
tps = Tps(tps_com)
t1 = tps.getTps()
time.sleep(1)
tps_com = mysql.queryTps()
tps = Tps(tps_com)
t2 = tps.getTps()
print (t2-t1)
with open(tps_before, 'w') as f:
f.write(str(t2))
#若临时文件存在且有数据,获取上次tps并计算;最后将本次的tps来源存放到临时文件,供下次使用
else:
tps_com = mysql.queryTps()
tps = Tps(tps_com)
tps_cur = tps.getTps()
with open(tps_before) as f:
tps_last=f.read()
print (tps_cur-int(tps_last))/diff
with open(tps_before, 'w') as f:
f.write(str(tps_cur))
else:
print "请输入正确参数: qps|tps"
mysql.closeDB()
三、配置zabbix agent
cd /etc/zabbix/zabbix_agentd.d/
vim userparameter_tps_qps.conf
UserParameter=mysql.qps,python /App/scripts/zabbix/mysql_qps_tps.py qps
UserParameter=mysql.tps,python /App/scripts/zabbix/mysql_qps_tps.py tps
四、配置percona mysql模板
1.配置监控项
2.配置图形
注意:时间间隔为300s,我们每5分钟统计一次。
mysql tps的监控项和图像也按如上配置。
四、总结
除了上述方式,还可以使用:
基于 questions 计算qps,基于 com_commit com_rollback 计算tps
questions = show global status like 'questions';
uptime = show global status like 'uptime';
qps=questions/uptime
com_commit = show global status like 'com_commit';
com_rollback = show global status like 'com_rollback';
uptime = show global status like 'uptime';
tps=(com_commit + com_rollback)/uptime
Questions 是记录了从mysqld启动以来所有的select,dml 次数包括show 命令的查询的次数。这样多少有失准确性,比如很多数据库有监控系统在运行,每5秒对数据库进行一次show 查询来获取当前数据库的状态,而这些查询就被记录到QPS,TPS统计中,造成一定的”数据污染”。