一次MySQL慢查询导致的故障

 更新时间:2015年08月12日 08:53:20   作者:Robin Wen  
这篇文章主要介绍了如何对MySQL慢查询导致的故障进行处理,慢查询是我们在mysql中经常需要使用到的一个很方便的功能,慢查询对于跟踪有问题的查询很有用,需要的朋友可以参考下

我们知道分析MySQL语句查询性能的方法除了使用EXPLAIN 输出执行计划,还可以让MySQL记录下查询超过指定时间的语句,我们将超过指定时间的SQL语句查询称为“慢查询”。

一、 起因
研发反应某台数据库僵死,后面的会话要么连接不上,要么要花费大量的时间返回结果,哪怕是一个简单的查询。

二、 处理
首先去监控平台查看服务器以及数据库状态,发现这台数据库有大量的慢查询。继续看服务器监控,CPU 平均使用率较高,IO 读写平均值正常。登录到 MySQL,使用 SHOW PROCESSLIST 查看会话状态,总数居然有 600+,这是很不正常的。查看慢查询日志,发现出问题的 SQL 主要集中在几个,有 SUM、有 COUNT、有等值操作等等。这台 MySQL 服务器的 long_query_time 设置为 3秒,而一个简单的查询却要几十秒,这显然是有问题的。写脚本试着 kill 掉相关的会话,发现于事无补,仍然有大量的连接进来。此时使用 top 查看服务器状态,mysqld 进程占用内存和 CPU 居高不下。

故障期间的慢查询数,如图:

CPU 平均使用率,如图:

接着使用 SHOW FULL PROCESSLIST 查看完整状态,在最上面居然发现几条 SQL。这些 SQL 操作使用子查询实现,TIME 列居然达到了 30000 秒,折算过来差不多 10 小时。EXPLAIN 这些语句,居然出现了 USING TEMPORY 和 USING FILESORT,可以看出这些语句是很糟糕的。于是跟开发确认,紧急把这些会话 kill 掉。稍等片刻,会话数立马降下来,只有 100+,top 查看 mysqld 进程,内存和 CPU 都呈现下降的趋势。接着分析开发说上午 9 时写了这些 SQL,发现有问题,注释掉了。新的代码虽然没有此类 SQL,但之前建立的连接并不会释放。解决问题和出现问题的时间差刚好可以和添加子查询的时间对应,就可以确认子查询是此次故障的罪魁祸首。

三、 总结
通过这个故障,总结如下几点:

  • MySQL 应该尽量避免使用子查询,即使使用,也要搞清楚大表和小表的关系;
  • 出现这类问题的排查步骤

第一,查看服务器监控和 MySQL 监控,分析服务器以及 MySQL 性能,找出异常;
第二,如果是慢查询导致,查看慢查询日志,找出出现问题的 SQL,试着优化,或者把结果缓存;
第三,分清主次,先解决大块问题,后解决细小问题。 把大块的异常解决,小问题就迎刃而解了。比如本文中的例子,把耗费时间长的会话 kill 掉后,后面的连接就正常了;
第四,总结分析。

  • 高效的沟通会事半功倍;
  • DBA 需要定期给出 Top N SQL(类 Oracle 的说法),提供给开发,并协助优化;
  • 查看监控时,不管是服务器监控还是 MySQL 监控,需要做对比,比如和昨天甚至前天的同一时间对比,这会更加快速地定位问题。

四、 技巧
最后,附上一个快速kill 掉 MySQL 会话的方法:

首先使用如下语句分析出有问题的 SQL:

/usr/local/mysql/bin/mysql -uroot -p'XXX' \ -e "SHOW FULL PROCESSLIST;" | more

然后将 SHOW FULL PROCESSLIST 的结果保存到一个文件:

/usr/local/mysql/bin/mysql -uroot -p'XXX' \
-e "SHOW FULL PROCESSLIST;" | \
grep "XXX" | awk '{print $1}' > mysql_slow.txt

