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

目录

mysql单实例故障排查

mysql主从故障排查

mysql优化

硬件方面

mysql配置文件

核心性能优化项

查询优化项

日志与监控

Innodb高级优化

[配置片段(my.cnf)](#配置片段(my.cnf))

sql方面

[使用EXPLAIN 进行sql优化的步骤及实验验证](#使用EXPLAIN 进行sql优化的步骤及实验验证)

优化步骤,添加索引

优化后查询及EXPLAIN分析


mysql单实例故障排查

故障现象1

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

问题分析:以上这种情况一般都是数据库未启动、mysql配置文件未指定socket

文件或者数据库端口被防火墙拦截导致

解决方法:启动数据库或者防火墙开放数据库监听端口。

故障现象2

复制代码
ERROR 1045 (28000) : Access denied for user root' @' localhost (usingpassword: NO)

解决方法

修改my.cnf主配置文件,在[mysqld]下添加skipo-grant-tables=on,重启

数据库。最后修改密码命令如下。

复制代码
mysql> UPDATE mysql.user SET authenticationstring='WHERE user='root'
AND Host='localhost';
mysql> FLUSH PRIVILEGES;
mysql> ALTER USER'root'@'localhost' IDENTIFIED BY '123456';

再删除刚刚添加的skip-grant-tables参数,重启数据库库,使用新密码即

可登录。重新授权,命令如下。

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

故障现象3

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

问题分析:如果MySQL主机查询DNS很慢或是有很多客户端主机时会导致连接

很慢.由于开发机器是不能够连接外网的,在进行MySQL连接时,DNS解析是

不可能完成的,从而也就明白了为什么连接那么慢了。

解决方法:修改my.cnf主配置文件,在[mysqld]下添加skip-namie-resolve,

重启数据库可以解决。注意在以后授权里面不能再使用主机名授权。

故障现象4

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

问题分析:

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

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

解决方法:可以使用下面的两种方式修复数据表(第一种方法仅适合独立立主机用户):

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

故障现象5

复制代码
ERROR 1129 (HY000) : Host 'xxx.xxx.xxx.xxx' is blocked 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_error的最大

值)。

解决方法

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

复制代码
mysqladmin -uroot -p -h 192.168.241.48 flush-hostsS
Enter password:

修改mysql配置文件,在[mysqld]下面添加max_connect_errors=1000,

然后重启MySQL。

故障现象6

客户端报Toomany connections。

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

解决方法:

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

复制代码
max_connections =10000

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

下次重启生效。

复制代码
set GLOBAL max_connections=10000;

故障现象7

Warning: World-writable config file '/etc/my.cnf' is isgnored

ERROR! MySQL is running but PID file could not befound

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

解决方法

复制代码
chmod 644 my.cnf

故障现象8

InnoDB: Error: page 14178 log sequence number 29455369832

InnoDB: is in the future! Current system log sequence number 29455369832

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

解决方法:修my.cnf配置文件,在[mysqld]下添加 innodl_force_recovery=4,

启动数据库后备份数据文件,然后去掉该参数,利用备份文件恢复数据。

mysql主从故障排查

故障现象1

从库的Slave_I0_Running为NO

The slave I/0 thread stops because master and slave equal MySQL server

ids; these ids must be different for replication to work (or the

--replicate-same-server-id option must be used on slavebut this does not

always make sense; please check the manual before using it).

问题分析:主库和从库的server-id值一样。

解决方法:修改从库的server-id的值,修改为和主库不一样。修已改完后重启,

再同步即可。

故障现象2

从库的Slave_I0_Running为NO

问题分析:造成从库线程为NO的原因会有很多,主要原因是是主键冲突或者主库

删除或更新数据,从库找不到记录,数据被修改导致。通常状态码报错有1007、

1032、1062、1452

解决方法一

复制代码
mysql> stop slave;
mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
mysql> start slave;

解决犯法二

设置用户权限,设置从库只读权限

复制代码
global read_only=true;

Error initializing relay log position: I/0 error readinag 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优化

硬件方面

说到服务器硬件,最主要的无非CPU、内存、磁盘三大关键因素。

关于CPU

CPU对于MySQL应用,推荐使用S.M.P.架构的多路对称CPU。例如:可以

使用两颗IntelXeon3.6GHz的CPU。现在比较推荐用4U的服务器来专门做

数据库服务器,不仅仅是针对于MySQL。

关于内存

物理内存对于一台使用MySQL的DatabaseServer来说,月服务器内存建议

不要小于2GB,推荐使用4GB以上的物理内存。不过内存对于现在的服务器而

言可以说是一个可以忽略的问题,工作中遇到了高端服务器基本上内存都超过了

32G。

关于磁盘

磁盘寻道能力(磁盘I/0)。以目前市场上普遍高转速SAIS硬盘(15000转

/秒)为例,这种硬盘理论上每秒寻道15000次,这是物理特性决定的,没有办

法改变。MySQL每秒钟都在进行大量、复杂的查询操作,对磁盘的读写量可想

而知。所以通常认为磁盘I/0是制约MySQL性能的最大因素之一,通常是使用

RAID-0+1磁盘阵列,注意不要尝试使用RAID-5,MySQL右ERAID-5磁盘阵列上

的效率并不高。如果不考虑硬件的投入成本,也可以考虑固态(SSD)硬盘专门

作为数据库服务器使用。数据库的读写性能肯定会提高很多。

mysql配置文件

核心性能优化项

内存配置(关键影响性能)

MySQL 主要通过内存缓存数据、索引和执行计划,合理分配内存是性能优化的核心。

innodb_buffer_pool_size(InnoDB 缓冲池大小)

作用 :缓存 InnoDB 表的数据和索引,是 InnoDB 性能优化的核心参数。优化逻辑 :值越大,缓存的数据越多,磁盘 I/O 越少。建议设置为服务器物理内存的 60%~80%(需为操作系统和其他进程保留内存)。

innodb_buffer_pool_size = 8G # 8GB 内存服务器建议值

查询优化项

复制代码
-- 低效:条件字段使用函数,导致索引失效
SELECT * FROM users WHERE YEAR(create_time) = 2023;

-- 高效:将函数运算移到右侧
SELECT * FROM users WHERE create_time >= '2023-01-01' AND create_time < '2024-01-01';

避免在索引字段上使用 NOT INIS NULL(可通过默认值优化)、OR(需索引覆盖所有条件)

执行计划分析(EXPLAIN)

使用 EXPLAIN 命令分析查询执行计划,重点关注以下字段:

字段 优化关注点
type 连接类型,优先级:system > const > eq_ref > ref > range > index > allall 表示全表扫描,需优化)。
key 实际使用的索引,若为 NULL 表示未使用索引。
rows 预估扫描的行数,数值越小越好。
Extra - Using filesort:需优化排序 - Using temporary:需优化分组或排序 - Using index:覆盖索引,性能最佳。

