Skip to content

mysql 内存占用高排查

  • 最近发现 mysql 的内存占用一直在逐渐增加,一开始重启完是 400 MB 左右,后面几天时间内就涨到了 2.4 G,然而跟着一些博客排查mysql内部却没发现什么问题。这里记录最终有效的操作。

缓存占用过多

  • my.conf 中可以调整缓存限制。
  • 但如果放宽之后发现系统的内存缓存居高不下,很可能说明mysql真的需要很多缓存,由于前面配置限制太小,导致mysql需要经常从硬盘重新读取然后切换放入缓存,因此系统的文件缓存会比较大。
    • 那这种情况下要么是真的数据比较多了,是该升级硬件了。要么是索引搞太多、表单行数据过大:
    • 检查全文索引等比较占用空间的索引大小
    • 如果表单行某些字段存放比较大的数据,比如 TEXT、json,但用的不多,在查询其他字段时,mysql会连带缓存整行,所以会导致缓存占用很多,可以拆分多表解决。
  • 实际操作了一下,发现某个表确实缓存占用很大,但索引还行,所以搞了分表,把大字段拉出来,现在好了很多,但仍然会随着时间逐渐增加。

glibc 内存碎片

  • 部分博客提到了 mysql 默认使用的 glibc 存在内存碎片问题,导致内存并未归还给系统,因此逐渐升高。
  • 我们可以手动触发其回收,但注意,生产环境谨慎使用:
sh
gdb --batch --pid `pidof mysqld` --ex 'call malloc_trim(0)'
  • 这个的效果很明显,直接从 2.4 g 降低到 1.5 g
  • 也有博客提到可以更换使用 jmalloc 解决。
  • 但每次手动回收不是长久之计

关闭 PFS

  • PFS(performance schema)是 mysql 的性能监控工具,但它也会占用内存和额外的 CPU。
  • 可以修改 /etc/mysql/my.cnf 文件:
txt
[mysqld]
performance_schema = OFF
  • 然后重启 mysqld :
sh
sudo systemctl restart mysql
  • 我这边已经关闭,等过一段时间看看效果。
  • 验证了没用,减少的不多,但少了很多排查问题的办法,建议恢复开启。