##================================================================##

先来个笑话:

刚交的女朋友让我去他家玩,我觉得空手不好,于是告诉她我买点东西就过去,谁知道她突然来一句:不用买,家里还有一盒!

##================================================================##

昨天在折腾一台磁盘出现性能问题的MySQL时,根据监控去慢日志里找,发现短短10分钟有好几万行慢日志,由于对慢日志结构不熟悉,打开一个600+MB的文件拖着滚动条看,好多慢SQL一条SQL就有几百行,看来看去都没找到问题最根本原因,总算功夫不负有心人,总算在不经意间找到,要不然让我在无知中慢慢老去???

问题SQL如下:

造成的影响:

怀疑造成问题的原因:

由于子查询中没有任何过滤条件,进行全表扫描,而服务器内存不够,导致扫描出来的数据有写到临时文件中,同时服务器上还有其他业务运行,服务器无法及时处理完所有请求,造成积压,而积压请求又增加服务器压力,最终导致相互影响恶性循环。

也不知道研发为啥蛋疼地这么套一下,反正Mysql语句优化处理能力这么差,大家尽可能简化SQL吧

##===================================================##

言归正传,由于这一个SQL执行频率较低,使用pt工具分析不能准确定位到该SQL,而使用肉眼看又比较蛋疼,因此写个小工具来处理,同时还可以解决慢日志较大阅读不便的问题。

python脚本如下:

