重写慢日志解析程序,实现打印慢SQL信息及其所属数据库
发表于:2024-11-30 作者:千家信息网编辑
千家信息网最后更新 2024年11月30日,分组自研的审计平台最近推出慢SQL优化的功能,topN慢SQL可以通过mysqldumpslow拿到,但由于mysqldumpslow输出的信息不包含数据库,这让程序后续的自动优化变得有些棘手。在观察
千家信息网最后更新 2024年11月30日重写慢日志解析程序,实现打印慢SQL信息及其所属数据库
分组自研的审计平台最近推出慢SQL优化的功能,topN慢SQL可以通过mysqldumpslow拿到,但由于mysqldumpslow输出的信息不包含数据库,这让程序后续的自动优化变得有些棘手。在观察了MySQL慢日志结构后,决定自己写一个python解析程序,返回的结果比mysqldumpslow解析结果上多出数据库名称这一列:
Count: 15 Time=0.002961s (0.034505s) Lock=8.8e-05s (0.000767s) Rows=446 (6690), dbmgr[dbmgr]@10.33.46.179 mysql --SQL所属数据库 SHOW GLOBAL VARIABLES;
python版本:2.7
文件名称:slowParse.py --目前仅支持按query time取topN
代码内容:
import osimport sysdef get_sql(slowlog, topN): #Slow log 所在目录,请自行替换 f1 = open("/var/mysql/data3306/" + slowlog, "r") flag1 = 1 flag2 = 0 sqltext = "" slow_sql_all = {} sql_info = [] queryTime_list = [] locksTime_list = [] rows_list = [] logonInfo_list = [] db = "None" rownum = 0 while 1: line = f1.readline() rownum += 1 if not line: break elif "use " in line and len(line) < 30: db = getDB(line.strip()) elif "# User@Host" in line and flag1 == 1: flag2 = 1 userAndHost = getUserAndHost(line.strip()) logonInfo = userAndHost[0] + "[" + userAndHost[0] + "]@" + userAndHost[1] logonInfo_list.append(logonInfo) elif "# Query_time" in line and flag1 == 1 and flag2 == 1: execInfo = getExecInfo(line.strip()) queryTime_list.append(execInfo[0]) locksTime_list.append(execInfo[1]) rows_list.append(execInfo[2]) elif ";" in line and "SET timestamp" not in line and flag1 == 1 and flag2 == 1: flag2 = 0 sqltext = sqltext + line.strip() if slow_sql_all.has_key(sqltext): tmp = slow_sql_all[sqltext] tmp[0].append(queryTime_list[0]) tmp[1].append(locksTime_list[0]) tmp[2].append(rows_list[0]) tmp[3].append(logonInfo_list[0]) else: # count = 1 # sql_info.append(count) sql_info.append(queryTime_list) sql_info.append(locksTime_list) sql_info.append(rows_list) sql_info.append(logonInfo_list) sql_info.append(db) slow_sql_all[sqltext] = sql_info queryTime_list = [] locksTime_list = [] rows_list = [] logonInfo_list = [] sqltext = "" sql_info = [] elif flag1 == 1 and flag2 == 1 and "# User@Host" not in line and "# Query_time" not in line and "# Time" not in line and "SET timestamp" not in line: sqltext = sqltext + line.strip() + " " f1.close() sqlCombined = {} sqlTmp = {} for i in slow_sql_all: # print i,slow_sql_all[i] count = len(slow_sql_all[i][0]) totalQueryTime = 0 totalLocksTime = 0 totalRows = 0 for j in slow_sql_all[i][0]: totalQueryTime += float(j) maxQueryTime = float(max(slow_sql_all[i][0])) for k in slow_sql_all[i][1]: totalLocksTime += float(k) maxLocksTime = float(max(slow_sql_all[i][1])) for l in slow_sql_all[i][2]: totalRows += int(l) maxRows = int(max(slow_sql_all[i][2])) logonInfo = slow_sql_all[i][3][0] db = slow_sql_all[i][4] sqlCombined[i] = ( count, maxQueryTime, totalQueryTime, maxLocksTime, totalLocksTime, maxRows, totalRows, logonInfo, db) sqlTmp[i] = maxQueryTime sqlTopN = sorted(sqlTmp.items(), key=lambda x: x[1], reverse=True)[:topN] #请自行替换生成文件的所在目录 f2 = open("/var/mysql/data3306/" + slowlog[:-4] + "-top" + str(topN) + ".txt", "w") for i in sqlTopN: sqltext = i[0] count_str = "Count: " + str(sqlCombined[sqltext][0]) queryTime_str = "Time=" + str(sqlCombined[sqltext][1]) + "s (" + str(sqlCombined[sqltext][2]) + "s)" locksTime_str = "Lock=" + str(sqlCombined[sqltext][3]) + "s (" + str(sqlCombined[sqltext][4]) + "s)" rows_str = "Rows=" + str(sqlCombined[sqltext][5]) + " (" + str(sqlCombined[sqltext][6]) + ")," logonInfo_str = sqlCombined[sqltext][7] db_str = sqlCombined[sqltext][8] f2.write( count_str + " " + queryTime_str + " " + locksTime_str + " " + rows_str + " " + logonInfo_str + " " + db_str + "\n " + sqltext + "\n") f2.close()def getDB(line): info = line.split(" ") db = info[1][:-1] return dbdef getUserAndHost(line): info_list = line.split(" ") User = info_list[2].split("[")[0] idx = info_list.index("@") hostInfo = info_list[idx + 2] if hostInfo == "[]": Host = "localhost" else: Host = hostInfo[1:-1] return User, Hostdef getExecInfo(line): info_list = line.split(" ") Query_time = info_list[0].split(" ")[2] Lock_time = info_list[1].split(" ")[1] Rows_sent = info_list[1].split(" ")[3] return Query_time, Lock_time, Rows_sentif __name__ == '__main__': filename = str(sys.argv[1]) topN = int(sys.argv[2]) get_sql(filename, topN)
使用:
python slowParse.py slow.log 5 --取top 5
数据
数据库
程序
名称
所在
文件
目录
结果
信息
所属
日志
棘手
代码
内容
功能
可以通过
平台
版本
结构
分组
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
桥梁大师数据库连接失败
招银网络软件开发做啥
ArcMap软件开发公司
学习智能硬件软件开发
win10网络安全组
perl语言软件开发
网络安全 开发语言
软件开发劳务派遣怎么样
山东电力网络安全红队
阿里巴巴网络安全部高管
甘肃企业微服务架构数据库
计算机网络安全实体
腾讯云服务器北京 上海
数据库可重复读取
广州网络安全建设费用
旅游景区的软件开发商
山东栖霞数据库
北屯ibm服务器维保费用
软件开发监理审批意见
山西餐饮软件开发销售价格
一台服务器部署多个java服务
网络安全经济损失
化学服务器
泰兴网络技术市场
中国互联网巨头不搞高科技
CSONLINE下载软件开发
对象型数据库的特点
数据库应满足哪几个方面的要求
数字时代网络安全挑战
删数据库微盟