在 MySQL 性能优化中,不同版本的特性差异会直接影响优化效果。本文基于 MySQL 5.7 和 8.0 两个主流版本,通过版本适配的配置代码、场景举例和通俗解释,让优化方案更精准落地。
MySQL 需大量文件描述符(连接、表文件等),默认值常不足,需手动调整:
# 临时生效
ulimit -n 65535
# 永久生效(编辑/etc/security/limits.conf)
echo "mysql soft nofile 65535" >> /etc/security/limits.conf
echo "mysql hard nofile 65535" >> /etc/security/limits.conf
在 MySQL 配置文件(my.cnf)中同步设置:
[mysqld]
open_files_limit = 65535 # 与系统配置保持一致,5.7和8.0通用
编辑/etc/sysctl.conf,添加以下配置后执行sysctl -p生效:
# 加速TIME_WAIT连接回收,适合高并发短连接场景(如Web应用)
net.ipv4.tcp_tw_recycle = 1 # 5.7推荐启用,8.0可结合tcp_autocorking使用
net.ipv4.tcp_tw_reuse = 1
# 降低内存交换频率,避免MySQL突然卡顿
vm.swappiness = 10 # 5.7建议10-20,8.0因内存管理优化可设5-10
# 脏页比例阈值,超过后系统强制刷盘
vm.dirty_ratio = 60 # 5.7和8.0通用
# 网络连接队列长度,应对突发连接请求
net.ipv4.tcp_max_syn_backlog = 65535 # 8.0因连接管理优化可设更高
作用:缓存数据页和索引页,减少磁盘读取。
配置原则:物理内存的 50%-70%(留部分给系统和其他进程)。
举例:
版本差异:
# 5.7配置
innodb_buffer_pool_size = 10G
innodb_buffer_pool_instances = 8
# 8.0配置
innodb_buffer_pool_size = 10G # 实例数自动优化
作用:控制最大并发连接,避免资源耗尽。
版本差异:
计算方法:max_connections = (系统可用内存 - 缓冲池内存) / 单个连接内存消耗
举例:16GB 内存,缓冲池 10G,剩余 6GB 可用:
# 5.7配置(单个连接按2MB计算)
max_connections = 800
max_user_connections = 500
# 8.0配置(单个连接按1.7MB计算,可适当提高)
max_connections = 1000
max_user_connections = 600
关键建议:8.0 新增connection_memory_limit可控制单连接内存上限:
# 8.0特有
connection_memory_limit = 100M # 防止单连接内存泄露
作用:存储事务日志,过小会频繁切换,过大影响恢复速度。
版本差异:
# 5.7配置
innodb_log_file_size = 1G
innodb_log_files_in_group = 2
# 8.0配置(高并发场景)
innodb_log_file_size = 2G
innodb_log_files_in_group = 2
版本差异:
# 5.7配置(高写场景必禁)
query_cache_size = 0
query_cache_type = 0
# 8.0无需配置(已移除)
作用:控制 binlog 何时写入磁盘,影响数据安全性和性能。
版本差异:
# 5.7配置(金融场景)
sync_binlog = 1
# 8.0配置(默认已安全,无需修改)
# sync_binlog = 1 # 默认值
作用:控制数据刷盘方式,避免双重缓存。
版本差异:
# 5.7配置
innodb_flush_method = O_DIRECT
# 8.0配置(SSD场景)
innodb_flush_method = O_DIRECT_NO_FSYNC
作用:告诉 InnoDB 存储设备的 IOPS 能力,优化刷盘频率。
版本差异:
# 5.7 SSD配置
innodb_io_capacity = 2000
innodb_io_capacity_max = 4000
# 8.0 NVMe SSD配置(可更高)
innodb_io_capacity = 5000
innodb_io_capacity_max = 10000
版本差异:
-- 5.7设计
CREATE TABLE user (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
birth DATE,
salary DECIMAL(10,2)
);
-- 8.0优化设计(使用生成列)
CREATE TABLE user (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
birth DATE,
salary DECIMAL(10,2),
birth_year INT GENERATED ALWAYS AS (YEAR(birth)) STORED, -- 生成列可建索引
INDEX idx_birth_year(birth_year)
);
版本差异:
# 5.7配置
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = 1
# 8.0配置(增加限流)
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = 1
log_throttle_queries_not_using_indexes = 100 # 每分钟最多记录100条
版本差异:
-- 5.7只能预估
EXPLAIN SELECT * FROM orders WHERE status=1;
-- 8.0可实际执行分析
EXPLAIN ANALYZE SELECT * FROM orders WHERE status=1;
版本差异:
-- 8.0特有:查看连接等待情况
SELECT * FROM performance_schema.events_waits_summary_global_by_event_name
WHERE EVENT_NAME LIKE 'wait/io/table/%';
版本差异:
-- 5.7整理碎片(锁表时间长)
ALTER TABLE orders ENGINE=InnoDB;
-- 8.0整理碎片(在线执行)
ALTER TABLE orders FORCE;
版本差异:
# 5.7主库配置
server-id = 1
log_bin = /var/log/mysql/binlog
binlog_do_db = your_db
gtid_mode = ON # 需手动开启
enforce_gtid_consistency = ON
# 8.0主库配置(默认GTID开启)
server-id = 1
log_bin = /var/log/mysql/binlog
binlog_do_db = your_db
# GTID默认启用,无需额外配置
从库配置差异:
-- 5.7从库配置
CHANGE MASTER TO
MASTER_HOST='主库IP',
MASTER_USER='repl',
MASTER_PASSWORD='password',
MASTER_AUTO_POSITION = 1; # GTID方式
-- 8.0从库配置(更简洁)
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='主库IP',
SOURCE_USER='repl',
SOURCE_PASSWORD='password',
SOURCE_AUTO_POSITION = 1; # 关键字从MASTER改为SOURCE
每个优化配置都需结合业务场景和 MySQL 版本特性,建议先在测试环境验证效果,再逐步推广到生产环境。
既然看到这里了,如果觉得不错,随手`点赞、点个关注,收藏`,可以第一时间收到推送。真诚感谢你看我的文章,我是`挑战者666888`,下次再见。