最近在玩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. Selenium-python 之弹窗处理

    在Selenium-python 中,有时候需要对弹窗进行处理,比如获取弹窗上的内容.确定.取消.在弹窗上输入内容后点击确定-再次点出弹窗,需要专门的处理. 一.获取弹窗的内容 driver.find ...

  2. JVM集合之开篇点题

    大家在平时的开发过程中是否遇到过StackOverflowError.OutOfMemoryError等类似的内存溢出错误呢?大家又是怎么解决这个问题的?再来,大家在面试过程中有没有被面试官提问过jv ...

  3. Git与GitHub入门

    一.git起步https://www.runoob.com/git/git-install-setup.html1.下载git(Windows)2.安装GUI(TortoiseGit)3.查看git配 ...

  4. Kali 2021.2 最新安装教程 图文详解(保姆式)

    0x00 前言 Kali Linux 新版本(2021.2)增加大量新工具和功能,感兴趣的小伙伴可以到kali官网查看相关介绍. 新版采用Xfce 4.16桌面环境,附上帅照! 0x01 安装环境 宿 ...

  5. [Azure DevOps] 编译时自动修改版本号

    1. 需求 在使用 Pipeline 自动化 CI/CD 流程的过程中,我还还需要自动修改程序集的版本号.这个功能 EdiWang 和LeoLaw 都写文章讲解过做法.不过我的项目基本都是 .Net ...

  6. Spring Boot WebFlux-02——WebFlux Web CRUD 实践

    第02课:WebFlux Web CRUD 实践 上一篇基于功能性端点去创建一个简单服务,实现了 Hello.这一篇用 Spring Boot WebFlux 的注解控制层技术创建一个 CRUD We ...

  7. SpringCloud-OAuth2(三):进阶篇

    上篇文章讲了SpringCloud OAuth 的实战篇,但是在微服务环境下,常常会有一个认证中心. 而普通服务接收到请求后,判断token是否有效并不是自己处理的,因为token的管理统一交给认证中 ...

  8. 一文读懂高速PCB设计跟高频放大电路应用当中的阻抗匹配原理

    这一期课程当中,我们会重点介绍高频信号传输当中的阻抗匹配原理以及共基极放大电路在高频应用当中需要注意的问题,你将会初步了解频率与波长的基础知识.信号反射的基本原理.特性阻抗的基本概念以及怎么样为放大电 ...

  9. MediaStore 与Media.EXTERNAL_CONTENT_URI

    MediaStore这个类是Android系统提供的一个多媒体数据库,android中多媒体信息都可以从这里提取. 这个MediaStore包括了多媒体数据库的所有信息,包括音频,视频和图像,andr ...

  10. SPF Tarjan算法求无向图割点(关节点)入门题

    SPF 题目抽象,给出一个连通图的一些边,求关节点.以及每个关节点分出的连通分量的个数 邻接矩阵只要16ms,而邻接表却要32ms,  花费了大量的时间在加边上. //   time  16ms 1 ...