Linux 5.15 内存交换Swap实战4GB 物理内存下 MySQL 8.0 性能调优与 OOM 规避在资源受限的服务器环境中如何让内存密集型应用如 MySQL 稳定运行是一门艺术。当物理内存仅有 4GB 时合理配置 Swap 空间和优化内存参数不仅能避免 OOMOut of Memory杀手误伤关键进程还能在性能与可靠性之间找到最佳平衡点。本文将手把手带您完成从 Swap 配置到 MySQL 调优的全流程实战。1. Swap 基础与 Linux 5.15 内核特性现代 Linux 系统中Swap 不再只是简单的内存溢出区而是内存管理策略的重要组成部分。Linux 5.15 内核引入了以下关键改进主动式 Swap 预读当系统检测到内存压力时会提前将不活跃页面移至 Swapcgroup v2 内存控制更精细的 per-cgroup Swap 限制策略zswap 压缩缓存对即将换出的页面进行压缩存储需启用CONFIG_ZSWAPSwap 的三种实现方式对比类型性能灵活性适用场景独立 Swap 分区高低长期稳定的生产环境Swap 文件中高云主机等动态环境zswap可变中内存较小但有快速存储设备提示在云环境中由于无法轻易调整分区Swap 文件通常是更实用的选择2. 配置 Swap 的最佳实践2.1 创建 Swap 文件以 Ubuntu 22.04 为例# 创建 4GB 的 Swap 文件大小建议为物理内存的 1-2 倍 sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile # 永久生效 echo /swapfile none swap sw 0 0 | sudo tee -a /etc/fstab关键参数验证sudo swapon --show free -h2.2 优化 swappiness 参数swappiness 值0-100控制内核使用 Swap 的倾向性# 查看当前值 cat /proc/sys/vm/swappiness # 临时设置为更保守的值推荐 10-30 对于数据库服务器 sudo sysctl vm.swappiness20 # 永久生效 echo vm.swappiness20 | sudo tee -a /etc/sysctl.conf对于 MySQL 专用服务器可以设置更激进的内存保留策略echo vm.min_free_kbytes65536 | sudo tee -a /etc/sysctl.conf3. MySQL 8.0 内存调优策略3.1 关键内存参数计算在 4GB 物理内存的服务器上建议分配# /etc/mysql/my.cnf [mysqld] innodb_buffer_pool_size 2G # 物理内存的 50% innodb_log_file_size 256M # 每个日志文件大小 innodb_log_files_in_group 2 # 日志文件数量 key_buffer_size 128M # MyISAM 索引缓存如使用 query_cache_size 0 # 建议禁用查询缓存 tmp_table_size 64M max_heap_table_size 64M table_open_cache 2000内存分配检查工具# 查看 MySQL 实际内存使用 sudo pmap -x $(pgrep mysqld) | grep total3.2 预防 OOM 的特殊配置[mysqld] oom-score -800 # 降低被 OOM killer 选中的概率 performance_schema ON # 开启性能监控 # 限制连接内存使用 max_connections 50 thread_stack 256K4. 监控与性能分析4.1 Swap 活动监控# 实时监控 Swap I/O vmstat 1 # 查看 si/so 列 sar -W 1 # 查看页面交换统计 # 更详细的 Swap 使用分析 cat /proc/meminfo | grep -i swap4.2 MySQL 内存压力测试使用 sysbench 模拟负载sysbench oltp_read_write \ --db-drivermysql \ --mysql-userroot \ --mysql-passwordyourpassword \ --mysql-dbsbtest \ --tables10 \ --table-size100000 \ --threads8 \ --time300 \ prepare sysbench oltp_read_write \ --db-drivermysql \ --mysql-userroot \ --mysql-passwordyourpassword \ --mysql-dbsbtest \ --tables10 \ --table-size100000 \ --threads8 \ --time300 \ run4.3 性能数据对比Swap 开启前后的 TPS 对比示例场景平均 TPS95% 延迟(ms)OOM 发生次数无 Swap1124453/5 次测试4GB Swap 文件986680/5 次测试zswap 启用1057520/5 次测试5. 高级调优技巧5.1 使用 cgroup v2 限制 MySQL 内存# 创建 cgroup sudo mkdir /sys/fs/cgroup/mysql echo memory | sudo tee /sys/fs/cgroup/cgroup.subtree_control echo 3G | sudo tee /sys/fs/cgroup/mysql/memory.high # 将 MySQL 进程加入 cgroup echo $(pgrep mysqld) | sudo tee /sys/fs/cgroup/mysql/cgroup.procs5.2 内核参数终极优化# 减少内存碎片化 echo vm.vfs_cache_pressure50 | sudo tee -a /etc/sysctl.conf echo vm.dirty_ratio10 | sudo tee -a /etc/sysctl.conf echo vm.dirty_background_ratio5 | sudo tee -a /etc/sysctl.conf # 应用所有修改 sudo sysctl -p6. 故障排查与应急方案当系统出现内存压力时按以下步骤排查快速诊断free -h top -o %MEM dmesg | grep oomMySQL 专用检查SHOW ENGINE INNODB STATUS\G SHOW GLOBAL STATUS LIKE Innodb_buffer_pool_wait%;紧急处理# 临时扩大 Swap sudo dd if/dev/zero of/swapfile2 bs1M count2048 sudo mkswap /swapfile2 sudo swapon /swapfile2 # 杀死最耗内存的进程 sudo kill -9 $(ps -eo pid,%mem --sort-%mem | head -n 2 | tail -n 1 | awk {print $1})在实际生产环境中我们曾遇到一个典型案例某电商平台的促销活动期间4GB 内存的数据库服务器通过合理配置 Swap 和 MySQL 参数成功扛住了平时 3 倍的流量冲击而之前同样配置的服务器因为没有优化 Swap 设置在流量高峰时频繁触发 OOM 导致服务不可用。