OpenEuler 系统 MySQL 故障排查与优化超详细教程
适配说明 :本教程针对源码安装在 /usr/local/mysql 路径的 MySQL 服务,全程无安装步骤,覆盖 OpenEuler 系统全场景故障排查、根因定位、解决方案及全维度性能优化,适配 x86 / 鲲鹏 ARM 架构,兼容 MySQL 5.7/8.0 主流版本。
一、前置环境信息确认(排查前必做)
所有故障排查的前提是确认基础环境一致性,避免因路径、权限、配置加载顺序错误导致无效排查。
1. 核心目录与路径确认(/usr/local 专属)
表格
| 配置项 | 标准路径 | 查看命令 |
|---|---|---|
| 基础安装目录 (basedir) | /usr/local/mysql | `mysqld --verbose --help |
| 数据目录 (datadir) | /usr/local/mysql/data | `mysqld --verbose --help |
| 配置文件加载顺序 | /etc/my.cnf > /etc/mysql/my.cnf > /usr/local/mysql/my.cnf > ~/.my.cnf | `mysqld --verbose --help |
| 错误日志路径 | 默认 /usr/local/mysql/data/ 主机名.err | mysql -uroot -p -e "show variables like 'log_error';" |
| Socket 文件路径 | 默认 /tmp/mysql.sock | mysql -uroot -p -e "show variables like 'socket';" |
| PID 文件路径 | /usr/local/mysql/data/mysqld.pid | `mysqld --verbose --help |
2. 基础环境校验
- 环境变量配置:确保 MySQL 命令可全局调用
bash
# 临时生效
export PATH=$PATH:/usr/local/mysql/bin
# 永久生效(OpenEuler系统)
echo "export PATH=\$PATH:/usr/local/mysql/bin" >> /etc/profile
source /etc/profile
# 验证
mysql --version
- 运行用户校验:确认 mysql 用户 / 用户组存在,且目录权限正确
bash
# 检查mysql用户
id mysql
# 修复目录所属权(高频故障点)
chown -R mysql:mysql /usr/local/mysql/data
chmod -R 700 /usr/local/mysql/data
chown -R mysql:mysql /usr/local/mysql/logs # 如有独立日志目录
- systemd 服务文件校验:源码安装高频故障点,确保服务文件路径正确
bash
# 查看服务文件路径
systemctl cat mysqld.service
# 核心配置校验(必须匹配/usr/local路径)
[Service]
User=mysql
Group=mysql
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf
LimitNOFILE=65535
二、MySQL 故障排查通用标准化流程
90% 的 MySQL 故障可通过该流程快速定位根因,禁止跳步排查,优先定位故障大类,再深入细节。
第一步:故障现象初步分类
先明确故障类型,缩小排查范围:
- 启动失败类:systemctl start mysqld 执行失败,服务无法进入 running 状态
- 连接异常类:服务正常运行,但本地 / 远程无法登录,报各类连接错误
- 性能异常类:服务可正常连接,但 SQL 执行慢、业务卡顿、CPU/IO 负载飙升
- 数据异常类:表损坏、数据丢失、主从同步中断、死锁 / 锁等待报错
- 服务崩溃类:服务运行中意外退出、被 OOM 杀死、频繁重启
第二步:优先查看错误日志(核心中的核心)
MySQL 绝大多数故障都会在错误日志中留下明确根因,这是排查的第一优先级。
- 日志查看命令
bash
# 方式1:根据配置文件路径查看(推荐)
tail -n 100 -f $(mysql -uroot -p -e "show variables like 'log_error';" | grep -v "Variable_name" | awk '{print $2}')
# 方式2:默认路径查看(启动失败无法登录时用)
tail -n 100 -f /usr/local/mysql/data/$(hostname).err
# 方式3:查看systemd系统日志(启动失败无MySQL日志时用)
journalctl -u mysqld.service -f --no-pager
- 日志核心排查要点
- 重点搜索关键字:
[ERROR]、[Warning]、Permission denied、Address already in use、No space left on device、InnoDB: Error、OOM - 启动失败优先看:配置文件语法错误、路径不存在、权限不足、端口占用、内存不足、InnoDB 文件损坏
- 运行中崩溃优先看:OOM killer 日志、内存参数溢出、IO 异常、内核报错
第三步:系统资源与服务状态排查
- 服务状态基础检查
bash
# 查看服务运行状态
systemctl status mysqld.service
# 查看mysqld进程是否存在
ps -ef | grep mysqld | grep -v grep
# 检查端口是否正常监听(默认3306)
ss -tulpn | grep mysqld
netstat -tulpn | grep 3306
- 系统资源瓶颈排查
bash
# 1. 磁盘空间检查(高频故障点:datadir分区满、Inode耗尽)
df -h /usr/local/mysql/data
df -i /usr/local/mysql/data
# 2. 内存检查(OOM、内存不足)
free -mh
# 查看是否有OOM杀死进程记录
dmesg | grep -i "oom" | grep -i "kill"
journalctl -k | grep -i oom
# 3. CPU/IO负载检查
top # 按P看CPU排序,按M看内存排序
iostat -x 5 3 # 查看%iowait、%util磁盘IO负载
vmstat 5 3 # 查看系统上下文切换、阻塞进程
- 系统安全组件排查(OpenEuler 特有高频故障点)
bash
# 1. 防火墙检查(远程连接失败核心原因)
# 查看防火墙状态
firewall-cmd --state
# 查看已放行端口
firewall-cmd --list-ports
# 临时放通3306端口
firewall-cmd --add-port=3306/tcp
# 永久放通
firewall-cmd --add-port=3306/tcp --permanent
firewall-cmd --reload
# 2. SELinux检查(启动失败、权限报错核心原因)
# 查看SELinux状态
getenforce
# 临时关闭(验证是否为SELinux导致)
setenforce 0
# 永久关闭(需重启服务器)
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
# 若不想关闭,添加SELinux规则适配/usr/local路径
semanage fcontext -a -t mysqld_db_t "/usr/local/mysql/data(/.*)?"
restorecon -Rv /usr/local/mysql/data
第四步:配置文件合法性校验
配置文件错误是启动失败、性能异常的 TOP1 原因,尤其是源码安装的路径配置错误。
- 配置文件语法校验
bash
# 全量校验配置文件合法性,有错误会直接输出(MySQL 5.7+支持)
mysqld --validate-config --defaults-file=/etc/my.cnf
# 兼容低版本的校验方式
mysqld --verbose --help --defaults-file=/etc/my.cnf > /dev/null
- 核心配置项校验重点检查以下参数,确保路径、数值无错误:
basedir、datadir:必须与实际安装路径一致,目录必须存在且 mysql 用户有权限port、socket:客户端与服务端配置必须一致,端口无占用,socket 文件目录有权限pid-file:目录必须存在,mysql 用户有写入权限log_error:路径必须存在,mysql 用户有写入权限- 内存相关参数:总和不超过系统物理内存的 80%,避免 OOM
第五步:数据库内部状态排查(可正常登录时执行)
若服务可正常登录,通过以下命令定位内部运行异常:
sql
-- 1. 查看当前所有连接,定位长事务、锁等待、异常SQL
show full processlist;
-- 2. 查看InnoDB引擎状态,核心用于死锁、事务、IO异常排查
show engine innodb status;
-- 3. 查看数据库全局配置,确认参数是否生效
show variables like '%参数名%';
-- 4. 查看数据库运行状态指标,定位性能瓶颈
show global status like '%状态名%';
-- 5. 查看锁等待信息(MySQL 8.0)
select * from performance_schema.data_locks;
select * from performance_schema.data_lock_waits;
-- 6. 查看事务信息
select * from information_schema.innodb_trx;
三、高频故障场景专项排查与解决方案
场景 1:MySQL 服务启动失败(最常见)
子场景 1.1 配置文件错误导致启动失败
- 现象 :systemctl start mysqld 执行失败,journalctl 日志报
unknown variable、syntax error、unknown option - 排查步骤 :
- 执行
mysqld --validate-config命令,查看具体的错误参数和行号 - 检查配置文件加载顺序,确认是否有多个配置文件冲突
- 检查参数拼写错误、格式错误(如缺少
=、多余空格、不支持的参数)
- 执行
- 解决方案 :
- 注释或修正报错的参数,确保参数与 MySQL 版本兼容
- 统一配置文件到
/etc/my.cnf,删除其他路径下的冗余配置文件 - 修正后重新执行校验命令,无报错后再启动服务
子场景 1.2 文件权限 / 所属权错误
-
现象 :启动失败,错误日志报
Can't create/write to file、Permission denied、Errcode: 13 - Permission denied -
排查步骤 :
- 查看错误日志,确认报错的文件 / 目录路径
- 检查 datadir、日志目录、pid 文件目录、socket 文件目录的所属用户和权限
-
解决方案 :
bash
# 修复核心目录所属权 chown -R mysql:mysql /usr/local/mysql/data chown -R mysql:mysql /usr/local/mysql/logs # 如有独立日志目录 # 修复目录权限 chmod -R 700 /usr/local/mysql/data chmod -R 660 /usr/local/mysql/data/* # 修复socket文件权限(若存在) chown mysql:mysql /tmp/mysql.sock chmod 777 /tmp/mysql.sock
子场景 1.3 端口被占用
- 现象 :启动失败,错误日志报
Can't start server: Bind on TCP/IP port: Address already in use - 排查步骤 :
ss -tulpn | grep 3306,查看占用 3306 端口的进程 - 解决方案 :
- 若为冗余 mysqld 进程占用,执行
kill -9 进程ID杀死进程后重新启动 - 若为其他程序占用,修改
/etc/my.cnf中的port参数,更换未被占用的端口 - 重启服务后验证端口监听状态
- 若为冗余 mysqld 进程占用,执行
子场景 1.4 磁盘空间 / Inode 耗尽
-
现象 :启动失败,错误日志报
No space left on device、Write to file failed、InnoDB: Error: Write to file ibdata1 failed -
排查步骤 :
df -h检查 datadir 所在分区磁盘使用率,确认是否 100% 占用df -i检查分区 Inode 使用率,确认是否耗尽
-
解决方案 :
- 清理无用文件:删除过期的 binlog 日志、大尺寸错误日志、临时文件
sql
-- 手动清理指定时间前的binlog(MySQL内执行) purge binary logs before '2026-03-01 00:00:00';- 调整 binlog 自动过期策略,避免无限增长(见优化章节)
- 若 Inode 耗尽,删除大量小文件(如过期的慢日志分片、临时文件)
- 扩容 datadir 所在磁盘分区,完成后重新启动服务
子场景 1.5 内存不足 / OOM 导致启动失败
- 现象 :启动失败,错误日志报
Cannot allocate memory,或服务启动后立即被杀死,dmesg 有 OOM killer 日志 - 排查步骤 :
free -mh查看系统可用内存,确认是否不足- 查看 my.cnf 中内存相关参数,计算总内存占用是否超过系统可用内存
- 解决方案 :
- 调小核心内存参数,优先降低
innodb_buffer_pool_size(最占内存) - 临时增加 swap 分区,缓解内存压力
- 扩容服务器物理内存,重新调整内存参数后启动服务
- 调小核心内存参数,优先降低
子场景 1.6 InnoDB 数据文件损坏
-
现象 :启动失败,错误日志报
InnoDB: Error: tablespace id mismatch、InnoDB: Database page corruption on disk、ibdata1 file corrupted -
排查步骤:查看错误日志,确认 InnoDB 文件损坏的具体表和类型
-
解决方案 :
- 轻度损坏:通过强制恢复模式启动,备份数据后重建
bash
# 1. 停止服务 systemctl stop mysqld # 2. 编辑/etc/my.cnf,添加强制恢复参数(1-6,从1开始尝试,最小能启动的值) innodb_force_recovery = 1 # 3. 启动服务,成功后全量备份所有数据库 mysqldump -uroot -p --all-databases > all_database_backup.sql # 4. 停止服务,注释innodb_force_recovery参数,重建数据目录 # 5. 重新初始化后导入备份数据- 重度损坏:直接从最近的全量备份恢复数据,配合 binlog 实现时间点恢复
子场景 1.7 systemd 服务文件配置错误
-
现象 :systemctl 启动失败,但手动执行
mysqld_safe --user=mysql可正常启动 -
排查步骤 :查看 mysqld.service 文件,检查
ExecStart、User、Group、LimitNOFILE配置 -
解决方案 :
- 修正服务文件,确保路径与 /usr/local/mysql 完全匹配,标准配置如下:
ini
[Unit] Description=MySQL Server After=network.target [Service] User=mysql Group=mysql Type=notify ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID LimitNOFILE=1048576 LimitNPROC=1048576 TimeoutSec=600 Restart=on-failure [Install] WantedBy=multi-user.target- 重新加载 systemd 配置并启动
bash
systemctl daemon-reload systemctl start mysqld
场景 2:MySQL 连接异常(服务正常,无法登录)
子场景 2.1 本地 Socket 连接失败
-
现象 :本地执行
mysql -uroot -p报错Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) -
排查步骤 :
- 确认服务正常运行,端口正常监听
- 查看 my.cnf 中
[mysqld]和[client]段的 socket 配置是否一致 - 检查 socket 文件是否存在,权限是否正确
-
解决方案 :
- 临时解决:指定正确的 socket 路径连接
bash
mysql -uroot -p -S /usr/local/mysql/data/mysql.sock- 永久解决:统一
/etc/my.cnf中[mysqld]和[client]的 socket 配置
ini
[mysqld] socket = /tmp/mysql.sock [client] socket = /tmp/mysql.sock- 重启服务,重新生成 socket 文件
子场景 2.2 远程连接失败
-
现象 :本地可正常登录,远程客户端连接报错
Host 'xxx.xxx.xxx.xxx' is not allowed to connect to this MySQL server、Connection timed out -
排查步骤 :
- 网络连通性测试:远程端执行
telnet 服务器IP 3306,确认端口可访问 - 检查 OpenEuler 防火墙是否放通 3306 端口
- 检查 MySQL 用户是否允许远程访问,host 字段是否为
%或指定 IP - 检查 my.cnf 中
bind-address是否绑定了 127.0.0.1
- 网络连通性测试:远程端执行
-
解决方案 :
- 防火墙放通 3306 端口(见前文系统资源排查)
- 修正 bind-address 配置,允许远程访问
ini
# /etc/my.cnf 添加/修改,重启服务生效 bind-address = 0.0.0.0- 创建允许远程访问的数据库用户
sql
-- 创建远程root用户(生产环境建议创建专用业务用户,限制权限) create user 'root'@'%' identified by '你的强密码'; grant all privileges on *.* to 'root'@'%' with grant option; flush privileges; -- 查看用户权限 select user,host from mysql.user where user='root';
子场景 2.3 连接数爆满报错 Too many connections
-
现象 :新连接报错
Too many connections,业务无法连接数据库 -
排查步骤 :
- 用 root 本地登录(MySQL 为 root 预留了 1 个额外连接),执行
show variables like 'max_connections';查看最大连接数 - 执行
show global status like 'Threads_connected';查看当前连接数 - 执行
show full processlist;查看是否有大量空闲睡眠连接、长事务
- 用 root 本地登录(MySQL 为 root 预留了 1 个额外连接),执行
-
解决方案 :
- 紧急恢复:kill 掉无用的空闲连接,释放连接数
- 临时调大最大连接数(重启后失效)
sql
set global max_connections = 2000;- 永久生效:修改 /etc/my.cnf 配置
ini
max_connections = 2000- 根因优化:调整连接超时参数,自动关闭空闲连接
ini
# 非交互式连接超时时间,单位秒,默认8小时,改为10分钟 wait_timeout = 600 # 交互式连接超时时间 interactive_timeout = 600- 优化应用端连接池,设置合理的最大连接数和空闲连接回收机制
子场景 2.4 密码正确但登录报错 Access denied
-
现象 :密码确认正确,登录报错
Access denied for user 'root'@'localhost' (using password: YES) -
排查步骤 :
- 确认用户 host 是否匹配,比如 root@'localhost' 和 root@'%' 是两个不同用户
- 检查是否存在匿名用户,导致登录匹配优先级异常
- 确认用户认证插件是否与客户端兼容(MySQL8.0 默认 caching_sha2_password,低版本客户端不兼容)
-
解决方案 :
- 跳过权限表启动,重置密码
bash
# 1. 停止服务 systemctl stop mysqld # 2. 跳过权限表启动 /usr/local/mysql/bin/mysqld_safe --skip-grant-tables --skip-networking --user=mysql & # 3. 无密码登录 mysql -uroot # 4. 重置密码(MySQL8.0) use mysql; flush privileges; alter user 'root'@'localhost' identified by '你的新密码'; flush privileges; exit; # 5. 停止跳过权限表的进程,正常启动服务- 删除匿名用户,避免匹配异常
sql
delete from mysql.user where user=''; flush privileges;- 兼容低版本客户端,修改认证插件
sql
alter user 'root'@'%' identified with mysql_native_password by '你的密码'; flush privileges;
场景 3:MySQL 运行卡顿 / 性能异常
子场景 3.1 CPU 使用率飙升
- 现象:top 查看 mysqld 进程 CPU 占用 100%+,业务响应卡顿,QPS 骤降
- 排查步骤 :
show full processlist;定位正在执行的耗时 SQL,查看是否有大量全表扫描、排序、分组操作- 开启慢查询日志,定位 TOP 慢 SQL
- 用 explain 分析慢 SQL 执行计划,确认是否未走索引、索引失效
- 解决方案 :
- 紧急处理:kill 掉异常耗时的 SQL,临时恢复业务
- 根因优化:为慢 SQL 添加合适的索引,优化 SQL 语句(避免 select *、避免函数操作索引字段、避免深分页)
- 避免大事务、长事务,拆分复杂 SQL,减少 CPU 计算开销
- 限制并发数,优化应用端连接池,避免大量并发 SQL 同时执行
子场景 3.2 磁盘 IO 负载过高
-
现象:iostat 查看 % iowait、% util 持续飙升,磁盘读写频繁,SQL 查询卡顿
-
排查步骤 :
- 慢查询日志定位大量磁盘 IO 的 SQL(全表扫描、无索引的大表查询)
show engine innodb status;查看 InnoDB IO 刷新情况- 检查 innodb_flush_log_at_trx_commit、sync_binlog 参数配置
-
解决方案 :
- 优化 SQL 和索引,减少全表扫描,降低磁盘 IO 次数
- 调大 innodb_buffer_pool_size,增加数据缓存,减少磁盘读写
- 合理调整事务刷盘参数,平衡性能与安全
ini
# 金融核心场景:双1配置,最高安全性 innodb_flush_log_at_trx_commit = 1 sync_binlog = 1 # 非核心业务场景:高性能配置,宕机丢失1秒数据 innodb_flush_log_at_trx_commit = 2 sync_binlog = 1000- 硬件优化:更换 NVMe SSD,分离数据文件、binlog、日志到不同磁盘,避免 IO 竞争
- 关闭 innodb_flush_neighbors(SSD 场景),减少不必要的邻页刷新
子场景 3.3 死锁与锁等待超时
-
现象 :业务报错
Lock wait timeout exceeded; try restarting transaction、Deadlock found when trying to get lock -
排查步骤 :
show engine innodb status;查看最近的死锁详细信息,定位死锁的 SQL 和事务information_schema.innodb_trx查看当前运行的长事务performance_schema.data_locks查看当前持有和等待的锁
-
解决方案 :
- 紧急处理:kill 掉导致锁等待的长事务,释放锁资源
- 优化 SQL 和索引,避免全表扫描导致的表锁,减少锁范围
- 拆分大事务、长事务,缩小事务执行时间,减少锁持有时间
- 统一业务中事务的更新顺序,避免交叉更新导致死锁
- 调整行锁等待超时参数
ini
innodb_lock_wait_timeout = 10
场景 4:主从同步异常
- 现象 :从库同步中断,
show slave status\G查看Slave_IO_Running或Slave_SQL_Running为 No - 排查与解决方案 :
- IO 线程为 No :
- 常见原因:主库网络不通、防火墙拦截、主从账号密码错误、主库 binlog 未开启、server-id 冲突、主库 binlog 文件丢失
- 解决方案:检查网络连通性、防火墙放通端口、确认同步账号权限、统一 server-id 集群内唯一、重新配置主从同步
- SQL 线程为 No :
- 常见原因:主从数据不一致、主键冲突、从库写入、DDL 执行失败、binlog 格式不兼容
- 解决方案:
- 临时跳过单个错误(非核心数据):
stop slave; set global sql_slave_skip_counter=1; start slave; - 数据不一致场景:通过 pt-table-checksum 校验数据差异,pt-table-sync 修复数据,或重新全量同步主库数据
- 临时跳过单个错误(非核心数据):
- 主从延迟过高 :
- 常见原因:从库性能不足、大事务执行、无主键表、并行复制未开启、网络延迟
- 解决方案:开启 MySQL8.0 并行复制、拆分大事务、确保所有表有主键、提升从库硬件配置、优化主库写入频率
- IO 线程为 No :
四、MySQL 全维度性能优化
优化核心原则:先优化业务 SQL 与索引,再优化配置参数,最后优化系统与架构,80% 的性能问题都可通过 SQL 与索引优化解决。
一、SQL 与索引优化(优先级最高)
1. 慢查询日志开启与分析
慢查询是性能问题的核心来源,生产环境必须开启,用于定位耗时 SQL。
ini
# /etc/my.cnf 慢查询配置
slow_query_log = ON
# 日志路径,确保mysql用户有写入权限
slow_query_log_file = /usr/local/mysql/data/slow.log
# 慢查询阈值,单位秒,超过1秒的SQL记录,生产环境可设为0.5
long_query_time = 1
# 记录未使用索引的SQL
log_queries_not_using_indexes = ON
# 限制每分钟未使用索引的SQL记录次数,避免日志暴涨
log_throttle_queries_not_using_indexes = 10
慢日志分析工具:
bash
# 1. 自带mysqldumpslow,按执行时间排序,取TOP10慢SQL
mysqldumpslow -s t -t 10 /usr/local/mysql/data/slow.log
# 2. 进阶工具pt-query-digest(percona-toolkit),生成详细分析报告
pt-query-digest /usr/local/mysql/data/slow.log > slow_report.log
2. 执行计划 explain 分析
通过 explain 分析 SQL 执行计划,定位索引失效、全表扫描等问题,核心用法:
sql
explain select * from 表名 where 条件;
核心字段关注重点:
表格
| 字段 | 优化要点 |
|---|---|
| type | 访问类型,最优到最差:system > const > eq_ref > ref > range > index > ALL,必须避免 ALL(全表扫描) |
| key | 实际使用的索引,为 NULL 表示未使用索引,需优化 |
| rows | 扫描的行数,数值越小越好,代表索引效率越高 |
| Extra | 避免出现Using filesort(文件排序)、Using temporary(临时表)、Using where无索引匹配 |
3. 索引优化最佳实践
- 高频查询字段优先建索引:where 条件、join 关联字段、order by、group by 字段
- 联合索引遵循最左前缀原则,区分度高的字段放在索引前列
- 单表索引数量控制在 5 个以内,避免大量索引导致写入性能下降
- 避免索引失效场景:索引字段使用函数运算、隐式类型转换、like '% xxx' 前缀模糊查询、or 连接非索引字段、!=/not in 操作
- 定期删除无用、重复、低选择性的索引,通过 pt-index-usage 分析索引使用率
- 所有表必须有主键,优先使用自增主键,避免 UUID 作为主键
4. SQL 编写优化规范
- 禁止使用 select *,只查询业务需要的字段,减少数据传输和内存占用
- 避免大表 join 大表,控制 join 的表数量不超过 3 个,join 字段必须建索引
- 避免在 where 子句中对索引字段进行函数、算术运算,导致索引失效
- 优化深分页查询,如
limit 100000,20,改为主键过滤分页where id > 100000 limit 20 - 批量操作代替循环单条操作,如批量 insert、update,减少数据库交互次数
- 拆分大事务、长事务,控制事务执行时间,避免锁持有时间过长
- 禁止在业务高峰期执行大表 DDL、alter table 操作,使用 pt-online-schema-change 工具无锁改表
二、MySQL 配置参数优化(/etc/my.cnf)
以下为适配 /usr/local/mysql 安装路径、OpenEuler 系统的优化配置,按服务器内存调整核心参数。
1. 基础路径与通用配置
ini
[mysqld]
# 核心路径配置(必须与你的安装路径一致)
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
socket = /tmp/mysql.sock
pid-file = /usr/local/mysql/data/mysqld.pid
port = 3306
user = mysql
# 字符集配置
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
lower_case_table_names = 1 # 表名大小写不敏感,OpenEuler系统建议开启
default-time_zone = '+8:00'
# 禁用DNS反向解析,提升连接速度
skip-name-resolve
2. 核心内存优化配置
内存优化核心原则:专用数据库服务器,MySQL 总内存占用不超过系统物理内存的 70%,避免 OOM。
表格
| 参数 | 优化建议 |
|---|---|
| innodb_buffer_pool_size | 最核心参数,InnoDB 数据和索引缓存,专用服务器设为物理内存的 50%-70%。例:8G 内存设 4G,16G 设 10G,32G 设 20G |
| innodb_buffer_pool_instances | 缓冲池实例数,缓冲池大于 8G 时设为 4-8 个,每个实例至少 1G,减少锁竞争 |
| innodb_log_buffer_size | redo log 缓冲区,高并发写入场景设为 64M-128M,最大不超过 1G,避免频繁刷磁盘 |
| sort_buffer_size | 每个会话排序缓冲区,默认 256K,建议不超过 4M,排序多的场景设 1M-2M |
| join_buffer_size | 每个会话 join 缓冲区,默认 256K,建议不超过 4M,避免大表 join 内存溢出 |
| read_buffer_size | 顺序读缓冲区,默认 128K,顺序扫描多的场景设 256K-1M |
| read_rnd_buffer_size | 随机读缓冲区,默认 256K,排序多的场景设 512K-1M |
3. InnoDB 引擎核心优化
ini
# IO刷新方式,绕过操作系统缓存,直接写入磁盘,SSD场景必选,减少双缓存和swap占用
innodb_flush_method = O_DIRECT
# 事务刷盘策略,见前文IO优化,根据业务场景选择
innodb_flush_log_at_trx_commit = 1
# binlog刷盘策略,与上面参数配合,双1配置最高安全性
sync_binlog = 1
# 每个表独立表空间,必须开启,方便表维护、空间回收,避免ibdata1无限膨胀
innodb_file_per_table = ON
# IO线程数,多核CPU建议设为8-16,提升IO并发能力
innodb_read_io_threads = 16
innodb_write_io_threads = 16
# 脏页最大比例,避免脏页集中刷盘导致IO抖动
innodb_max_dirty_pages_pct = 60
# 行锁等待超时时间,单位秒,业务场景建议5-10秒
innodb_lock_wait_timeout = 10
# 事务隔离级别,互联网业务推荐READ-COMMITTED,减少锁等待,提升并发
transaction_isolation = READ-COMMITTED
# 关闭邻页刷新,SSD场景必关,HDD场景开启
innodb_flush_neighbors = 0
# IO容量设置,根据SSD性能调整,普通SSD设2000,NVMe SSD设4000-8000
innodb_io_capacity = 2000
innodb_io_capacity_max = 4000
4. 连接与日志优化
ini
# 最大连接数,根据业务场景设置,建议1000-2000,避免设置过大
max_connections = 2000
# 连接超时时间,自动关闭空闲连接,单位秒
wait_timeout = 600
interactive_timeout = 600
# 最大错误连接数,避免频繁错误连接导致IP封禁
max_connect_errors = 1000
# binlog配置(主从同步、数据恢复必开)
server-id = 1 # 集群内必须唯一
log_bin = /usr/local/mysql/data/mysql-bin
binlog_format = ROW # 行级模式,推荐,主从同步更安全
binlog_row_image = FULL
# binlog自动过期时间,7天,避免磁盘占满(MySQL8.0推荐用秒级配置)
binlog_expire_logs_seconds = 604800
# MySQL5.7用天级配置
# expire_logs_days = 7
# 错误日志配置,排查故障核心,必须开启
log_error = /usr/local/mysql/data/mysql-error.log
log_error_verbosity = 3
三、OpenEuler 系统级内核优化
OpenEuler 针对服务器场景深度优化,通过内核参数调整可大幅提升 MySQL 性能,适配 x86 / 鲲鹏 ARM 架构。
1. 内核参数优化(/etc/sysctl.conf)
编辑/etc/sysctl.conf,添加以下配置,执行sysctl -p立即生效。
ini
# 内存优化
# 尽量不使用swap,数据库专用服务器设为1,避免swap导致性能暴跌
vm.swappiness = 1
# 脏页达到20%时,后台开始异步刷盘
vm.dirty_ratio = 20
# 脏页达到10%时,后台启动刷盘
vm.dirty_background_ratio = 10
# 严格控制内存分配,避免OOM
vm.overcommit_memory = 2
# 允许分配的内存不超过物理内存的80%+swap
vm.overcommit_ratio = 80
# IO优化
# 最大异步IO数量,适配InnoDB
fs.aio-max-nr = 1048576
# 系统级最大文件句柄数
fs.file-max = 2097152
# 网络优化,高并发连接场景
# 监听队列最大长度,默认128,高并发必须调大
net.core.somaxconn = 65535
# SYN队列最大长度
net.ipv4.tcp_max_syn_backlog = 65535
# TIME_WAIT超时时间,默认60,调小减少端口占用
net.ipv4.tcp_fin_timeout = 30
# 允许TIME_WAIT端口复用,高并发必须开启
net.ipv4.tcp_tw_reuse = 1
# 最大TIME_WAIT数量
net.ipv4.tcp_max_tw_buckets = 200000
# 网络设备接收队列最大长度
net.core.netdev_max_backlog = 30000
# 端口范围,扩大可用端口数
net.ipv4.ip_local_port_range = 1024 65535
# 读写缓冲区最大值
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
# 鲲鹏ARM架构专属优化(x86可忽略)
kernel.sched_steal_node_limit=4
2. 文件句柄限制优化
MySQL 需要大量文件句柄,默认 1024 远远不足,编辑/etc/security/limits.conf,添加以下配置,重启服务器生效。
ini
mysql soft nofile 65535
mysql hard nofile 1048576
mysql soft nproc 65535
mysql hard nproc 1048576
root soft nofile 1048576
root hard nofile 1048576
生效后执行ulimit -n,确认输出为 65535 及以上。
3. IO 调度器优化
- NVMe SSD / 固态硬盘 :推荐使用
none/noop调度器,减少 IO 调度开销 - 机械硬盘 HDD :推荐使用
mq-deadline调度器,优化寻道效率
bash
# 查看当前调度器(sda为你的磁盘名,根据实际修改)
cat /sys/block/sda/queue/scheduler
# 临时修改
echo none > /sys/block/sda/queue/scheduler
# 永久生效:编辑/etc/default/grub,在GRUB_CMDLINE_LINUX中添加elevator=none,更新grub后重启生效
4. CPU 性能优化
关闭 CPU 节能模式,设置为性能模式,避免 CPU 降频导致性能波动。
bash
# 临时设置为性能模式
cpupower frequency-set -g performance
# 永久生效:在BIOS中关闭CPU节能模式,或配置systemd服务开机执行
四、架构级长期优化
- 读写分离:主库负责写入,从库负责读取,分担读压力,适配读多写少的业务场景
- 分库分表:单表数据量超过 1000 万、单库容量超过 100G 时,实施水平 / 垂直分库分表,降低单表负载
- 缓存架构:搭配 Redis 缓存热点数据、高频查询结果,减少 MySQL 数据库访问压力
- 高可用架构:部署 MGR(MySQL Group Replication)、Keepalived + 双主架构,避免单点故障,提升服务可用性
- 冷热数据分离:历史冷数据归档到单独的库 / 表,热数据保留在主库,大幅提升查询性能
五、日常运维与故障预防
-
日常巡检核心项:
- 服务状态、端口监听、主从同步状态
- 磁盘空间使用率、binlog 增长情况
- CPU、内存、IO 负载是否有异常飙升
- 错误日志是否有新增 ERROR 告警
- 慢查询日志是否有新增异常慢 SQL
- 当前连接数、锁等待、长事务情况
-
监控告警部署:
- 推荐使用
Prometheus + Grafana + mysqld_exporter搭建监控体系,覆盖连接数、QPS/TPS、缓存命中率、IO 延迟、主从延迟等核心指标 - 设置磁盘空间、CPU 负载、服务状态、主从中断的告警规则,提前发现风险
- 推荐使用
-
备份策略:
- 制定定期备份计划:每日全量备份 + 每小时 binlog 增量备份
- 备份文件异地存储,定期执行备份恢复测试,确保备份可用
- 生产环境禁止在业务高峰期执行备份,大库推荐使用
percona-xtrabackup热备工具
-
常用运维工具推荐:
- percona-toolkit:MySQL 运维神器,包含慢日志分析、表同步、无锁改表、索引分析等工具
- pt-stalk:故障捕获工具,异常时自动捕获系统和数据库状态,用于事后排查
- binlog2sql:binlog 解析工具,生成回滚 SQL,用于误删数据恢复
- sysbench:MySQL 压测工具,用于验证优化效果、性能测试
重要注意事项
- 所有配置修改、参数优化,必须先在测试环境验证,再上线生产环境,避免配置错误导致服务不可用
- 优化参数循序渐进,每次仅修改 1-2 个核心参数,观察性能变化,避免一次性修改大量参数导致无法定位问题
- 生产环境任何数据修改、表结构变更、服务重启,必须先备份,制定回滚方案,避免数据丢失
- 生产环境禁止开启通用查询日志 general_log,会严重影响数据库性能,仅临时排查问题时使用
- 注意 MySQL 版本与 OpenEuler 系统的兼容性,鲲鹏 ARM 架构必须使用对应 ARM 版本的 MySQL 安装包,避免兼容性问题