最后使用如下简单的 Shell 脚本 kill 掉相关会话:

SELECT concat('kill ',id,';')
FROM information_schema.processlist
WHERE info like 'XXX';

当然也可以使用如下 SQL 拼接 kill 语句:

SELECT concat('kill ',id,';')
FROM information_schema.processlist
WHERE info like 'XXX';

本文对MySQL慢查询导致故障的起因,处理方法,所需的技巧进行了全面分析,希望可以让大家更好的了解MySQL慢查询,对大家的。

相关文章

  • 高效数据流转:Mycat分库分表与GreatSQL实时同步

    高效数据流转:Mycat分库分表与GreatSQL实时同步

    聚焦数据库扩容与实时数据同步,探索MyCat分库分表与GreatSQL的强大结合!想在大规模数据处理中游刃有余?本指南将带你轻松掌握MyCat的分布式解决方案和GreatSQL的实时同步机制,让高效、稳定的数据库管理触手可及,一起揭开高并发环境下数据库优化的神秘面纱吧!
    2024-01-01
  • MySQL 如何查询当前最新事务ID

    MySQL 如何查询当前最新事务ID

    这篇文章主要介绍了MySQL 如何查询当前最新事务ID,帮助大家更好的理解和学习MySQL,感兴趣的朋友可以了解下
    2020-08-08
  • MySQL数据库维护中监控所用到的常用命令

    MySQL数据库维护中监控所用到的常用命令

    这篇文章主要介绍额MySQL监控时常用的的几个MySQL命令,需要的朋友可以收藏下
    2013-08-08
  • 阿里云云服务器mysql密码找回的方法

    阿里云云服务器mysql密码找回的方法

    这篇文章主要介绍了阿里云云服务器mysql密码找回的方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-07-07
  • mysql VARCHAR的最大长度到底是多少

    mysql VARCHAR的最大长度到底是多少

    今天群里有人问varchar 不是最大应该只可以设置65532(第一个字节+两个长度字节)吗 ,但是为什么可以设置成65533
    2012-10-10
  • rpm -ivh方式安装mysql并修改数据存储位置的实现

    rpm -ivh方式安装mysql并修改数据存储位置的实现

    在Linux环境下进行MySQL的安装可以使用不同的方式,但在本文中我们将关注一种特定的方式,即通过RPM包的方式进行安装,本文主要介绍了rpm -ivh方式安装mysql并修改数据存储位置的实现,感兴趣的可以了解一下
    2023-09-09
  • mysql居然还能实现分布式锁的方法

    mysql居然还能实现分布式锁的方法

    这篇文章主要介绍了mysql居然还能实现分布式锁的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • MySQL 数据库的基础知识

    MySQL 数据库的基础知识

    这篇文章主要介绍了MySQL 数据库的基础知识,它是一类更具体的可以管理数据的软件。但是实现数据库的这个软件,需要用到很多的数据结构,下面来看看文章是怎么具体介绍这个数据库的
    2021-12-12
  • MySQL和Oracle批量插入SQL的通用写法示例

    MySQL和Oracle批量插入SQL的通用写法示例

    当我们要往数据库中批量保存多条数据得时候,分不同数据库,有不同得插入方式,这篇文章主要给大家介绍了关于MySQL和Oracle批量插入SQL的通用写法的相关资料,需要的朋友可以参考下
    2021-11-11
  • 使用JS+HTML/CSS实现虚拟滚动和分页加载效果

    使用JS+HTML/CSS实现虚拟滚动和分页加载效果

    虚拟滚动和分页加载是一种优化大型数据集的常见技术,用于在Web应用程序中提高性能和用户体验,在本文中,我将演示如何使用JavaScript和HTML/CSS来实现虚拟滚动和分页加载,同时提供示例代码和详细解释,需要的朋友可以参考下
    2023-10-10

最新评论