mysql的innodb_buffer_pool_size应设为可用内存的50%~60%,而非总内存的70%~80%;需在宝塔界面修改为如1536m并重启mysql,避免oom killer杀进程。

MySQL 的 innodb_buffer_pool_size 设定远超物理内存
宝塔面板默认会把 innodb_buffer_pool_size 设成总内存的 70%–80%,但这是给独占 MySQL 的服务器准备的。如果你的机器还跑着 Nginx、PHP、Python 应用甚至宝塔自身,这个值就非常危险——它不是“建议缓存大小”,而是 MySQL 启动时就直接 mmap 占用的内存块,且不轻易释放。
实操建议:
- 先查真实可用内存:
free -h看available列,不是total - 若机器有 4GB 内存,
available约 2.8GB,则innodb_buffer_pool_size最高设为1.5G(50%~60% available)更稳妥 - 修改位置:宝塔 → 数据库 → MySQL 设置 → 配置修改 → 找到
innodb_buffer_pool_size行,改成1536M(别写1.5G,MySQL 不认) - 改完必须重启 MySQL,光重载配置无效
MySQL 进程被系统 OOM killer 杀掉,日志里出现 Killed process mysqld
这不是 MySQL 崩溃,是 Linux 内核主动干掉它的——典型信号就是 dmesg -T | grep -i "killed process" 能搜到那行记录。根本原因往往是 innodb_buffer_pool_size + 其他连接内存(sort_buffer_size、join_buffer_size 等)叠加后突破了内存临界点。
实操建议:
- 检查当前连接消耗:
mysql -e "SHOW GLOBAL STATUS LIKE 'Threads_connected';",如果长期 >100,说明应用没正确复用连接 - 限制最大连接数:在 MySQL 配置里加
max_connections = 150(默认常是 151 或 200,对小内存机器太高) - 调低单连接内存参数:比如把
sort_buffer_size从默认的 2M 改成512K,read_buffer_size改成256K - 这些参数改完同样要重启 MySQL,且不能只改 my.cnf 里的注释行——宝塔的配置文件可能被自动覆盖,务必在宝塔界面里改并保存
宝塔面板里看不到 MySQL 实际内存占用,只显示“运行中”
宝塔的数据库列表页只显示进程状态,不反映 RSS 内存。你得绕出去看真实情况。
实操建议:
- 用
ps aux --sort=-%mem | head -n 10查内存 Top 进程,重点关注mysqld行的%MEM和VSZ/RSS列 -
RSS(Resident Set Size)才是真实占用的物理内存,如果接近或超过innodb_buffer_pool_size+ 1G,基本就是过载了 - 别信
top里 MySQL 的 “%CPU” 高就等于内存高——它可能 CPU 很低,但 RSS 悄悄顶到 3GB - 想持续监控?用
watch -n 2 'ps -o pid,user,%mem,rss,vsz,comm -C mysqld',每 2 秒刷一次
调整后 MySQL 启动失败,报错 Cannot allocate memory for the buffer pool
这说明你设的 innodb_buffer_pool_size 超过了系统能分配的连续内存页,尤其常见于开了 swap 但碎片严重,或内核参数 vm.swappiness 过低(比如设成 1)的环境。
实操建议:
- 临时验证:用
sudo sysctl vm.swappiness=60提高换页倾向(重启后失效),再试启动 - 永久生效:编辑
/etc/sysctl.conf,加一行vm.swappiness=60,然后sudo sysctl -p - 别关 swap——小内存机器关 swap 反而更容易触发 OOM killer
- 如果仍失败,把
innodb_buffer_pool_size再砍一刀,比如从1536M改成1024M,优先保服务起来
innodb_buffer_pool_size 是杠杆支点,但撬动它的还有 PHP-FPM 的 pm.max_children、Nginx 的 worker_connections、甚至宝塔后台任务的轮询频率——它们都在悄悄分走同一块物理内存。调参前先看 free -h 和 ps aux,比直接翻配置文件管用得多。