# coding: utf-8
import datetime
from optparse import OptionParser MAX_QUERY_TIME_SECONDS = 10
START_DATETIME = datetime.datetime.min
END_DATETIME = datetime.datetime.max
SLOW_LOG_PATH = "" class EventInfo(object):
def __init__(self):
self.exec_time = None
self.login_user = ""
self.query_time_seconds = 0
self.lock_time_seconds = 0
self.rows_sent = 0
self.rows_examined = 0
self.command_text = ""
self.file_line_num = 0 def get_datetime_by_time_line(time_line):
if time_line.startswith("# Time:"):
time_str = "" + time_line.replace("# Time:", "").replace(" ", " ").strip()
return datetime.datetime.strptime(time_str, "%Y%m%d %H:%M:%S")
else:
return None def set_query_info(event_info, query_info_line):
line = query_info_line
if line.startswith("# Query_time:"):
tmp_line = line.replace("#", "").replace(": ", ":").replace(" ", " ").replace(" ", " ")
tmp_items = tmp_line.split(" ")
for tmp_item in tmp_items:
# print(tmp_item)
if tmp_item.strip().startswith("Query_time:"):
event_info.query_time_seconds = float(tmp_item.replace("Query_time:", ""))
if tmp_item.strip().startswith("Lock_time:"):
event_info.lock_time_seconds = float(tmp_item.replace("Lock_time:", ""))
if tmp_item.strip().startswith("Rows_sent:"):
event_info.rows_sent = float(tmp_item.replace("Rows_sent:", ""))
if tmp_item.strip().startswith("Rows_examined:"):
event_info.rows_examined = float(tmp_item.replace("Rows_examined:", "")) def set_login_user(event_info, login_user_line):
line = login_user_line
if line.startswith("# User@Host:"):
event_info.login_user = line.replace("# User@Host:", "").strip() def set_command_text(event_info, command_text_line):
line = command_text_line
event_info.command_text += chr(13) + line def print_event_info(event_info):
print_info = """
file_line_num: {7}
Time: {0}
User@Host: {1}
Query_time: {2:.5f} seconds
Lock_time: {3:.5f} seconds
Rows_sent: {4}
Rows_examined: {5}
command_text:
{6}
""".format(event_info.exec_time,
event_info.login_user,
event_info.query_time_seconds,
event_info.lock_time_seconds,
event_info.rows_sent,
event_info.rows_examined,
event_info.command_text,
event_info.file_line_num)
print("*" * 70)
print(print_info) def get_user_paras():
try:
opt = OptionParser()
opt.add_option('--slow_log',
dest='slow_log',
type=str,
help='the file path of the slow log ')
opt.add_option('--long_query_seconds',
dest='long_query_seconds',
type=float,
help='long query seconds')
opt.add_option('--start_datetime',
dest="start_datetime",
type=str,
help="start datetime, format is %Y-%m-%d %H:%M:%S")
opt.add_option('--end_datetime',
dest="end_datetime",
type=str,
help="end datetime, format is %Y-%m-%d %H:%M:%S")
(options, args) = opt.parse_args()
error_messages = []
slow_log = options.slow_log
start_datetime = options.start_datetime
long_query_seconds = options.long_query_seconds
end_datetime = options.end_datetime
if not slow_log:
error_messages.append("slow_log must be set;")
else:
global SLOW_LOG_PATH
SLOW_LOG_PATH = slow_log
if not long_query_seconds:
error_messages.append("long_query_seconds must be set;")
else:
global MAX_QUERY_TIME_SECONDS
MAX_QUERY_TIME_SECONDS = long_query_seconds
try:
if start_datetime is not None:
tmp_start_datetime = datetime.datetime.strptime(start_datetime, "%Y-%m-%d %H:%M:%S")
global START_DATETIME
START_DATETIME = tmp_start_datetime
except:
error_messages.append("the format of start_datetime was wrong ;")
try:
if end_datetime is not None:
tmp_end_datetime = datetime.datetime.strptime(end_datetime, "%Y-%m-%d %H:%M:%S")
global END_DATETIME
END_DATETIME = tmp_end_datetime
except:
error_messages.append("the format of end_datetime was wrong ;") if len(error_messages) > 0:
opt.print_help()
for error_message in error_messages:
print(error_message)
return False
else:
return True
except Exception as ex:
print("exception :{0}".format(str(ex)))
return False def read_log():
global MAX_QUERY_TIME_SECONDS
file_path = SLOW_LOG_PATH
file_handler = open(file_path)
line = file_handler.readline()
line_num = 1
find_event_count = 0
current_event_info = EventInfo()
current_time = ""
has_time = False
while line:
if line.startswith("# Time:"):
current_time = get_datetime_by_time_line(line)
if current_time < START_DATETIME:
line = file_handler.readline()
line_num += 1
continue
if current_time > END_DATETIME:
break line = file_handler.readline()
line_num += 1
has_time = True
continue
if has_time:
if line.startswith("# User@Host:"):
if current_event_info.query_time_seconds > MAX_QUERY_TIME_SECONDS:
print_event_info(event_info=current_event_info)
find_event_count += 1
current_event_info = EventInfo()
current_event_info.file_line_num = line_num
current_event_info.exec_time = current_time
set_login_user(event_info=current_event_info,
login_user_line=line)
elif line.startswith("# Query_time:"):
set_query_info(event_info=current_event_info,
query_info_line=line)
else:
set_command_text(event_info=current_event_info,
command_text_line=line)
line = file_handler.readline()
line_num += 1
print("*" * 70)
print("parse completely")
print("find {0} events".format(find_event_count)) def main():
if get_user_paras():
read_log() if __name__ == '__main__':
main()

脚本调用方式如:

C:\Python27\python.exe D:/GGA/Code/slow_query_find/find_slow_quer.py --slow_log="D:\slow.log.2016010900" --long_query_seconds=4 --start_datetime="2016-01-08 15:46:00" --end_datetime="2016-01-08 15:50:00"

显示结果如:

##==================================================================##

