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

目录

一: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 高级优化](#4.InnoDB 高级优化)

5.示例配置片段

(3)SQL方面

1.创建测试表并插入数据

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

3.优化步骤:添加索引

4.优化后查询及EXPLAIN分析


一: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: ON)

**问题解析:**密码不正确或者没有权限访问。

解决方法:

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

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

Mysq18.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
Mysq18.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主配置文件,在[mysqld]下添加skip-name-resolve,重启数据库可以解决。注意在以后授权里面不能在使用主机名授权。

(4)故障现象4

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

问题解析:

> 服务器非正常关机,数据库所在空间已满,或一些其他未知的原因,对数据库表造成了损坏。

> 可能是操作系统下直接将数据库文件拷贝移动,会因为文件的属组问题而产生这个错误。

解决方法:

> 可以使用下面的两种方式修复时间表(第一种方法仅适合独立主机用户)

· 使用MySQL自带的专门用户设计表检查和修复工具 myisamchk。一般情况下只有在命令行下面才能运行myisamchk命令。常用的修复命令为:

myisamchk -r 数据文件目录/数据表名.MYI;

· 通过 phpMyAdmin修复,phpMyAdmin带有修复数据表的功能,进入到某一个表中后,点击"操作",在下方的"表维护"中点击"修复表"即可。

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

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

(5)故障现象5

ERROR 1129 (HY000) : Host 'xxx.xxx.xxx.xxx' is blockeed because of many
connection errors;
unblock with 'mysqladmin flush-hosts'
**问题分析:**由于mysql数据库的参数:max_connect_errors,其其默认值是10当大量(max_connect_errors)的主机去连接 MySQL,总连接请求超过了10次新的连接就再也无法连接上MySQL服务。同一个ip在短时间内产生太多中断的数据库连接而导致的阻塞(超过mysql数据库max_connection_errors的最大值)。

解决方法:

> 使用mysqladminflush-hosts命令清除缓存,命令执行方法去如下

mysqladmin -uroot -p -h 192.168.241.48 flush-hostS

Enter password:

> 修改mysql配置文件,在[mysqld]下面添加max_connect_erreors=1000,然后重启MySQL。

(6)故障现象6

客户端报Toomany connections。

问题分析: 连接数超出Mysql的最大连接数限制。
解决方法:

> 在my.cnf配置文件里面增大连接数,然后重启MySQL服务

max_connections = 10000

> 临时修改最大连接数,重启后不生效。需要在my.cnf里面修改配置文件,下次重启生效。

set GLOBAL 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 /et/my.cnf

(8)故障现象8

InnoDB: Error: page 14178 log sequence number 29455369832
InnoDB: is in the future! Current system log sequence number 29455369832
问题分析: innodb数据文件损坏。
**解决方法:**修my.cnf配置文件,在[mysqld]下添加 innodb_force_recovery=4,启动数据库后备份数据文件,然后去掉该参数,利用备份文件恢复数据。

二:MySQL主从故障排查

(1)故障现象1

从库的Slave_I0_Running为NO

The slave I/0 thread stops because master and slave have equal MySQL serverids; 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_I0_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/0 error reading the header from the binary log
分析问题: 从库的中继日志relay-bin损坏。
解决方法: 手工修复,重新找到同步的binlog和pos点,然后重新同步即可

mysql>CHAN GEMASTER TO MASTER_LOG_FILE=' mysql-bin. xx' , MASTER_LOG_POS=xxx;

三:MySQL优化

(1)硬件方面

1.关于cpu

CPU对于MySQL应用,推荐使用S.M.P.架构的多路对称CPU。例如:可以使用两颗IntelXeon3.6GHz的CPU。现在比较推荐用4U的服务器来专门做数据库服务器,不仅仅是针对于MySQL。

2.关于内存

物理内存对于一台使用MySQL的DatabaseServer来说,服务器内存建议不要小于2GB,推荐使用4GB以上的物理内存。不过内存对于现在的服务器而言可以说是一个可以忽略的问题,工作中遇到了高端服务器基本上内存都超过了32G。

3.关于磁盘

磁盘寻道能力(磁盘I/0)。以目前市场上普遍高转速SAS硬盘(15000转/秒)为例,这种硬盘理论上每秒寻道15000次,这是物理特性决定的,没有办法改变。MySQL每秒钟都在进行大量、复杂的查询操作,对磁盘的读写量可想而知。所以通常认为磁盘I/0是制约MySQL性能的最大团因素之一,通常是使用RAID-0+1磁盘阵列,注意不要尝试使用RAID-5,MySQL在ERAID-5磁盘阵列上的效率并不高。如果不考虑硬件的投入成本,也可以考虑固态(SSD)硬盘专门作为数据库服务器使用。数据库的读写性能肯定会提高很多。

(2)MySQL配置文件

1.核心性能优化项

