mysql慢sql监控
1、思路
之前用 mysql 一直没有考虑到这点,mysql 慢 sql 监控是很重要的,它能帮我们梳理我们的业务 sql 到底是哪里处了问题,那么慢 sql 监控怎么做呢?
有两种思路来实现:
在应用层做
比如我们的系统使用 mybatis,则可以使用 mybatis 的拦截器,在想要监控的 sql 前后进行即时,超时后打 error 日志。如果日志接入日志平台,那么日志平台可以配置报警邮件,直接发邮件提醒开发。
在 mysql 层做
mysql 开启慢日志,记录慢查询 sql。可以读取慢查询日志,分析哪些 sql 属于慢查询,然后发邮件提醒等。这等于做了一个慢 sql 预警系统,一般大公司都会有这样的一套系统(https://github.com/wxisme/slowsql-monitor 类似于这种)。
开启 mysql 慢查询日志的方法如下(https://github.com/wxisme/slowsql-monitor 可以参照这个工程):
--1.First configure the MySQL slow query log,you need to log in to the mysql client. Turn on MySQL slow query log switch:
show variables like 'slow_query_log';
set global slow_query_log='ON';
--2.Set the long query time in seconds:
show variables like 'long_query_time';
set global long_query_time=1;
--3.Set the log queries not using indexes:
show variables like 'log_queries_not_using_indexes';
set global log_queries_not_using_indexes='ON';
--4.show slow log location:
show variables like 'slow_query_log_file';
mysql 的 slowlog 的内容如下:
/usr/local/mysql/bin/mysqld, Version: 5.7.28-log (MySQL Community Server (GPL)). started with:
Tcp port: 3306 Unix socket: /tmp/mysql.sock
Time Id Command Argument
# Time: 2021-04-10T07:22:09.260226Z
# User@Host: root[root] @ localhost [127.0.0.1] Id: 7405
# Query_time: 0.247682 Lock_time: 0.025775 Rows_sent: 103 Rows_examined: 103
use deepwise;
SET timestamp=1618039329;
/* ApplicationName=DataGrip 2018.3.1 */ SELECT t.* FROM deepwise.DW_AI_RESULT t
LIMIT 501;
# Time: 2021-04-10T07:22:37.999494Z
# User@Host: root[root] @ localhost [127.0.0.1] Id: 7406
# Query_time: 0.018695 Lock_time: 0.017633 Rows_sent: 0 Rows_examined: 0
SET timestamp=1618039357;
/* ApplicationName=DataGrip 2018.3.1 */ SELECT t.* FROM deepwise.dw_ai_result_process t
LIMIT 501;
# Time: 2021-04-10T07:23:04.504722Z
# User@Host: root[root] @ localhost [127.0.0.1] Id: 7404
# Query_time: 0.008424 Lock_time: 0.002104 Rows_sent: 0 Rows_examined: 103
SET timestamp=1618039384;
/* ApplicationName=DataGrip 2018.3.1 */ select * from DW_AI_RESULT where PATIENT_ID like '%4468%';
剩下的就是解析这个 log 日志,然后把数据给前端进行页面渲染什么的。
其他用法:
https://zhuanlan.zhihu.com/p/565812229
mybatis 拦截器方案
package com.best.ecboss.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.BeanUtils;
import java.beans.PropertyDescriptor;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
@Intercepts(
@Signature(type = Executor.class, method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
)
public class QueryDaoMybatisInterceptor implements Interceptor {
private final Log logger = LogFactory.getLog(QueryDaoMybatisInterceptor.class);
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs(); //方法参数
Date begin = new Date();
Object ret = invocation.proceed();
Date end = new Date();
try {
MappedStatement mappedStatement = (MappedStatement) args[0];
// 方法参数
Object params = args[1];
// mapper 中的方法名称,如 “com.xushu.mysql.slowsql.dao.AccountMapper.selectList”
String mapperId = mappedStatement.getId();
// 获取 sql 语句,并格式化 sql,将很多空格替换成一个空格
String sql = formatSql(mappedStatement.getBoundSql(params).getSql());
log(mapperId, sql, params, begin, end);
} catch (Exception e) {
}
return ret;
}
private String formatSql(String sql) {
return sql.replaceAll("\\s+", " ");
}
private void log(String statementId, String sql, Object params, Date begin, Date end) {
// 这边可以记录自己想要的查询方法,比如 “selectList”
if (statementId == null || !statementId.contains(".selectList")) {
return;
}
long ms = end.getTime() - begin.getTime();
String paramStr = parseParams(params);
if (ms > 10000) {
logger.error("ms:[" + ms + "],sql:" + sql + ",param:[" + paramStr + "]");
} else if (ms > 1000) {
logger.warn("ms:[" + ms + "],sql:" + sql + ",param:[" + paramStr + "]");
} else {
logger.info("ms:[" + ms + "],sql:" + sql + ",param:[" + paramStr + "]");
}
}
// 格式化传参
private String parseParams(Object params) {
StringBuilder sb = new StringBuilder();
try {
if (params instanceof Map) {
Map map = (Map) params;
map.forEach((k, v) -> {
sb.append(",").append(k).append(":").append(v);
});
} else if (BeanUtils.isSimpleProperty(params.getClass())) {
sb.append(",").append(params.getClass().getSimpleName()).append(":").append(params).append(",");
} else {
// 反射getter属性
PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(params.getClass());
for (PropertyDescriptor pd : pds) {
if (pd.getReadMethod() != null && !"class".equals(pd.getName())) {
String name = pd.getName();
Object value = null;
value = pd.getReadMethod().invoke(params);
sb.append(",").append(name).append(":").append(value);
}
}
}
} catch (Exception e) {
}
if (sb.length() > 0) {
return sb.toString().substring(1);
}
return "";
}
@Override
public Object plugin(Object o) {
return Plugin.wrap(o, this);
}
@Override
public void setProperties(Properties properties) {
}
}
作者:放开那个BUG
链接:https://www.jianshu.com/p/24a42bcd6ef8
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
mysql慢sql监控的更多相关文章
- SQL监控:mysql及mssql数据库SQL执行过程监控审计
转载 Seay_法师 最近生活有很大的一个变动,所以博客也搁置了很长一段时间没写,好像写博客已经成了习惯,搁置一段时间就有那么点危机感,心里总觉得不自在.所以从今天起还是要继续拾起墨笔(键盘),继续好 ...
- MySQL性能、监控与灾难恢复
原文:MySQL性能.监控与灾难恢复 监控方案: up.time http://www.uptimesoftware.com/ 收费 Cacti http:/ ...
- MySQL常用SQL整理
MySQL常用SQL整理 一.DDL #创建数据库 CREATE DATABASE IF NOT EXISTS product DEFAULT CHARSET utf8 COLLATE utf8_ge ...
- mysql优化sql语句
mysql优化sql语句 常见误区 www.2cto.com 误区1: count(1)和count(primary_key) 优于 count(*) 很多人为了统计记录条数,就使 ...
- SpringBoot之使用Druid连接池,SQL监控和spring监控
项目结构 1.引入maven依赖 <dependencies> <dependency> <groupId>org.springframework.boot< ...
- (二十二)SpringBoot之使用Druid连接池以及SQL监控和spring监控
一.引入maven依赖 <dependencies> <dependency> <groupId>org.springframework.boot</grou ...
- 【0.2】【MySQL】常用监控指标及监控方法(转)
[MySQL]常用监控指标及监控方法 转自:https://www.cnblogs.com/wwcom123/p/10759494.html 对之前生产中使用过的MySQL数据库监控指标做个小结. ...
- SpringBoot之使用Druid连接池以及SQL监控和spring监控
一.引入maven依赖 <dependencies> <dependency> <groupId>org.springframework.boot</grou ...
- 小麦苗数据库巡检脚本,支持Oracle、MySQL、SQL Server和PG等数据库
目录 一.巡检脚本简介 二.巡检脚本特点 三.巡检结果展示 1.Oracle数据库 2.MySQL数据库 3.SQL Server数据库 4.PG数据库 5.OS信息 四.脚本运行方式 1.Oracl ...
- 阿里云sql监控配置-druid
今天我们说说数据源和数据库连接池,熟悉java开发的同仁应该都了解C3PO,在这里不做过多的赘述了,今天我们说的是阿里DRUID,druid是后起之秀,因为它的优秀很快占领了使用市场,下边我们一起来看 ...
随机推荐
- 我做的FFmpeg开源C#封装库Sdcb.FFmpeg
我做的FFmpeg开源C#封装库Sdcb.FFmpeg 写在前面: 该主题为2022年12月份.NET Conf China 2022我的主题,项目地址:https://github.com/sdcb ...
- Java第三讲动手动脑
1 以上代码无法通过编译主要是由于在Foo类中自定义了有参的构造函数,系统不在提供默认的构造函数(无参),而在上述的引用中并没有提供参数导致无法通过编译. 2. 运行结果 由运行结果分析可知,在运行时 ...
- 模拟浏览器与服务器交互(简易TomCat框架)
模拟浏览器发送请求到服务器获取资源的思想和代码实现 浏览器发送请求到服务器获取资源的流程和概念 日常我们使用的浏览器,底层都是帮我们做了很多事情,我们只需要用,比如输入www.baidu.com,就可 ...
- 动手写了个简单版的ChatGPT的Java版客户端
最近ChatGpt大火,我在年前申请过账号忘了下确实强大. 作为Java程序猿社畜就尝试写了个Java版本的简易版客户端. 源码地址:https://github.com/Grt1228/chatgp ...
- MySQL联合索引的创建规则
1.索引应该按照最常用于查询的列的顺序创建.这样可以最大程度地提高查询性能. 2.如果查询中包含的列与索引中的列顺序不一致,则无法使用索引.因此,如果您有多个查询,每个查询都包含不同的列,那么最好为每 ...
- Java学习笔记(三)java方法
学习笔记3 Java方法 一.什么是方法 System.out.println() 是什么 System是一个类,out是一个对象,println()就是一个方法 意思是调用System中的out对象 ...
- Qt控制台输出显示乱码
Qt控制台输出显示乱码 https://jingyan.baidu.com/article/ab69b2709aab0b2ca7189f3d.html
- risv RV32I寄存器全称
- 通过url跳转到页面锚点
在需要跳到的页面加: function GetQueryString(name) { var reg = new RegExp("(^|&)" + name ...
- PHP 发送application/json POST请求
PHP用CURL发送Content-type为application/json的POST请求方法 function json_post($url, $data = NULL) { $curl = cu ...