必须调操作系统内核参数,因为mysql的i/o、内存和并发行为直接受linux内核调度与资源管理策略影响;例如vm.swappiness=60默认值会导致innodb缓冲池被频繁换出,net.core.somaxconn=128会丢弃syn包引发connection refused,这些是mysql自身无法绕过的底层限制。

为什么必须调操作系统内核参数,而不是只改 MySQL 配置
MySQL 的 I/O、内存和并发行为直接受 Linux 内核调度与资源管理策略影响。比如 vm.swappiness=60(默认值)会让内核频繁将匿名页换出到 Swap,导致 InnoDB 缓冲池被“误杀”;又比如 net.core.somaxconn=128(旧内核默认),在高并发连接建立时会直接丢弃 SYN 包,表现为应用层报 Connection refused 而非超时。这些都不是 MySQL 自身能绕过的底层限制。
关键内核参数必须改的三项
以下三项在 95% 的生产 MySQL 部署中都需调整,且顺序不能错:
-
vm.swappiness=1:强制内核优先回收 page cache(如文件缓存),而非杀死缓冲池里的 InnoDB 数据页;设为 0 反而可能引发 OOM killer 杀掉 mysqld 进程 -
vm.dirty_ratio=80和vm.dirty_background_ratio=5:避免刷脏页时阻塞写入线程;若用 NVMe SSD,可进一步提高vm.dirty_ratio至 90,但需配合innodb_io_capacity_max同步调高 -
net.core.somaxconn=65535和net.ipv4.tcp_max_syn_backlog=65535:防止连接洪峰时 SYN 队列溢出;注意net.core.somaxconn必须 ≥ MySQL 的max_connections,否则mysqld启动时会静默截断连接数上限
磁盘 I/O 相关参数要按硬件类型配
同一套参数在 SATA SSD 和 NVMe 上表现可能天差地别:
- SSD(SATA/NVMe):挂载时加
noatime,nobarrier,commit=60;barrier=0在 ext4/xfs 下已默认禁用,但显式写上更稳妥 - NVMe 设备:必须设
vm.vfs_cache_pressure=50,降低 dentry/inode 缓存回收倾向,避免大量表打开时触发频繁元数据 I/O - 如果使用 LVM 或 RAID,还需确认
read_ahead_kb值:机械盘建议 128,SSD 建议 16(过大会造成无效预读)
容易被忽略的 CPU 和 NUMA 陷阱
多路服务器上不处理 NUMA,InnoDB 缓冲池可能跨节点访问内存,延迟翻倍:
- 先用
numactl --hardware确认拓扑;若为双路 CPU 且mysqld进程绑定了错误 node,innodb_buffer_pool_size再大也白搭 - 启动 mysqld 时强制绑定:用
numactl --cpunodebind=0 --membind=0 /usr/local/mysql/bin/mysqld ...(假设主实例跑在 node 0) - 禁用 CPU 频率缩放:
echo 'performance' > /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor;否则高负载时 CPU 频率跳变,innodb_thread_concurrency的调控逻辑会失准
真正卡住上线的,往往不是 innodb_log_file_size 设小了,而是 vm.swappiness 没关、或 numactl 绑错了节点——这些点在压测初期几乎不暴露,一到流量高峰就批量超时。











