分析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