2g内存vps部署mysql 8.0必须将innodb_buffer_pool_size设为512m、innodb_buffer_pool_instances=1,并压低sort_buffer_size、join_buffer_size至128k,max_connections=100,关闭performance_schema,否则极易oom崩溃。

2G内存的VPS上跑MySQL 8.0,不调参基本等于自爆——innodb_buffer_pool_size默认可能被设成1.4G,再加几十个连接,sort_buffer_size和join_buffer_size一叠,swap立刻开始狂刷,查询延迟直接跳到秒级。
查清当前内存真实去向
别信ps aux里那个RES值,MySQL很多内存是“占着不还”的。先连进MySQL执行:
SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool_size'; SHOW GLOBAL VARIABLES LIKE '%buffer%'; SHOW GLOBAL STATUS LIKE 'Threads_connected';
重点看三个数:innodb_buffer_pool_size(全局大头)、sort_buffer_size(单连接排序缓存)、Threads_connected(当前连接数)。如果后者是80,而sort_buffer_size是2M,光这一项就吃掉160MB——这还没算join_buffer_size和read_rnd_buffer_size。
- 用
mysqladmin -u root -p extended-status | grep -E "Created_tmp_disk_tables|Innodb_buffer_pool_reads"确认是否频繁下盘或缓冲池命中率低 -
performance_schema默认开启且吃内存,小机器建议关掉:在my.cnf加performance_schema = OFF - 不要用
top或htop直接判断MySQL内存压力,它们显示的是虚拟内存映射,得结合SHOW ENGINE INNODB STATUS里的“BUFFER POOL AND MEMORY”段看实际使用量
砍掉全局缓冲的冗余配置
2G内存不是“分给MySQL 1.5G就行”,得给系统、SSH、Nginx、PHP留足至少512MB。全局缓冲必须做减法:
-
innodb_buffer_pool_size设为512M(不是70%,更不是1G)——这是2G机器的临界安全值;设太高会导致OOM Killer干掉mysqld进程 -
innodb_buffer_pool_instances必须同步调小,设为1(默认可能是8),否则每个实例最低也占几MB,纯属浪费 -
table_open_cache和table_definition_cache按实际表数设:如果你只有30张表,table_open_cache = 64、table_definition_cache = 150足够,设成1000会白吃上百MB -
key_buffer_size设为8M或干脆0(除非你真用MyISAM,现在基本没有)
严格控制每个连接的私有内存
连接数一上来,线程缓冲就是“隐形炸弹”。默认sort_buffer_size=256K看着小,但200连接就是50MB;join_buffer_size=256K同理。必须压低:
-
sort_buffer_size = 128K(复杂ORDER BY才需加大,日常够用) -
join_buffer_size = 128K(NLJ算法下,这个值够大多数两表JOIN) -
read_buffer_size = 64K、read_rnd_buffer_size = 128K(顺序/随机读,小值不影响性能,只防内存堆叠) -
max_connections = 100(宁可让新连接等,也不要让它进来吃内存) - 配合
wait_timeout = 60,快速回收空闲连接,避免长连接持续占着缓冲区
临时表与日志策略要务实
临时表下盘、redo log刷写慢,都会把内存压力转成IO压力,最终拖垮整个系统:
-
tmp_table_size和max_heap_table_size统一设为32M(不是默认16M,也不是64M)——太小导致频繁下盘,太大又撑爆内存 -
innodb_log_file_size别乱调大,2G内存机器保持默认48M即可;改大反而增加恢复时间,且日志文件本身也占磁盘+内存映射 -
innodb_flush_log_at_trx_commit = 1必须保留(保证ACID),但别为了“省IO”改成2——数据丢不起,小机器扛不住的其实是并发连接,不是日志刷写频率 - 二进制日志
binlog_cache_size设为1M,max_binlog_size保持默认100M,避免日志碎片过多影响purge
最易被忽略的一点:innodb_buffer_pool_size可以在线调整,但sort_buffer_size这类会话级参数,改完配置必须重启MySQL才能生效——很多人改了以为立刻起效,其实旧连接还在用老值,得等连接自然断开或主动KILL掉。











