#MySQL# 文章列表 MySQL:简介 Ubuntu 安装 MySQL MySQL:官方文档地址 MySQL:DDL、DQL、DML、DCL的含义 MySQL:Mac 中启动 关闭 MySQL 服务 MySQL:有哪些好用的管理工具? MySQL:命令行工具 mycli MySQL:CHAR类型 MySQL:VARCHAR类型 MySQL:整型数字 MySQL:datetime 类型 MySQL:时间戳 MySQL:创建和删除数据库 MySQL:切换和查看数据库 MySQL:创建和删除表 MySQL:在表中增加、删除、修改列 MySQL:创建和删除主键 MySQL:使用 rename 修改表名 MySQL:修改自增主键id的类型 MySQL:如何创建一个相同的表 MySQL:修改表的字符编码 MySQL:增删查改 MySQL:插入数据 MySQL:插入多行数据 MySQL:使用 insert set 插入数据 MySQL:大小写和反引号 MySQL:字符串类型值的大小写 MySQL:SQL注释 MySQL:不要使用utf8 MySQL:NULL的判等 MySQL:InnoDB存储引擎的限制 MySQL:if和case的使用 MySQL:使用 load data 快速导入数据 MySQL:使用 select into outfile 导出数据 MySQL:查询和设置 sql_mode MySQL:严格模式 MySQL:NOT NULL 字段不插入数据,会发生什么? MySQL:无符号整数列插入负数会发生什么? MySQL:关于 null 的那些事 MySQL:大表行数查询 MySQL:自动生成创建时间、更新时间;自动更新更新时间 MySQL:insert ignore MySQL:字符集排序规则 MySQL:如果连续更新一个字段两次,结果是? MySQL:字符串转数字 MySQL:尾部空格 MySQL:添加和删除索引 MySQL:唯一索引与NULL MySQL:唯一索引的单列长度限制 MySQL:InnoDB 索引 MySQL:字符集排序规则对唯一索引的影响 MySQL:唯一索引冲突消耗主键 ID MySQL 使用 index hint 指定索引:ignore index、force index、use index MySQL:查看客户端连接信息 MySQL:查看表的状态 show table status MySQL:如何治理连接数 ? MySQL:如何监控和处理慢查询与长事务 ? MySQL:自定义函数 MySQL:now() 函数 MySQL:unix_timestamp() 函数 MySQL:from_unixtime() 函数 MySQL:version() 函数 MySQL:current_timestamp() 函数 MySQL:cast 函数 MySQL:convert 函数 MySQL:使用 greatest、least 函数获取行最大值、最小值 MySQL:使用 group_concat 函数连接多行数据为一个字符串 MySQL:获取版本号 MySQL:Java 类型映射 MySQL下创建只能有一行记录的table 关于MySQL的字符集 理解数据库中的undo日志、redo日志、检查点 ubuntu下源码安装MySQL MySQL:JOIN解惑 如何快速更新数据库中的百万条数据

MySQL:如何监控和处理慢查询与长事务 ?


#MySQL#


什么是慢查询、长事务 ?

慢查询 是指一条 SQL 的执行时间太长。比如在一个有100w条数据的表中,查询一条数据时未命中索引,从而通过全表扫描查询数据,这个查询会耗时很长。这就是一个 Long SQL 。类似,更新数据、删除数据也可能出现慢查询 。

长事务,是指事务开启后长时间未结束(commit或者rollback都没执行)。出现长事务的原因有很多,例如:

  • 事务中有一个慢查询;
  • 就是忘记结束事务了;
  • 一个长事务中锁住了一些资源,导致其他需要该资源的事务也变成长事务。

很多情况下,慢查询和长事务,会对业务产生很大的负面影响:

  • 业务响应太慢。
  • 连接数暴涨。

如何发现慢查询 ?

方法1:

使用 show processlist 查看MySQL 线程情况,若有 Command 为 Query ,Time 很大的线程在列表中,那么这个线程就是在执行一个慢查询。Info 字段能看出来对应的 SQL 。

select * from information_schema.processlist 效果和 show processlist 相同。

示例:

mysql> show processlist \G
***************************[ 1. row ]***************************
Id      | 2
User    | root
Host    | localhost:52376
db      | <null>
Command | Query
Time    | 0
State   | init
Info    | show processlist

show processlist 官方文档 

方法2:

开启慢查询日志,实时解析日志内容。

略。

如何处理不可接受的慢查询?

如果慢查询在意料之中,可接受,那么不用处理。否则应该:

  • 干掉此次的慢查询。使用 kill <id> ,id 是 show processlist 返回的 Id 。
  • 优化SQL、索引等,防止再次出现慢查询。

如何发现长事务?

根据 MySQL运维中长事务和锁等待排查 ,可以用下面的 SQL :

select t.*,to_seconds(now())-to_seconds(t.trx_started) idle_time from INFORMATION_SCHEMA.INNODB_TRX t \G

查询结果中,idle_time 过大的事务就是长事务。输出结果中, trx_mysql_thread_id  是对应的线程标识。

如何干掉长事务?

方案1

INFORMATION_SCHEMA.INNODB_TRX 得到的长事务信息中,有对应的线程标识, kill 掉即可。

方案2

设置较小的 wait_timeout 可以干掉部分长事务。 对于业务代码,使用的是非交互模式的连接,可以使用 wait_timeout 设置超时时间。相当于,若某个连接在 wait_timeout 这个时间范围内是空闲的,MySQL 服务器会自动关闭连接。 注意,数据库连接池参数要根据情况调整下。


( 本文完 )