转载用sql语句计算出mysql数据库的qps,tps,iops性能指标

Posted zhming

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了转载用sql语句计算出mysql数据库的qps,tps,iops性能指标相关的知识,希望对你有一定的参考价值。

本帖最后由 LUK 于 2014-9-21 22:39 编辑 

思路:

1 关注MYSQL三个方面的性能指标,分别为query数,transaction数,io请求数

2 在某个时间范围内(例如20秒),统计mysql中上面的三个指标的总量,以及每一秒的量 ,同时每隔一秒种打印一个当前的指标量,在最后再计算并打印时间段内总量及每秒量

3 在IO的统计公式如下:
Key_reads  * 2 +  Key_writes * 2 + Key_read_requests + Innodb_data_reads + Innodb_data_writes + Innodb_dblwr_writes + Innodb_log_writes (该公式最早从taobaodba.com这个网上传出,这里学习借鉴)

key_reads 和 key_writes都乘以2的原因是因为如果从磁盘中读或写索引块之后会再去磁盘读或写数据块,所以就会有至少两倍的IO请求.
事务数总量为 com_commit+com_rollback
query数通过 com_select获取


4 虽然统计的时间范围可以自己指定(例如20秒),但最终计算每秒的指标量时,是以脚本开始执行时间至脚本执行结束时mysql uptime的时间差来算的,因为脚本执行会消耗一定时间,这样,实际的时间会多于我们指定的时间
(结束时的量-开始时的量)/(结束时uptime-开始时uptime)




#!/bin/bash

#filename mysqlgather.sh
#param
#N seconds
#s print query 
#t print transaction 
#i print mysql io
# example
# ./mysqlgather.sh 20 s t i  

--脚本的名字为mysqlgather.sh,执行例子为 ./mysqlgather.sh 20 s t i  
其中20为取样的时间范围,在这里假设20s,这个时间参数必须要输入,时间大小可以自己定
s 表示要统计query及query per second (可选参数)
t 表示要统计transaction及transaction per second (可选参数)
i 表示要统计mysql中的io请求数及io per second (可选参数)

s t i 三个参数可以只输入其中任意一个或多个,可以只统计三个指标中的一个或者两个

如果三个参数都写或者都不写,表示都要统计s t i


--selecom函数取query数量
#qps

selcom ()
{
      mysql -uroot -e "show global status where variable_name in (‘com_select‘);" > select.out
      SELECT_NUM=`grep -i "com_select"  select.out | awk ‘{print $2}‘`

      echo "com_select: $SELECT_NUM"
}


--trans_num函数 统计transaction数量
#tps

trans_num ()
{
     mysql -uroot -e "show global status where variable_name in(‘com_commit‘,‘com_rollback‘);" > transactions.out

     COMMIT_NUM=`grep -i "com_commit"  transactions.out | awk ‘{print $2}‘`
     ROLLBACK_NUM=`grep -i "com_rollback"  transactions.out | awk ‘{print $2}‘`

     SUM_TRAN=$[ $COMMIT_NUM1 + $ROLLBACK_NUM1 ]
     echo "transations:$SUM_TRAN"
}


--ionum函数统计io读写请求数

#IO

ionum ()
{
mysql -uroot -e "show global status where variable_name in(‘Key_reads‘,‘Key_writes‘,‘Key_read_requests‘,‘Innodb_data_reads‘,‘Innodb_data_writes‘,‘Innodb_dblwr_writes‘,‘Innodb_log_writes‘);" > iops.out
KEYREAD=`grep -i "Key_reads"  iops.out | awk ‘{print $2}‘`
KEYWRITE=`grep -i "Key_writes"  iops.out | awk ‘{print $2}‘`
READREQ=`grep -i "Key_read_requests"  iops.out | awk ‘{print $2}‘`
DATAREAD=`grep -i "Innodb_data_reads"  iops.out | awk ‘{print $2}‘`
DATAWRITE=`grep -i "Innodb_data_writes"  iops.out | awk ‘{print $2}‘`
DBLWR=`grep -i "Innodb_dblwr_writes"  iops.out | awk ‘{print $2}‘`
LOGWRITE=`grep -i "Innodb_log_writes"  iops.out | awk ‘{print $2}‘`

SUM_IO=$[ $KEYREAD * 2 + $KEYWRITE * 2 + $READREQ + $DATAREAD + $DATAWRITE + $DBLWR + $LOGWRITE ]
echo "io:$SUM_IO"
}

--up_time函数是统计MYSQL启动后的时间
#uptime
up_time ()
{
      mysql -uroot -e "show global status where variable_name in (‘Uptime‘);" > uptime.out
     UP_TIME=`grep -i "Uptime"  uptime.out | awk ‘{print $2}‘`
}



--下面的程序逻辑是先检查输入了哪些参数,再计算所想要统计的指标
NUM_PARM=$#