日志与监控

. 错误日志(Error Log)

作用 :记录启动、停止过程中的错误,以及运行时的关键错误(如内存不足、表损坏)。配置

复制代码
[mysqld]
log_error = /var/log/mysql/error.log  # 日志路径
log_error_verbosity = 3               # 日志详细程度(1-3级,默认2)

tail -f /var/log/mysql/error.log

用途:排查启动失败、连接异常、磁盘空间不足等问题。

Innodb高级优化

InnoDB 作为 MySQL 的默认存储引擎,其高级优化涉及多方面的深度配置和架构调整。以下是针对 InnoDB 高级优化 的核心策略,涵盖性能调优、并发控制、存储结构、高可用等关键领域

、内存与缓冲池优化

InnoDB 通过内存缓存数据和索引,合理分配内存是性能优化的核心。

缓冲池配置(innodb_buffer_pool_size)

作用 :缓存表数据和索引,减少磁盘 I/O。优化建议 :建议设置为物理内存的 50%~75% ,需为操作系统和其他进程保留空间。对于专用数据库服务器,可设为 80%(如 64GB 内存设为 48GB)。分批次调整(每次增加不超过 1GB),避免 MySQL 重启时间过长

复制代码
[mysqld]
innodb_buffer_pool_size = 48G

[配置片段(my.cnf)](#配置片段(my.cnf))

以下是一个针对 高性能 InnoDB 优化 的 MySQL 配置文件(my.cnf)示例,结合了前面讨论的核心优化参数。你可以根据服务器硬件配置(内存、磁盘类型)和业务场景(读多 / 写多)进行调整:

复制代码
[mysqld]
# 基础设置
server_id = 1
port = 3306
socket = /var/run/mysqld/mysqld.sock
pid-file = /var/run/mysqld/mysqld.pid
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
log_error = /var/log/mysql/error.log
slow_query_log = ON
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_slow_admin_statements = ON
expire_logs_days = 7

# 内存配置(根据服务器总内存调整)
innodb_buffer_pool_size = 8G                # 缓冲池大小,建议为物理内存的50%-75%
innodb_buffer_pool_instances = 8            # 缓冲池分区数,8-16个(大内存建议)
innodb_buffer_pool_load_at_startup = ON     # 启动时加载缓冲池状态
innodb_buffer_pool_dump_at_shutdown = ON    # 关闭时保存缓冲池状态

# 日志配置
innodb_log_file_size = 2G                   # 单个日志文件大小
innodb_log_files_in_group = 2               # 日志文件组数
innodb_log_buffer_size = 16M                # 日志缓冲区大小
innodb_flush_log_at_trx_commit = 2          # 日志刷盘策略:2=每秒刷盘(兼顾性能和安全)
sync_binlog = 100                           # binlog刷盘频率,1=每次提交都刷

# I/O 优化(适用于SSD)
innodb_io_capacity = 4000                   # IOPS能力(SSD可设5000+)
innodb_io_capacity_max = 8000               # 突发IO时的最大吞吐量
innodb_read_io_threads = 8                  # 读IO线程数
innodb_write_io_threads = 8                 # 写IO线程数
innodb_flush_method = O_DIRECT              # 直接IO,减少系统缓存干扰
innodb_file_per_table = ON                  # 独立表空间
innodb_file_format = Barracuda              # 支持DYNAMIC/COMPRESSED行格式
innodb_file_format_max = Barracuda

# 并发控制
innodb_thread_concurrency = 0               # 线程并发数,0=不限制(根据CPU调整)
innodb_lock_wait_timeout = 50               # 锁等待超时时间(秒)
transaction_isolation = READ-COMMITTED      # 隔离级别,减少间隙锁

# 查询优化
join_buffer_size = 2M                       # JOIN缓冲区大小
sort_buffer_size = 2M                       # 排序缓冲区大小
read_rnd_buffer_size = 1M                   # 随机读缓冲区大小
max_allowed_packet = 128M                   # 最大允许数据包大小

# 连接管理
max_connections = 1000                      # 最大连接数
max_user_connections = 800                  # 单个用户最大连接数
wait_timeout = 600                          # 非活跃连接超时时间(秒)
interactive_timeout = 600                   # 交互式连接超时时间

# 复制配置(主从复制)
log_bin = mysql-bin                         # 开启binlog
binlog_format = ROW                         # binlog格式
expire_logs_days = 14                       # binlog过期天数
relay_log = relay-bin                       # 中继日志
relay_log_recovery = ON                     # 从库崩溃恢复

# 其他优化
innodb_print_all_deadlocks = ON             # 打印所有死锁信息
innodb_stats_on_metadata = OFF              # 避免元数据统计导致的锁
innodb_adaptive_hash_index = ON             # 自适应哈希索引
innodb_flush_neighbors = 0                  # SSD禁用相邻页刷新

sql方面

SQL优化是确保数据库高效运行的关键,其核心在于通过减少少资源消耗(如
CPU、内存、磁盘I/0)来提升查询响应速度,避免慢查询导致用户体验下降或
系统崩溃。未优化的SQL可能引发全表扫描、冗余计算或锁竞争,尤其在数据量
大或高并发场景下,会导致服务器负载飙升、响应延迟,甚至影响业务连续性(如
交易超时)。通过索引调优、查询改写、执行计划分析等手段设,可显著降低数据
库压力,支撑业务规模扩展,同时控制硬件成本与运维复杂度。

[使用EXPLAIN 进行sql优化的步骤及实验验证](#使用EXPLAIN 进行sql优化的步骤及实验验证)

EXPLAIN 是MySQL中用于分析SQL执行计划的工具,通过模拟查询执行

过程输出关键信息(如访问类型 type、使用索引 key、预估扫描行数

rows、额外操作 Extra等),帮助开发者识别全表扫描、索引失效等性能瓶颈,从

而指导优化方向(如添加索引、改写查询或调整表结构),是提升数据库效率不

可或缺的诊断手段。

例如

复制代码
mysql>EXPLAIN SELECT * FROM users WHERE name = 'user123';

优化步骤,添加索引

复制代码
mysql>ALTER TABLE users ADD INDEX idx name (name);

优化后查询及EXPLAIN分析

复制代码
mysql>EXPLAIN SELECT * FROM user WHERE name = 'user123';
相关推荐
万山y39 分钟前
es快速上手(从MySQL角度)
mysql·elasticsearch·jenkins
Listennnn1 小时前
Neo4j数据库
数据库·人工智能·neo4j
Liu1bo1 小时前
【MySQL】库与表的操作
数据库·mysql·oracle
冬瓜的编程笔记2 小时前
【MySQL成神之路】MySQL常用语法总结
数据库·mysql
YJQ99672 小时前
Redis配置与优化:提升NoSQL数据库性能的关键策略
数据库·redis·nosql
@Turbo@2 小时前
【QT】一个界面中嵌入其它界面(二)
开发语言·数据库·qt
小白的码BUG之路3 小时前
Elasticsearch-kibana索引操作
大数据·数据库·elasticsearch
遇见火星4 小时前
Ansible模块——文件内容修改
数据库·mysql·ansible
八股文领域大手子4 小时前
MySQL死锁:面试通关“三部曲”心法
数据库·mysql·面试
dianzouyou1234564 小时前
钉钉报销与金蝶付款单系统对接技术揭秘
大数据·数据库·钉钉