当前位置: 首页 > news >正文

MySQL 故障排查与生产环境优化

目录

一、前置知识点

MySQL的运行原理

1. 客户端连接

2. SQL 解析与优化

3. 存储引擎处理

4. 日志与持久化

二、MySQL 单实例故障排查

(1)故障现象1

(2)故障现象2

(3)故障现象3

(4)故障现象4

(5)故障现象5

(6)故障现象6

(7)故障现象7

(8)故障现象8

三、MySQL 主从故障排查

(1)故障现象1

(2)故障现象2

(3)故障现象3

四、MySQL 优化

1、硬件方面

(1)关于 CPU

(2)关于内存

(3)关于磁盘

2、MySQL 配置文件

(1)核心功能优化项

(2)查询优化项

(3)日志与监控

(4)InnoDB 高级优化

(5)示例配置(my.cnf)

3、SQL 方面

(1)创建测试表并插入数据

(2)使用 EXPLAIN 进行 SQL 优化的步骤及实验验证

(3)优化步骤:添加索引

(4)优化后查询及 EXPLAIN 分析


一、前置知识点

MySQL的运行原理

1. 客户端连接
  • 客户端通过 TCP/IP 或 Socket 连接到 MySQL 服务端。

  • 连接管理器(Connection Manager)负责管理线程池和用户认证。

2. SQL 解析与优化
  • 解析器:将 SQL 语句解析为语法树,验证语法合法性。

  • 优化器:生成执行计划,选择索引或全表扫描等策略。

3. 存储引擎处理
  • 执行引擎:调用存储引擎(如 InnoDB、MyISAM)执行读写操作。

  • 数据存储

    • InnoDB:数据存储在表空间文件(.ibd)中,支持事务和行级锁。

    • MyISAM:数据存储在 .MYD(数据文件)和 .MYI(索引文件)中,不支持事务。

4. 日志与持久化
  • Redo Log(重做日志):确保事务的持久性,崩溃恢复时重放未提交的事务。

  • Undo Log(回滚日志):支持事务回滚和多版本并发控制(MVCC)。

  • Binlog(二进制日志):记录所有数据变更,用于主从复制和增量备份。

二、MySQL 单实例故障排查

(1)故障现象1

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/data/mysql/mysql.sock' (2)

问题分析:以上这种情况一般都是数据库未启动、mysql 配置文件未指定 socket 文件或者数据库端口被防火墙拦截导致。
解决方法:启动数据库或者防火墙开放数据库监听端口。

(2)故障现象2

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

问题分析:密码不正确或者没有权限访问。
解决方法

修改 my.cnf 主配置文件,在 [mysqld] 下添加 skip - grant - tables=on,重启数据库。最后修改密码命令如下:

Mysql5.7 版本

mysql> update mysql.user set authentication_string=password('123456') where user='root' and Host = 'localhost';
mysql> flush privileges;

Mysql8.0

mysql> UPDATE mysql.user SET authentication_string='' WHERE user='root' AND Host='localhost';
mysql> FLUSH PRIVILEGES;
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';

再删除刚刚添加的 skip-grant-tables 参数,重启数据库,使用新密码即可登录。重新授权,命令如下。

Mysql5.7

mysql>grant all on *.* to 'root'@'mysql-server' identified by '123456';

Mysql8.0

mysql> CREATE USER 'root'@'mysql-server' IDENTIFIED BY '123456';
mysql> GRANT all ON *.* TO 'root'@'mysql-server';

(3)故障现象3

使用远程连接数据库时偶尔会发生远程连接数据库很慢的问题

问题分析:如果MySQL主机查询DNS很慢或有很多客户端连接导致很慢,由于开发机器是不可以连接外网的,在进行MySQL连接时,DNS解析是不可能完成的,从而也就明白了连接那么慢的原因。

解决方法:修改配置文件my.cnf ,在[mysql] 下添加 skip-name-resolve,重启数据库可以解决,注意在以后授权里面不能再使用主机名授权。