if [ $NUM_PARM = 1 ];then
PARM1=$1
up_time
UP_TIME1=$UP_TIME
selcom
SELECT_NUM1=$SELECT_NUM
trans_num
SUM_TRAN1=$SUM_TRAN
ionum
SUM_IO1=$SUM_IO

sleep 1
PARM1=$[ $PARM1 - 1]
while [ $PARM1 -gt 0 ]
do 
selcom
trans_num
ionum
PARM1=$[ $PARM1 - 1]
sleep 1
done
SELECT_NUM2=$SELECT_NUM
SUM_TRAN2=$SUM_TRAN
SUM_IO2=$SUM_IO
up_time
UP_TIME2=$UP_TIME


--统计时间范围内的总量
SELECT_DIFF=$[ $SELECT_NUM2 - $SELECT_NUM1 ]
TRANS_DIFF=$[ $SUM_TRAN2 - $SUM_TRAN1 ]
IO_DIFF=$[ $SUM_IO2 - $SUM_IO1 ]

TIME_DIFF=$[ $UP_TIME2 - $UP_TIME1 ]

--统计每秒的量
SELECT_PERSECOND=$[ $SELECT_DIFF / $TIME_DIFF]
TRANS_PERSECOND=$[ $TRANS_DIFF / $TIME_DIFF]
IOREQ_PERSECOND=$[ $IO_DIFF / $TIME_DIFF]
echo -n "sel_s:$SELECT_PERSECOND; trans_s:$TRANS_PERSECOND; io_s:$IOREQ_PERSECOND"
elif [ $NUM_PARM = 2 ];then
PARM1=$1
PARM2=$2

case $PARM2 in 
"s")
up_time
UP_TIME1=$UP_TIME
selcom
SELECT_NUM1=$SELECT_NUM

sleep 1
PARM1=$[ $PARM1 - 1]
while [ $PARM1 -gt 0 ]
do 
selcom
PARM1=$[ $PARM1 - 1]
sleep 1
done
SELECT_NUM2=$SELECT_NUM
up_time
UP_TIME2=$UP_TIME
SELECT_DIFF=$[ $SELECT_NUM2 - $SELECT_NUM1 ]
TIME_DIFF=$[ $UP_TIME2 - $UP_TIME1 ]
SELECT_PERSECOND=$[ $SELECT_DIFF / $TIME_DIFF]
echo -n "sel_s:$SELECT_PERSECOND;"

;;

"t")
PARM1=$1
up_time
UP_TIME1=$UP_TIME
trans_num
SUM_TRAN1=$SUM_TRAN
sleep 1
PARM1=$[ $PARM1 - 1]
while [ $PARM1 -gt 0 ]
do 
trans_num
PARM1=$[ $PARM1 - 1]
sleep 1
done
SUM_TRAN2=$SUM_TRAN
up_time
UP_TIME2=$UP_TIME
TRANS_DIFF=$[ $SUM_TRAN2 - $SUM_TRAN1 ]
TIME_DIFF=$[ $UP_TIME2 - $UP_TIME1 ]
TRANS_PERSECOND=$[ $TRANS_DIFF / $TIME_DIFF]
echo -n " trans_s:$TRANS_PERSECOND; "

;;

"i")
PARM1=$1
up_time
UP_TIME1=$UP_TIME

ionum
SUM_IO1=$SUM_IO

sleep 1
PARM1=$[ $PARM1 - 1]
while [ $PARM1 -gt 0 ]
do 

ionum
PARM1=$[ $PARM1 - 1]
sleep 1
done

SUM_IO2=$SUM_IO
up_time
UP_TIME2=$UP_TIME
IO_DIFF=$[ $SUM_IO2 - $SUM_IO1 ]
TIME_DIFF=$[ $UP_TIME2 - $UP_TIME1 ]
IOREQ_PERSECOND=$[ $IO_DIFF / $TIME_DIFF]
echo -n " io_s:$IOREQ_PERSECOND"

;;

*)
exit;
esac



elif [ $NUM_PARM = 3 ];then
PARM1=$1
PARM2=$2
PARM3=$3

if [ $PARM2 = "s" ] || [ $PARM2 = "t" ] && [ $PARM3 = "s" ] || [ $PARM3 = "t" ]; then
PARM1=$1
up_time
UP_TIME1=$UP_TIME
selcom
SELECT_NUM1=$SELECT_NUM
trans_num
SUM_TRAN1=$SUM_TRAN
sleep 1
PARM1=$[ $PARM1 - 1]
while [ $PARM1 -gt 0 ]
do 
selcom
trans_num
PARM1=$[ $PARM1 - 1]
sleep 1
done
SELECT_NUM2=$SELECT_NUM
SUM_TRAN2=$SUM_TRAN
up_time
UP_TIME2=$UP_TIME

SELECT_DIFF=$[ $SELECT_NUM2 - $SELECT_NUM1 ]
TRANS_DIFF=$[ $SUM_TRAN2 - $SUM_TRAN1 ]

