最近在玩python,为了熟悉一下python,写了个mysql的检查与性能优化建议的脚本。

虽然,真的只能算是一个半成残次品。也拿出来现眼一下。

不过对于初学者来说,还是有一定的参考价值的。比如说如何接受命令参数,python如果调用shell等。

这个脚本的主要过程就是把mysql的状态信息输出到一个临时文件,再读取临时文件解析一下比对结果。

其实做好难的不是脚本本身,而是看你对于mysql的方方面面的熟悉程度了。

如果想完善的话,其实可以做几方面的事情。

比如说根据机器配置信息(如内存,CPU),查看一下配置信息是否合理。查看一个其它配置项是否合理,用户帐号等检查之类。

关于OS方面,只是简单输出,还可以做简单分析。如磁盘是否太满了,IO/CPU是否过高等。

可惜最近没时间弄。不多说了,直接上代码(也不怕人笑了)。

#!/usr/bin/python
import getopt
import os
import sys
import platform
import re usages = '''
Usage: mysql_sts_analyze.py [OPTION]
The parameter changes recommendation of MySQL, based on the global status & system variables.
-H hostname Connect to host. Default: localhost
-P port Port number to use for connection to MySQL Server. Default: 3306
-u username User for login.
-p password Password to use when connecting to server.
-t interval time interval between two SLEEP commands. Default: 300 (seconds)
''' error_messages = {
"max_conn_excessive" : "too many connections. Recommendation: increase max_connections, or drop unused connection.",
"excessive_tmp_tables" : "Created_tmp_disk_tables / Created_tmp_tables *100 >= 25%. Recommendation: increase the tmp_table_size & max_heap_table_size, or check the SQLs use temporay tables.",
"small_table_open_cache": "table_open_cache too small. Recommendation: increase the table_open_cache variables",
"dead_lock_error" : "Dead lock occurs in the system. Recommendation: Invest by check more info from INNODB_TRX, INNODB_LOCKS, INNODB_LOCK_WAITS.",
"buffer_pool_hit_rate_low": "Buffer pool hit rate usually should be up to 998/1000. Recommendation: Increase the innodb_buffer_pool_size"
} def parse_status(name):
dict_variables={}
dict_sts_1={}
dict_sts_2={}
list_innodb_sts=[] try:
fh = open(name, "r")
except IOError:
print ("Error: File %s not found." %(name))
return ({},{},{},[])
else:
iShowStsCnt = 0
# 1: global variables, 2: status one, 3: status two, 4: innodb sts
iCurrentParse = 0 for line in fh.readlines():
newStrl = line.replace("\n", "")
if(newStrl == 'SHOW GLOBAL VARIABLES' and iCurrentParse == 0) :
iCurrentParse = 1
continue
elif( newStrl == 'SHOW GLOBAL STATUS' and iShowStsCnt == 0 and iCurrentParse == 0) :
iShowStsCnt += 1
iCurrentParse = 2
continue
elif( newStrl == 'SHOW GLOBAL STATUS' and iShowStsCnt == 1 and iCurrentParse == 0) :
iCurrentParse = 3
continue
elif( newStrl == 'SHOW ENGINE INNODB STATUS' and iCurrentParse == 0):
iCurrentParse = 4
continue
elif( newStrl == 'END SHOW') :
iCurrentParse = 0
continue #show engine innodb status no need to parse
if(iCurrentParse == 4):
list_innodb_sts.append(newStrl)
continue;
#newStr = line.replace(" ", "").replace("\t", "").strip()
#newStrl=newStrl.lower()
paras = newStrl.split("\t")
if len(paras)==2 :
if( iCurrentParse == 1):
dict_variables[paras[0]]=paras[1]
elif (iCurrentParse == 2):
dict_sts_1[paras[0]] = paras[1]
elif (iCurrentParse == 3):
dict_sts_2[paras[0]] = paras[1] fh.close() return dict_variables,dict_sts_1,dict_sts_2,list_innodb_sts; def generate_mysql_output(sh_script, hostname,port,username,password,tmpfile,sleep_time_interval):
cmd = '%s %s %s %s %s %s %s' %(sh_script, hostname,port,username,password,tmpfile,sleep_time_interval)
#print ("Executing shell script to gather mysql status:\n" + cmd)
print("-------------------------------\nGeneral Statistic info:\n-------------------------------")
os.system(cmd) def show_os_sts():
#process CPU info
cmd = 'top -b -n 1 - p `pidof mysqld|awk \'{print $1}\'`'
print("-------------------------------\nShow CPU usage info:\n-------------------------------\n" + cmd)
os.system(cmd)
#RMA info
cmd = 'free -lh'
print("-------------------------------\nShow RAM usage info:\n-------------------------------\n" + cmd)
os.system(cmd)
#Disk info
cmd = 'df -lTh'
print("-------------------------------\nShow disk usage info:\n-------------------------------\n" + cmd)
os.system(cmd)
#IO info
cmd = 'iostat -x 1 1'
print("-------------------------------\nShow IO info:\n-------------------------------\n" + cmd)
os.system(cmd)
#network INFO
cmd = 'sar -n DEV 1 1'
print("-------------------------------\nShow network usage info:\n-------------------------------\n" + cmd)
os.system(cmd) def show_common_sts(dict_sts_1,dict_sts_2):
toltal_queries1 = int(dict_sts_1['Com_select']) + int(dict_sts_1['Com_insert']) \
+ int(dict_sts_1['Com_update']) + int(dict_sts_1['Com_delete'])
toltal_queries2 = int(dict_sts_1['Com_select']) + int(dict_sts_1['Com_insert']) \
+ int(dict_sts_1['Com_update']) + int(dict_sts_1['Com_delete']) query_per_second = float(toltal_queries1 + toltal_queries2) / float(int(dict_sts_2['Uptime']) - int(dict_sts_1['Uptime']))
#print("###query per second: %f" % (query_per_second)) print("Uptime: %s Threads: %s Slow queries: %s Open tables: %s Queries per second: %.2f" %(\
dict_sts_2['Uptime'],\
dict_sts_2['Threads_running'], \
dict_sts_2['Slow_queries'], \
dict_sts_2['Open_tables'], \
query_per_second \
))
def show_recommend_changes(dict_variables,dict_sts_1,dict_sts_2):
print ("-------------------------------\nStatus Variables Relvant Recommend\n-------------------------------")
#Max_used_connections > 85%
if( int(dict_sts_2['Max_used_connections']) *100 / int(dict_variables['max_connections']) > 85) :
print (error_messages['max_conn_excessive'])
if(int(dict_sts_2['Created_tmp_disk_tables']) *100 / int(dict_sts_2['Created_tmp_tables']) > 25):
print(error_messages['excessive_tmp_tables'])
#Open_tables / Opened_tables * 100% >= 85% table_open_cache
if( int(dict_sts_2['Open_tables'])*100/int(dict_sts_2['Opened_tables']) < 85):
print(error_messages['small_table_open_cache']) def index_of_str(s1, s2):
n1=len(s1)
n2=len(s2)
for i in range(n1-n2+1):
if s1[i:i+n2]==s2:
return i
else:
return -1
#print(index_of_str('12abc34de5f', 'c34'))
def show_innodb_recommend(list_innodb_lines):
print ("-------------------------------\nInnodb Engine Status Relvant Recommend\n-------------------------------")
cnt =0;
for elem in list_innodb_lines:
if (index_of_str(elem,'LATEST DETECTED DEADLOCK') >= 0):
print (error_messages['dead_lock_error'])
elif(index_of_str(elem,'Buffer pool hit rate') >= 0):
#Format: Buffer pool hit rate 944 / 1000
#buff_pool_Reg = re.compile(r'(\D+) (\d+) / (\d+)')
#grp = buff_pool_Reg.search(elem)
grp = re.search(r'(\D+) (\d+) / (\d+)', elem) num1 = int(grp.group(2))
num2 = int(grp.group(3))
if(num1*100/num2 < 998):
print (grp.group(0))
print (error_messages['buffer_pool_hit_rate_low']) cnt += 1
if (cnt == 100):
pass ########################################
## Main program start hear
########################################
HOSTNAME='localhost'
PORT=3306
USERNAME='root'
PASSWORD='root'
if platform.system().lower() == 'linux':
TMPFILE = '/tmp/output-mysql.txt'
else:
TMPFILE='e:\\output-mysql.txt' SHELL_SCRIPT='./gather_mysql_sts.sh'
#unit second
SLEEP_INTERVAL=300
#TMPFILE='/tmp/output-mysql.txt'
try:
opts, args = getopt.getopt(sys.argv[1:], '-h-H:-P:-u:-p:-t:')
#print(opts)
for opt_name, opt_value in opts:
if opt_name in ('-h'):
print(usages)
sys.exit()
if opt_name in ('-H'):
HOSTNAME = opt_value
continue;
if opt_name in ('-P'):
PORT = opt_value
continue;
if opt_name in ('-u'):
USERNAME = opt_value
continue;
if opt_name in ('-p'):
PASSWORD = opt_value
continue;
if opt_name in ('-t'):
SLEEP_INTERVAL = opt_value
continue;
except getopt.GetoptError as e:
print ('ERROR: %s' % str(e))
print(usages)
sys.exit(2) if platform.system().lower() == 'linux':
generate_mysql_output(SHELL_SCRIPT,HOSTNAME,PORT,USERNAME,PASSWORD,TMPFILE,SLEEP_INTERVAL)
dict_variables,dict_sts_1,dict_sts_2,list_innodb_sts = parse_status(TMPFILE) show_common_sts(dict_sts_1,dict_sts_2)
show_recommend_changes(dict_variables,dict_sts_1,dict_sts_2)
show_innodb_recommend(list_innodb_sts)
if platform.system().lower() == 'linux':
show_os_sts()
#print (dict_variables)
#print (dict_sts_1)
#print (dict_sts_2) sys.exit(0)

