• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Python-过滤Mysql慢日志_mysql

mysql 搞代码 7年前 (2018-06-09) 160次浏览 已收录 0个评论

Python–过滤mysql慢日志

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

先来个笑话:

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

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

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

问题SQL如下:

Python-过滤Mysql慢日志_mysql

造成的影响:

Python-过滤Mysql慢日志_mysql

怀疑造成问题的原因:

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

也不知道研发为啥蛋疼地这么套一下,反正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 = "20" + 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慢日志_mysql

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

Python-过滤Mysql慢日志_mysql

1楼Uest
结束语的妹子升级成开篇的笑话啦

欢迎大家阅读《Python-过滤Mysql慢日志_mysql》,跪求各位点评,by 搞代码


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Python-过滤Mysql慢日志_mysql

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址