TIME_DIFF=$[ $UP_TIME2 - $UP_TIME1 ]
SELECT_PERSECOND=$[ $SELECT_DIFF / $TIME_DIFF]
TRANS_PERSECOND=$[ $TRANS_DIFF / $TIME_DIFF]
echo -n "sel_s:$SELECT_PERSECOND; trans_s:$TRANS_PERSECOND;"

elif [ $PARM2 = "s" ] || [ $PARM2 = "i" ] && [ $PARM3 = "s" ] || [ $PARM3 = "i" ];

PARM1=$1
up_time
UP_TIME1=$UP_TIME
selcom
SELECT_NUM1=$SELECT_NUM
ionum
SUM_IO1=$SUM_IO

sleep 1
PARM1=$[ $PARM1 - 1]
while [ $PARM1 -gt 0 ]
do 
selcom
ionum
PARM1=$[ $PARM1 - 1]
sleep 1
done
SELECT_NUM2=$SELECT_NUM
SUM_IO2=$SUM_IO
up_time
UP_TIME2=$UP_TIME

SELECT_DIFF=$[ $SELECT_NUM2 - $SELECT_NUM1 ]
IO_DIFF=$[ $SUM_IO2 - $SUM_IO1 ]

TIME_DIFF=$[ $UP_TIME2 - $UP_TIME1 ]
SELECT_PERSECOND=$[ $SELECT_DIFF / $TIME_DIFF]
IOREQ_PERSECOND=$[ $IO_DIFF / $TIME_DIFF]
echo -n "sel_s:$SELECT_PERSECOND;  io_s:$IOREQ_PERSECOND"
else
PARM1=$1
up_time
UP_TIME1=$UP_TIME
trans_num
SUM_TRAN1=$SUM_TRAN
ionum
SUM_IO1=$SUM_IO

sleep 1
PARM1=$[ $PARM1 - 1]
while [ $PARM1 -gt 0 ]
do 
trans_num
ionum
PARM1=$[ $PARM1 - 1]
sleep 1
done
SUM_TRAN2=$SUM_TRAN
SUM_IO2=$SUM_IO
up_time
UP_TIME2=$UP_TIME
TRANS_DIFF=$[ $SUM_TRAN2 - $SUM_TRAN1 ]
IO_DIFF=$[ $SUM_IO2 - $SUM_IO1 ]

TIME_DIFF=$[ $UP_TIME2 - $UP_TIME1 ]
TRANS_PERSECOND=$[ $TRANS_DIFF / $TIME_DIFF]
IOREQ_PERSECOND=$[ $IO_DIFF / $TIME_DIFF]
echo -n " trans_s:$TRANS_PERSECOND; io_s:$IOREQ_PERSECOND"
fi
elif [ $NUM_PARM = 4 ];then
PARM1=$1
PARM2=$2
PARM3=$3
PARM4=$4
up_time
UP_TIME1=$UP_TIME
selcom
SELECT_NUM1=$SELECT_NUM
trans_num
SUM_TRAN1=$SUM_TRAN
ionum
SUM_IO1=$SUM_IO
sleep 1
PARM1=$[ $PARM1 - 1]
while [ $PARM1 -gt 0 ]
do 
selcom
trans_num
ionum
PARM1=$[ $PARM1 - 1]
sleep 1
done
SELECT_NUM2=$SELECT_NUM
SUM_TRAN2=$SUM_TRAN
SUM_IO2=$SUM_IO
up_time
UP_TIME2=$UP_TIME


SELECT_DIFF=$[ $SELECT_NUM2 - $SELECT_NUM1 ]
TRANS_DIFF=$[ $SUM_TRAN2 - $SUM_TRAN1 ]
IO_DIFF=$[ $SUM_IO2 - $SUM_IO1 ]

TIME_DIFF=$[ $UP_TIME2 - $UP_TIME1 ]

SELECT_PERSECOND=$[ $SELECT_DIFF / $TIME_DIFF]
TRANS_PERSECOND=$[ $TRANS_DIFF / $TIME_DIFF]
IOREQ_PERSECOND=$[ $IO_DIFF / $TIME_DIFF]
echo -n "sel_s:$SELECT_PERSECOND; trans_s:$TRANS_PERSECOND; io_s:$IOREQ_PERSECOND"


else
echo "You have not input any parameter!";
exit;
fi




















































































































































































































































































































































































以上是关于转载用sql语句计算出mysql数据库的qps,tps,iops性能指标的主要内容,如果未能解决你的问题,请参考以下文章

我要用sql语句查询出MySql的各项监控指标...

MySQL 定位不合理的索引(转载)

用T-sql语句写出 查询出平均分大于80分,且至少两门课大于80的学生。 表如下:

用SQL语句查询出数据表中的字段名以及注释(Oracle)

mysql基础语句

用SQL语句计算出给定日期是星期几?