重写慢日志解析程序,实现打印慢SQL信息及其所属数据库
发表于:2024-12-03 作者:千家信息网编辑
千家信息网最后更新 2024年12月03日,分组自研的审计平台最近推出慢SQL优化的功能,topN慢SQL可以通过mysqldumpslow拿到,但由于mysqldumpslow输出的信息不包含数据库,这让程序后续的自动优化变得有些棘手。在观察
千家信息网最后更新 2024年12月03日重写慢日志解析程序,实现打印慢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安全错误
数据库的锁怎样保障安全
北京天盈九州网络技术有限公司
党支部监督网络安全
先锋机器人软件开发包
2019网络安全周天津
家庭教育网络安全课
有服务器和域名怎么创建网页
织梦数据库调用文件
什么人学网络安全最好
网信办的网络安全职责
在网络安全中中断指
计算机网络技术怎么能学好
软件开发销售收入
为家人写网络安全书信
阿里云linux服务器购买价格
数据库压缩后可用空间变小
什么是控制网络技术
林芝博客网站怎么设计数据库
c 多线程 数据库
安卓studio怎么查找数据库
javafx软件开发
服务器多台管理
更改dns服务器安全吗
网络技术服务规范
专业型软件开发报价表
高校网络安全评估报告
大学计算机专业有网络安全吗
遵化品质软件开发
数据库原理真题
电脑怎么退出网络安全模式
数据库更新数据并保留原数据