(4)故障现象4

Can’t open file: 'xxx_forums.MYI'. (errno: 145)

问题分析:服务器非正常关机,数据库所在空间已满,或一些其他未知原因,对数据库表造成了损坏。可能是系统下直接将数据库文件拷贝,会因为文件的属组问题产生这个错误。

解决方法

1.可以使用两种方式修复数据表

  • 使用 MySQL 自带的专门用户数据表检查和修复工具 myisamchk。一般情况下只有在命令行下面才能运行 myisamchk 命令。常用的修复命令为:
myisamchk -r 数据文件目录/数据表名.MYI;
  • 通过 phpMyAdmin 修复,phpMyAdmin 带有修复数据表的功能,进入到某一个表中后,点击 “操作”,在下方的 “表维护” 中点击 “修复表” 即可。

注意:以上两种修复方式在执行前一定要备份数据库。

  • 修改文件的属组(仅适合独立主机用户):
  • 复制数据库文件的过程中没有将数据库文件设置为 MySQL 运行的帐号可读写(一般适用于 Linux 和 FreeBSD 用户)。

(5)故障现象5

ERROR 1129 (HY000): Host 'xxx.xxx.xxx' is blocked because of many connection erros;
unblock with 'mysqladmin flush-hosts'

问题分析:由于数据库参数:max_connect_errors , 其默认值是10.当大量的主机去连接MySQL ,总连接请求超过了,新的连接就无法连上MySQL。同一个IP在短时间内产生太多中断的数据库连接而导致的阻塞。

解决方法:使用 mysqladmin flush-hosts 命令清除缓存

(6)故障现象6

客户端报 Too many connections.

问题分析:连接数超出MySQL的最大连接数限制

解决方法:1.在 /etc/my.cnf 配置文件增大连接数,然后重启MySQL

                     max_connections = 10000

                    2.临时修改最大连接数,在my.cnf 里修改

                      set GLOBL max_connections = 10000

(7)故障现象7

Warning:World-writable config file '/etc/my.cnf' is ignored
ERROR! MySQL is running but PID file could not be found

问题分析:MySQL 的配置文件/etc/my.cnf 权限不对

解决方法:给它权限  chmod 644 /etc/my.cnf

(8)故障现象8

InnoDB: Error:page 14178 log sequence number 29455369832
InnoDB:is in the future!Current system log sequence number 29455369832f

问题分析: innodb 数据文件损坏。

解决方法:修改 my.cnf 配置文件,在[mysql] 下添加 innodb_force_recovery=4,启动数据库后备份数据文件,然后去掉该参数,利用备份文件恢复数据。

三、MySQL 主从故障排查

(1)故障现象1

从库的 Slave_IO_Running 为 NO
The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).

问题分析:主库和从库的 server-id 值一样。
解决方法:修改从库的 server-id 的值,修改为和主库不一样。修改完后重启,再同步即可。 

(2)故障现象2

从库的 Slave_IO_Running 为 NO

问题分析:造成从库线程为 NO 的原因会有很多,主要原因是主键冲突或者主库删除或更新数据,从库找不到记录,数据被修改导致。通常状态码报错有 1007、1032、1062、1452 等。

解决方法一

mysql> stop slave;
mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
mysql> start slave;

解决方法二
设置用户权限,设置从库只读权限

set global read_only=true;

(3)故障现象3

Error initializing relay log position: I/O error reading the header from the binary log

分析问题:从库的中继日志 relay-bin 损坏。

解决方法:手工修复,重新找到同步的 binlog 和 pos 点,然后重新同步即可。

mysql>CHANGE  MASTER  TO  MASTER_LOG_FILE='mysql-bin.xxx', MASTER_LOG_POS=xxx;

四、MySQL 优化

1、硬件方面

(1)关于 CPU