Python--过滤Mysql慢日志的更多相关文章

  1. python mysql开发日志

    开始做python 的数据库访问了,暂时选定了mysql数据库.原本想使用ORM,后来考虑到项目的情况是:表结构不复杂,但是数据库非常大.还是自己来操作sql,不过PYTHON的那些数据库ORM的代码 ...

  2. 使用 python 管理 mysql 开发工具箱 - 1

    Mysql 是一个比较优秀的开源的数据库,很多公司都在使用.作为运维人员,经常做着一些重复性的工作,比如创建数据库实例,数据库备份等,完全都可以使用 python 编写一个工具来实现. 一.模块 Co ...

  3. Python自动化 【第十二篇】:Python进阶-MySQL和ORM

    本节内容 数据库介绍 mysql 数据库安装使用 mysql管理 mysql 数据类型 常用mysql命令 创建数据库 外键 增删改查表 权限 事务 索引 python 操作mysql ORM sql ...

  4. Python操作MySQL -即pymysql/SQLAlchemy用法

    本节介绍Python对于MySQL的一些操作用法 模块1:pymysql(等同于MySQLdb) 说明:pymysql与MySQLdb模块的使用基本相同,学会pymysql,使用MySQLdb也就不是 ...

  5. ELK 构建 MySQL 慢日志收集平台详解

    ELK 介绍 ELK 最早是 Elasticsearch(以下简称ES).Logstash.Kibana 三款开源软件的简称,三款软件后来被同一公司收购,并加入了Xpark.Beats等组件,改名为E ...

  6. Python 12 - Mysql & ORM

    本节内容 1.数据库介绍 2.mysql数据库安装使用 3.mysql数据库基础 4.mysql命令 5.事务 6.索引 7.Python操作mysql 8.ORM sqlalchemy了解 数据库介 ...

  7. 前端和后端的数据交互(jquery ajax+python flask+mysql)

    上web课的时候老师布置的一个实验,要求省市连动,基本要求如下: 1.用select选中一个省份. 2.省份数据传送到服务器,服务器从数据库中搜索对应城市信息. 3.将城市信息返回客户,客户用sele ...

  8. logstash采集tomcat日志、mysql错误日志

    input{ file { path => "/opt/Tomcat7.0.28/logs/*.txt" start_position => "beginni ...

  9. python创建MySQL多实例-1

    python创建MySQL多实例-1 前言 什么是多实例 多实例就是允许在同一台机器上创建另外一套不同配置文件的数据库,他们之间是相互独立的,主要有以下特点, 1> 不能同时使用一个端口 2&g ...

  10. ELK构建MySQL慢日志收集平台详解

    上篇文章<中小团队快速构建SQL自动审核系统>我们完成了SQL的自动审核与执行,不仅提高了效率还受到了同事的肯定,心里美滋滋.但关于慢查询的收集及处理也耗费了我们太多的时间和精力,如何在这 ...

随机推荐

  1. HTML5新增的属性

    关于html5新增的属性: HTML5现在已经不是SGML的子集,主要是增加了关于图像,位置,存储,多任务等功能. 绘画CANVAS; 用于播放媒体的video和audio元素: 本地离线存储loca ...

  2. C# 有关打印机的连接判断...随便看看

    各位coder手下留情 /// <summary> /// 判断是否连接打印机 /// </summary> public bool CheckPrinter() { //取得 ...

  3. 在DW 5.5+PhoneGap+Jquery Mobile下搭建移动开发环境

    移动设备应用开发有多难,只要学会HTML5+Javascript就可以.用Dreamweaver5.5+PhoneGap+Jquery Mobile搭建移动开发环境,轻轻松松开发你自己的应用.让你用普 ...

  4. UML类图6种关系的总结

    http://www.open-open.com/lib/view/open1328059700311.html

  5. JavaScript常用函数之Eval()使用

    eval() 功能:首先解释Javascript代码  然后执行它 用法:Eval(codeString) codeString是包含有javascript语句的字符串,在eval之后使用Javasc ...

  6. JS-Dom概念

    <!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content=&q ...

  7. SSH项目(struts+spring+hibernate)搭建_代码简化

    在上篇讲到SSH框架的搭建后,为了有利于随时能熟练的把一个SSH的项目快速的搭建起来,我又进一步对其了解学习,对代码进行了简化,大家相互讨论学习. 为什么要简化:  如果要做一个大项目,假设项目的ac ...

  8. Android 时间维护服务 TimeService(针对于特殊定制设备)

    此方法针对于无法自动获取网络时间的特殊设备,正常 Android 设备直接调用 System.currentTimeMillis(); 方法获取当前时间即可. TimeService 集成于 Serv ...

  9. 最新基于adt-bundle-windows-x86的android开发环境筹建

    最新基于adt-bundle-windows-x86的android开发环境搭建 某系统要配套做一个android客户端,来一次android开发环境快速搭建,系统Win7,具体步骤如下: 1.下载j ...

  10. Scrum - BB项目日志

    这是第三个Scrum团队开发,也是我首次担任Scrum Master一职.所以需要掌握的流程还是很多,也会碰到各种问题,在此记录一下,希望对以后有所帮助. Day1: 开了一次kick-off mee ...