gather_mysql_sts.sh脚本

#!/bin/bash
if [ $# -ne 6 ];
then
echo "Invalid parameter numbers $#"
exit
fi
hostname=$1
port=$2
username=$3
password=$4
tmpfile=$5
sleep_interval=$6 if test -e $tmpfile
then
rm -rf $tmpfile
fi mysql -h $hostname -P $port -u $username -p$password 1>/dev/null 2>&1<< EOF
#mysql -h $hostname -P $port -u $username -p$password << EOF
TEE $tmpfile;
SELECT NOW();
SELECT "SHOW GLOBAL VARIABLES";
SHOW GLOBAL VARIABLES;
SELECT "END SHOW";
SELECT "SHOW GLOBAL STATUS";
SHOW GLOBAL STATUS;
SELECT "END SHOW";
SELECT SLEEP($sleep_interval);
SELECT "SHOW GLOBAL STATUS";
SHOW GLOBAL STATUS;
SELECT "END SHOW";
SELECT "SHOW ENGINE INNODB STATUS";
SHOW ENGINE INNODB STATUS\G
SELECT "END SHOW";
NOTEE;
EOF

执行帮助如下:

[root@master python-study]# ./mysql_sts_analyze.py -h

Usage: mysql_sts_analyze.py [OPTION]
The parameter changes recommendation of MySQL, based on the global status & system variables.
-H hostname Connect to host. Default: localhost
-P port Port number to use for connection to MySQL Server. Default: 3306
-u username User for login.
-p password Password to use when connecting to server.
-t interval time interval between two SLEEP commands. Default: 300 (seconds)

执行结果输出:

./mysql_sts_analyze.py -u root -p Xiaopang*803 -t 10
-------------------------------
General Statistic info:
-------------------------------
Uptime: 136 Threads: 2 Slow queries: 0 Open tables: 54 Queries per second: 1.00
-------------------------------
Status Variables Relvant Recommend
-------------------------------
table_open_cache too small. Recommendation: increase the table_open_cache variables
-------------------------------
Innodb Engine Status Relvant Recommend
-------------------------------
Buffer pool hit rate 950 / 1000
Buffer pool hit rate usually should be up to 998/1000. Recommendation: Increase the innodb_buffer_pool_size
-------------------------------
Show disk usage info:
-------------------------------
df -lTh
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/cl-root xfs 29G 21G 8.8G 70% /
devtmpfs devtmpfs 486M 0 486M 0% /dev
tmpfs tmpfs 497M 8.0K 497M 1% /dev/shm
tmpfs tmpfs 497M 6.6M 490M 2% /run
tmpfs tmpfs 497M 0 497M 0% /sys/fs/cgroup
/dev/sda1 xfs 1014M 140M 875M 14% /boot
tmpfs tmpfs 100M 0 100M 0% /run/user/0
-------------------------------
Show RAM usage info:
-------------------------------
free -lh
total used free shared buff/cache available
Mem: 992M 446M 193M 17M 352M 380M
Low: 992M 799M 193M
High: 0B 0B 0B
Swap: 0B 0B 0B
-------------------------------
Show CPU usage info:
-------------------------------
top -b -n 1 - p `pidof mysqld|awk '{print $1}'`
top - 23:15:37 up 2 min, 2 users, load average: 0.46, 0.39, 0.17
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
%Cpu(s): 4.0 us, 2.9 sy, 0.0 ni, 81.9 id, 11.1 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1016476 total, 197836 free, 457576 used, 361064 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 389412 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2091 mysql 20 0 1327188 368768 15456 S 0.0 36.3 0:02.02 mysqld
-------------------------------
Show network usage info:
-------------------------------
sar -n DEV 1 1
Linux 3.10.0-514.el7.x86_64 (master) Wednesday, July 14, 2021 _x86_64_ (1 CPU) 11:15:37 HKT IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s
11:15:38 HKT enp0s3 6.06 9.09 0.44 1.13 0.00 0.00 0.00
11:15:38 HKT enp0s8 0.00 0.00 0.00 0.00 0.00 0.00 0.00
11:15:38 HKT lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Average: IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s
Average: enp0s3 6.06 9.09 0.44 1.13 0.00 0.00 0.00
Average: enp0s8 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00

MySQL检查与性能优化示例脚本的更多相关文章

  1. mysql配置以及性能优化(转)

    MySQL配置文件my.cnf中文详解,附mysql性能优化方法分享 ================================================================= ...

  2. MySQL之查询性能优化(二)

    查询执行的基础 当希望MySQL能够以更高的性能运行查询时,最好的办法就是弄清楚MySQL是如何优化和执行查询的.MySQL执行一个查询的过程,根据图1-1,我们可以看到当向MySQL发送一个请求时, ...

  3. MySQL抓包工具:MySQL Sniffer 和性能优化

    简介 MySQL Sniffer 是一个基于 MySQL 协议的抓包工具,实时抓取 MySQLServer 端的请求,并格式化输出.输出内容包访问括时间.访问用户.来源 IP.访问 Database. ...

  4. MySql学习—— 查询性能优化 深入理解MySql如何执行查询

    本篇深入了解查询优化和服务器的内部机制,了解MySql如何执行特定查询,从中也可以知道如何更改查询执行计划,当我们深入理解MySql如何真正地执行查询,明白高效和低效的真正含义,在实际应用中就能扬长避 ...

  5. 2020重新出发,MySql基础,性能优化

    @ 目录 MySQL性能优化 MySQL性能优化简述 使用 SHOW STATUS 命令 使用慢查询日志 MySQL 查询分析器 EXPLAIN DESCRIBE 索引对查询速度的影响 MySQL优化 ...

  6. MySQL 基础及性能优化工具

    数据库,用户及权限 常用用户管理操作 # 创建本地用户 abc create user abc@localhost # 创建内网能够访问的用户 abc create user abc@'192.168 ...

  7. 利用 gperftools 对nginx mysql 内存管理 性能优化

    利用 gperftools 对nginx 与 mysql  进行 内存管理  性能优化 降低负载. Gperftools 是由谷歌开发.官方对gperftools 的介绍为: These tools ...

  8. MySQL系列:性能优化

    1. 优化简介 MySQL性能优化包括:查询优化.数据库结构优化.MySQL服务器优化等. 2. 查询优化 2.1 分析查询语句 MySQL提供EXPLAIN和DESCRIBE,用来分析查询语句. E ...

  9. 2018/09/17《涂抹MySQL》【性能优化及诊断】学习笔记(七)

    读 第十三章<MySQL的性能优化与诊断> 总结 一说性能优化,整个人都像被打了鸡血一样

随机推荐

  1. 深入理解java虚拟机笔记Chapter3-内存分配策略

    内存分配策略 新生代和老年代的 GC 操作 新生代 GC 操作:Minor GC 发生的非常频繁,速度较块. 老年代 GC 操作:Full GC / Major GC 经常伴随着至少一次的 Minor ...

  2. Centos7拓展磁盘(逻辑增加)

    目录 第一步 第二步 第三步 以107.4G的Centos操作系统拓展20G磁盘空间,并将此20G磁盘空间分别分配给/home为例. 第一步 首先查看操作系统分区状况和磁盘占用情况.发现磁盘sda空间 ...

  3. 实验8、31个最重要的Python Flask面试问题和答案

    实验介绍 1. 实验内容 内容涵盖了31个最热门的Flask面试问题,帮助学生更好的理解Flask. 2. 实验要点 了解面试Flask开发人员的常见问题 实验内容 Flask面试问答 Q:Flask ...

  4. 【NX二次开发】Block UI 通过浏览选择文件夹

    属性说明 属性   类型   描述   常规           BlockID    String    控件ID    Enable    Logical    是否可操作    Group    ...

  5. 【UG二次开发】装配设计

    与装配相关的术语 tag 部件或对象的标识,还可能是部件原型.实例和事例 piece part 单个部件 occurrence 部件或对象的事例,装配中的是部件事例 object occurrence ...

  6. NOIP模拟测试28「阴阳·虎·山洞」

    写这几个题解我觉得我就像在按照官方题解抄一样 阴阳 题解 将题目中给的阴阳看作黑色和白色 首先我们观察到最后生成图中某种颜色必须是竖着单调递增或竖着单调递减 类似这样 否则不满足这个条件 但合法染色方 ...

  7. Telnet查看端口是否通

    1. 查看端口是否通畅   telnet IP 端口号 如:telnet 10.150.159.71 5516 2.查看本机是否开启某个端口:netstat -an |findstr "端口 ...

  8. 浏览器中js怎么将图片下载而不是直接打开

    网上找了好多方法都是不能用的,经过试验在Chrome中都是直接打开. 经过自己的摸索,找到了一套能用的解决方案 var database = "data:image/jpg;base64,& ...

  9. Golang编写动态库实现回调函数

    Golang编写动态库实现回调函数 我们现在要做一个动态库,但是C++实在是比较难,于是就想能不能用更简单的golang来实现,golang也就是最近的版本才支持编译成动态库,在网上也没找到可用的案例 ...

  10. 学习Qt Charts - 不使用UI的情况下使用QTCharts

    新建一个Qt Widgets Application项目,不添加UI文件,如下图: 建立工程后,在.pro文件中添加: QT += charts 然后在.h文件中添加: #include " ...