MySQL出现慢查询或者主从延迟的问题,怎么做根因分析?

针对 MySQL 的慢查询和主从延迟问题,进行根因分析可以遵循一套系统化的排查流程。这两个问题虽然表现不同,但根源常常交织在一起。

🐢 慢查询根因分析

慢查询通常是导致数据库整体性能下降和主从延迟的直接原因。排查的核心在于定位分析

1. 定位慢查询

首先,需要开启慢查询日志来捕获执行时间过长的 SQL 语句。

开启慢查询日志:可以通过修改配置文件或动态设置来开启。

sql 复制代码
-- 动态开启慢查询日志(无需重启)
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1; -- 设置阈值为1秒,可根据业务调整
SET GLOBAL log_queries_not_using_indexes = 'ON'; -- 记录未使用索引的查询,非常有用
  • 分析慢查询日志 :原始的慢查询日志可能非常庞大,需要使用工具进行分析。
    • pt-query-digest (推荐) :Percona Toolkit 中的工具,功能强大,能生成详细的分析报告,按总耗时、执行频率等对 SQL 进行排序,快速定位最耗资源的 SQL。

      bash 复制代码
      pt-query-digest /path/to/mysql-slow.log > slow_report.txt
    • mysqldumpslow :MySQL 自带的工具,可以对慢查询日志进行汇总和排序。

      bash 复制代码
      mysqldumpslow -s t -t 10 /path/to/mysql-slow.log 
      # 按平均查询时间排序,取前10条
2. 分析根因

定位到具体的慢 SQL 后,下一步是分析它为什么慢。

  • 使用 EXPLAIN 分析执行计划 :这是最关键的一步。EXPLAIN 可以展示 MySQL 如何执行一条查询,帮助你判断是否存在全表扫描、索引使用不当等问题。

    sql 复制代码
    1EXPLAIN SELECT * FROM orders WHERE user_id = 1001 AND status = 'paid';
    • 关注重点
      • type:连接类型。ALL 表示全表扫描,性能最差;index 表示全索引扫描;range 表示索引范围扫描,是较好的结果。
      • key:实际使用的索引。如果为 NULL,则说明没有使用索引。
      • rows:MySQL 估计需要扫描的行数。数值越大,性能越差。
      • Extra:额外信息。Using filesort(需要额外排序)和 Using temporary(使用了临时表)通常意味着性能瓶颈。
  • 检查锁竞争:慢查询也可能是因为等待锁。可以通过以下命令查看当前的锁等待情况。

    sql 复制代码
    SELECT * FROM information_schema.innodb_lock_waits;

🔗 主从延迟根因分析

主从延迟的本质是从库重放事务的速度跟不上主库生成事务的速度。分析的关键在于判断延迟发生在哪个环节。

1. 确认延迟状态

使用 SHOW SLAVE STATUS\G 命令查看从库的复制状态,重点关注以下指标:

  • Seconds_Behind_Master:最直观的延迟秒数,但不够精确。
  • Master_Log_File / Read_Master_Log_Pos:从库的 I/O 线程已经读取到的主库 Binlog 文件和位置。
  • Relay_Master_Log_File / Exec_Master_Log_Pos:从库的 SQL 线程已经执行完的主库 Binlog 文件和位置。

通过对比 Read_Master_Log_PosExec_Master_Log_Pos,可以判断延迟的瓶颈:

  • 如果两者差距不大,但都落后于主库,问题可能出在网络传输或主库写入压力过大。
  • 如果 Read_Master_Log_Pos 远大于 Exec_Master_Log_Pos,说明 I/O 线程正常,但 SQL 线程执行过慢,这是最常见的情况。
2. 排查延迟根因

当确定是 SQL 线程执行过慢时,可以从以下几个方面深入排查:

排查方向 具体操作与说明
从库负载与资源 1. 检查系统负载 :使用 topiostat -x 1 等命令查看从库的 CPU、I/O 使用率。如果 %util 接近 100%,说明磁盘 I/O 是瓶颈。 2. 检查额外负载:确认从库是否承担了繁重的报表查询或备份任务,挤占了复制线程的资源。
SQL 线程执行情况 1. 检查中继日志堆积SHOW GLOBAL STATUS LIKE 'Relay_log_space'; 如果该值持续增长,说明中继日志在堆积,SQL 线程处理不过来。 2. 查看当前执行的 SQLSHOW PROCESSLIST; 查看 Command 列为 Slave_SQL 的线程正在执行什么 SQL,这通常就是导致延迟的慢查询。
主库写入压力 1. 大事务 :主库上的批量更新/删除、大表 DDL 操作会生成巨大的 Binlog 事件,从库需要很长时间才能重放。 2. 高并发写入:主库写入 QPS 过高,Binlog 生成速度远超从库处理能力。
复制配置 1. 检查并行复制 :执行 SHOW VARIABLES LIKE 'slave_parallel_workers';。如果值为 0 或 1,说明是单线程复制,在 MySQL 5.7+ 版本中应开启并行复制(如设置为 LOGICAL_CLOCK 模式)以提升性能。 2. 检查其他参数 :如 innodb_buffer_pool_size 是否过小,导致缓存命中率低。
相关推荐
曹牧9 小时前
Oracle:前缀匹配之REGEXP_LIKE
数据库·oracle
暴躁小师兄数据学院12 小时前
【AI大数据工程师特训笔记】第05讲:关联查询
数据库·sql·oracle
倔强的石头_12 小时前
《Kingbase护城河》——跨平台环境下的数据库联调实战
数据库
lzhdim12 小时前
SQL 入门 17:MySQL 数据类型:从字符串到 JSON 的全面解析
数据库·sql·mysql·json
骄马之死12 小时前
MySQL-InnoDB 核心原理
mysql
杨云龙UP13 小时前
Oracle RAC / ODA 生产环境指定 PDB 启动 SOP
linux·运维·数据库·oracle
kingwebo'sZone13 小时前
在Cent上安装Mysql 8.0的遇到的问题和解决办法
数据库·mysql·adb
幽络源小助理13 小时前
最新知识付费系统网站源码 PC+H5双端 附安装教程 – 幽络源源码网
大数据·数据库
小白考证进阶中13 小时前
Oracle OCP证书报考&考试全指南
数据库·oracle·oracle ocp·ocp认证·oracle认证·甲骨文认证·oracle ocp题库
Leon-Ning Liu14 小时前
【真实经验分享】 ORA-600 [qesmaGetTblSeg1]
数据库·oracle