优化目标

  • 提升并行处理能力,减少 SQL 执行和锁竞争带来的 CPU 瓶颈。

关键策略

  1. 选择多核 CPU

    • MySQL 支持多线程操作(如并行查询、连接处理),多核 CPU 能更好地处理高并发请求。

    • 建议:优先选择主频高、核心数多的 CPU(如 16 核以上)。

  2. 监控 CPU 使用率

    # 查看 CPU 负载  
    top  
    # 检查用户态(us)和内核态(sy)的 CPU 占用  
    vmstat 1  
    • 常见问题

      • us 高:SQL 执行消耗过多 CPU(需优化慢查询)。

      • sy 高:系统内核资源争用(如锁竞争、线程切换)。

  3. 优化锁与并发

    • 减少表锁(MyISAM)或行锁(InnoDB)竞争:

      -- 查看锁等待  
      SHOW ENGINE INNODB STATUS\G  
      -- 查看当前运行事务  
      SELECT * FROM information_schema.INNODB_TRX;  
(2)关于内存

优化目标

  • 最大化利用内存缓存数据,减少磁盘 I/O。

关键策略

  1. 配置 InnoDB 缓冲池

    • innodb_buffer_pool_size 是 InnoDB 引擎的核心参数,用于缓存数据和索引。

    • 建议:设置为系统总内存的 70%~80%(需预留内存给操作系统和其他进程)。

      # my.cnf 示例  
      innodb_buffer_pool_size = 64G  

  2. 优化其他内存区域

    • 连接线程内存

      thread_cache_size = 100      # 缓存线程数  
      max_connections = 1000       # 最大连接数  
    • 排序和临时表内存

      sort_buffer_size = 4M        # 排序缓冲区  
      tmp_table_size = 256M        # 内存临时表大小  
  3. 监控内存使用

    -- 查看 InnoDB 缓冲池命中率  
    SHOW STATUS LIKE 'Innodb_buffer_pool_read%';  
    -- 计算命中率公式:  
    -- (1 - Innodb_buffer_
(3)关于磁盘

优化目标

  • 提升 I/O 吞吐量,降低数据读写延迟。

关键策略

  1. 选择高性能存储设备

    • SSD:比 HDD 快 10 倍以上,尤其适合随机 I/O 密集场景。

    • RAID 配置

      • RAID 10:兼顾性能与冗余,适合 OLTP 场景。

      • RAID 5:适合读多写少的 OLAP 场景。

  2. 分离日志与数据文件

    • 日志文件(binlog、redo log):

      • 写入频繁且顺序写入,建议单独挂载高速 SSD。

    • 数据文件

      • 随机读写较多,使用独立磁盘或 RAID 10。

  3. 优化文件系统与 I/O 调度

    • 文件系统:使用 XFS 或 ext4(启用 noatime 减少元数据写入)。

    • I/O 调度器

      # 查看当前调度策略  
      cat /sys/block/sda/queue/scheduler  
      # 设置为 deadline 或 noop(SSD 推荐)  
      echo 'deadline' > /sys/block/sda/queue/scheduler  
  4. 监控磁盘 I/O

    # 查看磁盘吞吐量和延迟  
    iostat -x 1  
    # 检查 I/O 等待时间  
    top(关注 %wa 指标)  

2、MySQL 配置文件

(1)核心功能优化项
参数作用建议配置注意事项
innodb_buffer_pool_sizeInnoDB 缓冲池大小,缓存数据和索引,直接影响读性能设置为物理内存的 50%~70%(如 64GB 内存配 40G)避免超过物理内存,防止系统交换(Swap)
innodb_log_file_size单个 InnoDB 重做日志文件大小,影响事务提交速度和崩溃恢复时间建议 1G~4G(如 2G)修改需停止 MySQL,删除旧日志文件后重启
innodb_flush_log_at_trx_commit控制事务日志刷新策略,平衡性能与数据安全1(默认,完全持久化);2(折中,每秒刷盘);0(高性能,风险高)高并发写入场景可设为 2,但需容忍最多 1 秒数据丢失
max_connections最大客户端连接数,避免连接耗尽根据业务需求设置,建议 500~2000监控 Threads_connected 和 Threads_running 调整
tmp_table_size、max_heap_table_size内存临时表大小上限,影响复杂查询(如 GROUP BY、JOIN)建议 64M~256M(如 128M),两者值需一致过小会导致磁盘临时表,降低性能;过大可能耗尽内存
(2)查询优化项
参数作用建议配置
query_cache_type查询缓存类型(MySQL 8.0 已移除,旧版本慎用)OFF(默认,高并发下建议关闭)
sort_buffer_size排序操作缓冲区大小2M~8M(如 4M)
join_buffer_sizeJOIN 操作缓冲区大小4M~16M(如 8M,仅对无索引 JOIN 有效)
read_buffer_size顺序读缓冲区大小2M~8M(如 4M)
read_rnd_buffer_size随机读缓冲区大小4M~16M(如 8M)
(3)日志与监控
参数作用建议配置
slow_query_log启用慢查询日志ON
long_query_time定义慢查询阈值(秒),记录执行时间长的 SQL1~2(根据业务容忍度调整)
log_error错误日志路径,用于故障排查指定路径(如 /var/log/mysql/error.log )
binlog_format二进制日志格式(主从复制依赖)ROW(推荐,数据一致性高)
expire_logs_days自动清理旧的二进制日志天数7~14(根据备份策略调整)
(4)InnoDB 高级优化
参数作用建议配置
innodb_io_capacityInnoDB 后台任务的 I/O 能力(如刷新脏页)SSD 建议 2000~4000,HDD 建议 200~400
innodb_flush_method控制数据文件与日志文件的刷新方式O_DIRECT(默认,避免双缓冲)
innodb_thread_concurrencyInnoDB 并发线程数(默认,自适应),高并发场景影响性能可设为 CPU 核数 * 2
innodb_autoinc_lock_mode自增锁模式,影响插入(连续模式,高并发插入性能)2
(5)示例配置(my.cnf)

物理资源 32 核 CPU、64G 内存、500G SSD

[mysqld]
# 核心配置
innodb_buffer_pool_size = 40G
innodb_log_file_size = 2G
innodb_flush_log_at_trx_commit = 2
max_connections = 1000
thread_cache_size = 100
# 查询优化
tmp_table_size = 128M
max_heap_table_size = 128M
sort_buffer_size = 4M
join_buffer_size = 8M
# 日志与监控
slow_query_log = ON
long_query_time = 1
log_error = /var/log/mysql/error.log
binlog_format = ROW
expire_logs_days = 7
# InnoDB 高级
innodb_io_capacity = 2000
innodb_flush_method = O_DIRECT
innodb_thread_concurrency = 0
innodb_autoinc_lock_mode = 2

3、SQL 方面

SQL 优化是保障数据库高效运行的关键,核心是减少 CPU、内存、磁盘 I/O 等资源消耗,提升查询响应。未优化 SQL 在大数据量或高并发时会引发全表扫描等问题,致服务器负载高、响应慢,影响业务。可借助索引优化等手段降低数据库压力,支持业务扩展,控制成本与运维复杂度。

(1)创建测试表并插入数据
-- 创建数据库
Create database test;
-- 使用数据库
Use test;CREATE TABLE users (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL,email VARCHAR(100) NOT NULL,age INT NOT NULL,created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);--插入 10 万条测试数据(使用存储过程生成)
DELIMITER $$
CREATE PROCEDURE insert_users()
BEGINDECLARE i INT DEFAULT 0;WHILE i < 100000 DOINSERT INTO users (name, email, age)VALUES (CONCAT('user', i), CONCAT('user', i, '@example.com'), FLOOR(RAND() * 100));SET i = i + 1;END WHILE;
END$$
DELIMITER ;CALL insert_users();
(2)使用 EXPLAIN 进行 SQL 优化的步骤及实验验证

EXPLAIN 是 MySQL 分析 SQL 执行计划的工具,模拟查询执行输出访问类型、索引使用、扫描行数、额外操作等关键信息,能帮开发者找出全表扫描、索引失效等性能问题,进而从添加索引、改写查询、调整表结构等方面优化,是提升数据库效率的重要诊断工具。

例如:

mysql>EXPLAIN SELECT * FROM users WHERE name = 'user123';

EXPLAIN 用于显示 MySQL 如何执行一条 SQL 语句,关键字段如下:

字段说明优化关注点
id查询序列号,相同 id 为同一执行层,不同 id 按序执行(如查看复杂查询的嵌套层级)-
select_type查询类型(SIMPLE、PRIMARY、SUBQUERY、DERIVED 等)识别子查询或临时表操作
table访问的表名或别名确认查询涉及的表
type访问类型,性能从优到劣:system > const > eq_ref > ref > range > index > ALL避免 ALL(全表扫描),优先优化为 ref 或 range
possible_keys可能使用的索引检查是否有合适索引未被使用
key实际使用的索引确认是否命中最佳索引
rows预估扫描的行数行数越少,查询效率越高
Extra附加信息(如 Using where、Using index、Using temporary 等)发现潜在性能问题(

根据关键字段说明,对 explain SELECT * FROM users WHERE name = 'user123' 的结果分析如下:

  • type=ALL:全表扫描,效率极低。
  • possible_keys=NULL:未命中索引。
  • rows=100000:扫描全部数据。
(3)优化步骤:添加索引
mysql>ALTER TABLE users ADD INDEX idx_name (name);
(4)优化后查询及 EXPLAIN 分析
mysql>EXPLAIN SELECT * FROM users WHERE name = 'user123';

 

优化后结果分析如下:

  • type=ref:索引查找,效率高。
  • key=idx_name:命中新创建的索引。
  • rows=1:仅扫描一行数据。

相关文章:

  • 科技行业智能化升级经典案例—某芯片公司
  • Java 泛型详解
  • VR 互动实训与展示,借科技开启沉浸式体验新篇​
  • 使用excel 工具做数据清洗
  • excel:时间戳格式与日期格式的互转
  • vue2.0 组件之间的数据共享
  • nginx 漏洞修复 CVE-2024-7347 CVE-2025-23419
  • Java实现PDF加水印功能:技术解析与实践指南
  • luckysheet的使用——17.将表格作为pdf下载到本地
  • Node-Red通过Profinet转ModbusTCP采集西门子PLC数据配置案例
  • BGP综合实验(2)
  • 高项-挣值管理TCPI
  • 软件设计师“测试用例”考点分析——求三连
  • ip与mac-数据包传输过程学习
  • 社交平台推出IP关联机制:增强用户体验与网络安全的新举措
  • 紫光同创FPGA实现AD9238数据采集转UDP网络传输,分享PDS工程源码和技术支持和QT上位机
  • 解决报错 Flask-SQLAlchemy TypeError: ‘float‘ object is not callable
  • Linux内核深入学习(4)——内核常见的数据结构之链表
  • WebRTC技术EasyRTC嵌入式音视频通信SDK助力智能电视搭建沉浸式实时音视频交互
  • 正点原子STM32新建工程
  • 总书记回信二周年之际,上海如何将垃圾分类深度融入城市发展?
  • 苏丹港持续遭无人机袭击,外交部:呼吁各方保护民用设施和平民安全
  • 一周观展|一批重量级考古博物馆开馆:从凌家滩看到孙吴大墓
  • 中国田径巡回赛西安站完赛:男子跳远石雨豪夺冠
  • 中科院合肥物质院迎来新一届领导班子:刘建国继续担任院长
  • 打造信息消费新场景、新体验,上海信息消费节开幕