|------------------------------------|-------------------------------|------------------------------------------|--------------------------------------|
| 参数 | 作用 | 建议配置 | 注意事项 |
| innodb_buffer_pool_size | 存储索引和数据的内存区域,对 InnoDB 表性能影响极大 | 物理内存的 50%-75%(大内存服务器建议更高比例) | 需缓慢调整,防止 swap 出现 |
| innodb_log_file_size | 单个 redo 日志文件大小,影响事务写入性能 | 1GB-2GB(根据写入负载调整,大事务场景建议更大值) | 调整需重建日志文件(需重启); |
| innodb_flush_log_at_trx_commit | 控制事务提交时日志写入策略(影响 ACID 中的 D) | 1(默认,强持久化但有 IO 开销) | 对写入密集型系统,设为 2 可显著提升性能,但需权衡数据安全性 |
| max_connections | 最大允许的客户端连接数 | 根据应用需求调整,建议不超过 1000(需结合 wait_timeout 参数) | 过高会导致内存耗尽;需监控 Threads_connected 状态变量 |
| tmp_table_size | 内存临时表的最大大小 | 64M-256M(根据查询复杂度调整) | 过大可能导致内存溢出;临时表超过此值会转为磁盘表(性能显著下降 |
| max_heap_table_size | 内存表的最大大小 | 与 tmp_table_size 保持一致 | 需防止应用创建过大的 MEMORY 表 |

2.查询优化项

|----------------------|---------------------------|----------------------------|
| 参数 | 作用 | 建议配置 |
| query_cache_type | 查询缓存类型(MySQL8.0已移除,旧版本慎用) | OFF(默认,高并发下建议关闭)。 |
| sort_buffer_size | 排序操作缓冲区大小。 | 2M~8M,过大浪费内存 (如4M)。 |
| join_buffer_size | JOIN操作缓冲区大小。 | 4M~16M,仅对无索引 JOIN有效(如8M)。 |
| read_buffer_size | 顺序读缓冲区大小。 | 2M 8M(如4M) |
| read_rnd_buffer_size | 随机读缓冲区大小。 | 4M16M(如 8M)。 |

3.日志与监控

|------------------|----------------------|-----------------------------------|
| 参数 | 作用 | 建议配置 |
| slow_query_log | 启用慢查询日志,记录执行时间长的SQL。 | ON |
| long_query_time | 定义慢查询阈值(秒)。 | 1~2(根据业务容忍度调整) |
| log_error | 错误日志路径,用指于故障排查。 | 用指定路径 (如/var/10g/mysql/error.log) |
| binlog_format | 二进制日志格式(主从复制依赖)。 | ROW(推荐,数据一致性高) |
| expire_logs_days | 自动清理旧的二进制日志天数。 | 7~14(根据备份策略调整) |

4.InnoDB 高级优化

|---------------------------|----------------------------|-------------------------------|
| 参数 | 作用 | 建议配置 |
| innodb_io_capacity | InnoDB 后台任务的 I/0能力(如刷新脏页)。 | SSD建以2000~4000 HDD建议200·400。 |
| innodb_flush_method | 控制数据文件与日志 文件的刷新方式。 | 0_DIRECT(默认,避免双缓冲)。 |
| innodb_thread_concurrency | InnoDB并发线程数 限制。 | 0(默认,自适应),高并发场景可设为 CPU核数*2。 |
| innodb_autoinc_lock_mode | 自增锁模式,影响插入性能。 | 2(连续模式,高并发插入推 荐)。 |

5.示例配置片段

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

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/0)来提升查询响应速度,避免慢查询导致用户体验下降或系统崩溃。未优化的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()

BEGIN

DECLARE i INT DEFAULT 0;

WHILE i < 100000 DO

INSERT 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执行计划的工具,通过模拟查询执行过程输出关键信息(如访问类型 type、使用索引 key、预估扫描行数 rows、额外操作 Extra等),帮助开发者识别全表扫描、索引失效等性能瓶颈,从而指导优化方向(如添加索引、改写查询或调整表结构),是提升数据库效率不可或缺的诊断手段。

3.优化步骤:添加索引

mysql>ALTER TABLE users ADD INDEX idx_name (name);

4.优化后查询及EXPLAIN分析

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

相关推荐
日日行不惧千万里2 小时前
数据库故障排查指南
网络·数据库·oracle
神秘敲码人2 小时前
Django基础(二)Django 项目基础操作
数据库·笔记·django
程序员Bears2 小时前
电商后台管理系统:Django Admin深度定制实战指南
数据库·django·sqlite
TDengine (老段)2 小时前
TDengine 2025年产品路线图
大数据·数据库·动态规划·时序数据库·tdengine·涛思数据
朝新_2 小时前
【MySQL】第七弹——复习总结 & 视图
mysql
Aurora_NeAr2 小时前
Redis设计与实现——分布式Redis
数据库·redis·分布式
bst@微胖子2 小时前
DeepSeek提示工程Prompt Engineering
java·数据库·prompt
xuyin12044 小时前
SQLite基础及优化
数据库·sqlite
Faith_xzc4 小时前
MySQL 迁移至 Doris 最佳实践方案
数据库·mysql·adb
ikun·4 小时前
MySQL高可用
数据库·mysql