如何在大内存服务器上通过配置MySQL的huge pages优化其性能?

2026-04-30 10:592阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计892个文字,预计阅读时间需要4分钟。

如何在大内存服务器上通过配置MySQL的huge pages优化其性能?

MySQL 在大内存服务器上启用 `large-pages` 不等同于增加一行配置即生效。多数失败案例根本原因是没有使用上大页 —— 通过 `SHOW VARIABLES LIKE 'large_pages'` 显示 `ON`,但执行 `/proc/meminfo` 里的 `HugePages_Free` 未变、在 `INNODB STATUS` 里也没有 `Large pages used`,即典型静默默认 fallback。

确认内核是否真正支持显式大页(hugetlbpage)

透明大页(transparent_hugepage)和 MySQL 要的显式大页(hugetlbpage)完全不兼容,不能混用。必须确认内核编译时启用了 CONFIG_HUGETLB_PAGE=y

  • 运行 grep -i hugetlb /boot/config-$(uname -r),有输出才表示支持;无输出就得换内核或重编译
  • 再看 cat /proc/meminfo | grep -i huge:如果 Hugepagesize 是空或报错,说明底层未启用;HugePages_Total: 0 只是还没分配,不算问题
  • 别信 echo 1024 > /proc/sys/vm/nr_hugepages 成功就完事——若 HugePages_Free 不变,大概率是物理内存不连续,尤其在长期运行的生产机上;最稳做法是重启后立刻配

计算并分配足够且不过量的 vm.nr_hugepages

配少了 MySQL 启动时 fallback 到 4KB 页;配多了浪费内存、还可能挤占其他服务。关键不是“全内存”,而是覆盖 MySQL 实际申请的共享内存段:

  • 主要来源是 innodb_buffer_pool_size,加上 key_buffer_sizeinnodb_log_buffer_sizeperformance_schema.memory 等,再上浮 10%
  • 假设总需求 32GB,Hugepagesize 是 2048 kB,则需 vm.nr_hugepages = 32 * 1024 / 2 = 16384
  • 写入 /etc/sysctl.conf:`vm.nr_hugepages = 16384`,再执行 sudo sysctl -p
  • 验证:cat /proc/meminfo | grep -i "hugepages_total\|hugepagesize",确保值匹配

确保 mysqld 进程能锁住并使用大页

即使内核配好了,MySQL 进程没权限也白搭。三个环节缺一不可:

  • /etc/security/limits.conf 必须加两行(假设用户是 mysql):
    mysql soft memlock unlimited
    mysql hard memlock unlimited
  • systemd 启动时会覆盖 ulimit,检查 /usr/lib/systemd/system/mysqld.service 是否含 LimitMEMLOCK=infinity;没有就加,并 sudo systemctl daemon-reload
  • my.cnf[mysqld] 段下只写 large-pages(无等号、无值、无引号),写成 large-pages=ONlarge_pages=1 全部无效

验证是否真生效,而非假 ON

SELECT @@large_pages; 返回 1 只代表配置被读取,不代表内存已映射。必须交叉验证:

  • 查进程状态:cat /proc/$(pidof mysqld)/status | grep -i hugetlb,值 > 0 才算真用上
  • 查 InnoDB 状态:SHOW ENGINE INNODB STATUS\G,搜索 Large pages used 字样
  • 查系统级占用:cat /proc/meminfo | grep -i "hugepages_free",启动后应比初始值减少(减少量 ≈ buffer pool 占用页数)
  • 注意:innodb_buffer_pool_size 最好设为大页大小整数倍(如 2MB × N),否则余数部分仍走 4KB 页

最容易被忽略的是 systemd 的 LimitMEMLOCK 覆盖和 limits.conf 权限漏配——这两个一漏,large-pages 就是纸面功能,连 pmap 都看不到大页映射。别只盯着 my.cnf。

标签:Mysql

本文共计892个文字,预计阅读时间需要4分钟。

如何在大内存服务器上通过配置MySQL的huge pages优化其性能?

MySQL 在大内存服务器上启用 `large-pages` 不等同于增加一行配置即生效。多数失败案例根本原因是没有使用上大页 —— 通过 `SHOW VARIABLES LIKE 'large_pages'` 显示 `ON`,但执行 `/proc/meminfo` 里的 `HugePages_Free` 未变、在 `INNODB STATUS` 里也没有 `Large pages used`,即典型静默默认 fallback。

确认内核是否真正支持显式大页(hugetlbpage)

透明大页(transparent_hugepage)和 MySQL 要的显式大页(hugetlbpage)完全不兼容,不能混用。必须确认内核编译时启用了 CONFIG_HUGETLB_PAGE=y

  • 运行 grep -i hugetlb /boot/config-$(uname -r),有输出才表示支持;无输出就得换内核或重编译
  • 再看 cat /proc/meminfo | grep -i huge:如果 Hugepagesize 是空或报错,说明底层未启用;HugePages_Total: 0 只是还没分配,不算问题
  • 别信 echo 1024 > /proc/sys/vm/nr_hugepages 成功就完事——若 HugePages_Free 不变,大概率是物理内存不连续,尤其在长期运行的生产机上;最稳做法是重启后立刻配

计算并分配足够且不过量的 vm.nr_hugepages

配少了 MySQL 启动时 fallback 到 4KB 页;配多了浪费内存、还可能挤占其他服务。关键不是“全内存”,而是覆盖 MySQL 实际申请的共享内存段:

  • 主要来源是 innodb_buffer_pool_size,加上 key_buffer_sizeinnodb_log_buffer_sizeperformance_schema.memory 等,再上浮 10%
  • 假设总需求 32GB,Hugepagesize 是 2048 kB,则需 vm.nr_hugepages = 32 * 1024 / 2 = 16384
  • 写入 /etc/sysctl.conf:`vm.nr_hugepages = 16384`,再执行 sudo sysctl -p
  • 验证:cat /proc/meminfo | grep -i "hugepages_total\|hugepagesize",确保值匹配

确保 mysqld 进程能锁住并使用大页

即使内核配好了,MySQL 进程没权限也白搭。三个环节缺一不可:

  • /etc/security/limits.conf 必须加两行(假设用户是 mysql):
    mysql soft memlock unlimited
    mysql hard memlock unlimited
  • systemd 启动时会覆盖 ulimit,检查 /usr/lib/systemd/system/mysqld.service 是否含 LimitMEMLOCK=infinity;没有就加,并 sudo systemctl daemon-reload
  • my.cnf[mysqld] 段下只写 large-pages(无等号、无值、无引号),写成 large-pages=ONlarge_pages=1 全部无效

验证是否真生效,而非假 ON

SELECT @@large_pages; 返回 1 只代表配置被读取,不代表内存已映射。必须交叉验证:

  • 查进程状态:cat /proc/$(pidof mysqld)/status | grep -i hugetlb,值 > 0 才算真用上
  • 查 InnoDB 状态:SHOW ENGINE INNODB STATUS\G,搜索 Large pages used 字样
  • 查系统级占用:cat /proc/meminfo | grep -i "hugepages_free",启动后应比初始值减少(减少量 ≈ buffer pool 占用页数)
  • 注意:innodb_buffer_pool_size 最好设为大页大小整数倍(如 2MB × N),否则余数部分仍走 4KB 页

最容易被忽略的是 systemd 的 LimitMEMLOCK 覆盖和 limits.conf 权限漏配——这两个一漏,large-pages 就是纸面功能,连 pmap 都看不到大页映射。别只盯着 my.cnf。

标签:Mysql