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 是否过小,导致缓存命中率低。
相关推荐
辞旧 lekkk3 小时前
【Qt】信号和槽
linux·开发语言·数据库·qt·学习·mysql·萌新
2301_809204704 小时前
JavaScript中严格模式use-strict对引擎解析的辅助.txt
jvm·数据库·python
zjy277774 小时前
mysql如何选择合适的索引类型_mysql索引设计实战
jvm·数据库·python
笨蛋不要掉眼泪5 小时前
Mysql架构揭秘:update语句的执行流程
数据库·mysql·架构
万邦科技Lafite5 小时前
京东item_get接口实战案例:实时商品价格监控全流程解析
java·开发语言·数据库·python·开放api·淘宝开放平台
秋96 小时前
ruoyi项目更换为mysql9.7.0数据库
数据库
Andya_net6 小时前
MySQL | MySQL 8.0 权限管理实践-精确赋予库、表只读等权限
android·数据库·mysql
筑梦之路7 小时前
harbor数据库报错权限异常如何处理——筑梦之路
数据库·harbor
czlczl200209258 小时前
理解 MySQL 行锁:两阶段锁协议与热点更新优化
数据库·mysql
AllData公司负责人8 小时前
通过Postgresql同步到Doris,全视角演示AllData数据中台核心功能效果,涵盖:数据入湖仓,数据同步,数据处理,数据服务,BI可视化驾驶舱
java·大数据·数据库·数据仓库·人工智能·python·postgresql