分析Mysql慢日志是运维工作中,不可少的。要快速定位慢Sql,以及发现后优化Sql及修改业务,保证数据库稳定高效地工作。下面是我工作中解决的思路...
1.先查看本地数据库慢日志文件
2.编写分析慢日志脚本
#!/usr/bin/python
#coding=utf-8 #字符编码
import re #导入正则匹配模块
import time #导入时间模块
import sys #导入sys模块
import MySQLdb #导入连接mysql模块
canshu=len(sys.argv) #参数个数
def help():
#帮助函数
print "分析当天慢日志执行命令python %s today today" %sys.argv[0]
print "分析以前慢日志执行命令python %s before 日志名字" %sys.argv[0]
def create_table():
# 打开数据库连接
db=MySQLdb.connect("192.168.1.1","test","test","log_fenxi")
# 使用cursor()方法获取操作游标
cursor=db.cursor()
# 如果数据表已经存在使用 execute() 方法删除表。
cursor.execute("DROP TABLE IF EXISTS `mysql_slow`;")
# 创建数据表SQL语句
sql="""CREATE TABLE `mysql_slow` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`Query_time` float(11,6) NOT NULL,
`Lock_time` char(11) NOT NULL,
`Rows_sent` int(11) NOT NULL,
`Rows_examined` int(11) NOT NULL,
`time` datetime NOT NULL,
`slow_sql` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;"""
cursor.execute(sql)
# 关闭数据库连接
db.close()
def insert_table():
log_file=open(log_name) #读取慢日志
# 打开数据库连接
db=MySQLdb.connect("192.168.1.1","test","test","log_fenxi")
# 使用cursor()方法获取操作游标
cursor = db.cursor()
for line in log_file:
line=line.strip()
Query_time=re.search(‘Query_time:(\s\d+\.\d+)‘,line) #正则匹配慢日志时间
Lock_time=re.search(‘Lock_time:(\s\d+\.\d+)‘,line) #正则匹配锁定时间
Rows_sent=re.search(‘Rows_sent:(\s\d+)‘,line) #正则匹配返回结果好多行数据
Rows_examined=re.search(‘Rows_examined:(\s\d+)‘,line) #正则匹配扫描好多行数据
timestamp=re.search(‘timestamp=(\d+)‘,line) #正则匹配时间戳
slow_sql=re.match(‘(SELECT.*?);‘,line) #正则匹配慢sql
if Query_time:
Query_time_new=Query_time.group(1).strip() #匹配正则结果赋值
if Lock_time:
Lock_time_new=Lock_time.group(1).strip() #匹配正则结果赋值
if Rows_sent:
Rows_sent_new=Rows_sent.group(1).strip() #匹配正则结果赋值
if Rows_examined:
Rows_examined_new=Rows_examined.group(1).strip() #匹配正则结果赋值
if timestamp:
timestamp=int(timestamp.group(1))
timeArray=time.localtime(timestamp)
sql_time=time.strftime("%Y-%m-%d %H:%M:%S", timeArray) #匹配正则结果赋值
if slow_sql:
slow_sql_new=slow_sql.group() #匹配正则结果赋值
# SQL 插入语句
sql = """INSERT INTO mysql_slow(Query_time,Lock_time,Rows_sent,Rows_examined,time,slow_sql)
VALUES ("""+Query_time_new+""","""+Lock_time_new+""","""+Rows_sent_new+""","""+Rows_examined_new+""",‘"""+sql_time+"""‘,‘"""+slow_sql_new+"""‘)""";
try:
# 执行sql语句
cursor.execute(sql)
# 提交到数据库执行
db.commit()
except:
# Rollback in case there is any error
db.rollback()
log_file.close()
# 关闭数据库连接
db.close()
def main():
global log_name
if canshu!=3:
print "参数数量错误,请检查!"
help()
else:
create_table()
xuanze=sys.argv[1] #第一个参数(慢日志时间)
log_before=sys.argv[2] #慢日志具体时间
if xuanze==‘today‘:
log_name=‘/data/mysqlp/mysql-slow.log‘
insert_table()
elif xuanze==‘before‘:
log_name=‘/data/logs/mysql_slow/%s‘ %log_before
insert_table()
else:
print ‘参数类型选择错误,类型只包含today|before‘
help()
main()3.用脚本处理的结果存在数据库中,查看数据库记录。
备注:
如果想快速定位那些Sql有问题,只需要把Query_time和Rows_examined字段进行降序排序就可以定位了。可以把排序在前面的Sql手动进行查询,如果发现还是比较慢就需要优化Sql和修改业务了。
如果想用此脚本直接使用,需要修改数据库连接ip和用户密码,还需要在日志库上面安装MySQLdb模块,并且需要修改当前慢日志路径及名字/data/mysqlp/mysql-slow.log,及保留慢日志的路径/data/logs/mysql_slow,这两个路径请根据自己存储路径修改,才能正常使用此脚本!
本文出自 “成都@阿状” 博客,请务必保留此出处http://azhuang.blog.51cto.com/9176790/1561517
原文地址:http://azhuang.blog.51cto.com/9176790/1561517