必须先确认内核支持HugePages,再依次配置预分配页数、memlock权限、systemd能力及MySQL参数;需验证CONFIG_HUGETLB_PAGE=y、/proc/meminfo含HugePages_Total字段、/proc/sys/vm/hugetlb_shm_group可写,否则large-pages静默失效。

必须先确认内核已启用 HugePages 支持,再按顺序配置预分配页数、用户锁内存权限、systemd 能力与 MySQL 参数;任意一环缺失都会导致 large-pages 静默失效。
检查内核是否真正支持 HugePages
别只看 /proc/meminfo 里有 Hugepagesize 就以为 OK。实际要验证三件事:
- 运行
grep -i huge /boot/config-$(uname -r),确保输出包含CONFIG_HUGETLB_PAGE=y和CONFIG_HUGETLB_PAGE_SIZE_2MB=y - 执行
cat /proc/meminfo | grep -i "HugePages_Total",初始值为 0 是正常的,但字段必须存在 - 检查
ls /proc/sys/vm/hugetlb_shm_group是否可写,不存在说明 hugetlbfs 子系统未激活(需重编译内核或换发行版)
预分配 2MB 大页并禁用 THP
MySQL 只认 2MB 页(即使你配了 1GB),且透明大页(THP)会干扰 InnoDB 的显式大页申请,必须关掉:
- 临时分配:用
echo 4096 | sudo tee /proc/sys/vm/nr_hugepages(按ceil((innodb_buffer_pool_size * 1.1) / 2097152)算,单位是页) - 永久生效:在
/etc/default/grub的GRUB_CMDLINE_LINUX行末加default_hugepagesz=2M hugepagesz=2M hugepages=4096,再跑sudo update-grub && sudo reboot - 禁用 THP:向
/sys/kernel/mm/transparent_hugepage/enabled写入never,并加到/etc/rc.local或 systemd boot service 中
授予 MySQL 用户锁定内存权限
systemd 服务会覆盖 limits.conf,所以必须双管齐下:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 在
/etc/security/limits.conf加两行:mysql soft memlock unlimited和mysql hard memlock unlimited - 编辑
/usr/lib/systemd/system/mysqld.service(路径依发行版可能为/etc/systemd/system/mysqld.service),确保含以下两行:LimitMEMLOCK=infinityCapabilityBoundingSet=CAP_IPC_LOCK - 重载配置:
sudo systemctl daemon-reload && sudo systemctl restart mysqld
MySQL 启动参数与验证要点
my.cnf 里写错格式或漏掉关键项,large-pages 就不会生效,且无报错日志:
-
[mysqld]段下只写一行:large-pages(不能带=1、不能加引号、不能缩进) - 启动后立刻查 SQL:
SELECT @@large_pages;—— 返回1才算成功 - 进一步验证:
SHOW ENGINE INNODB STATUS\G,搜索Large pages used;同时看cat /proc/meminfo | grep HugePages_Free是否下降 - 若
HugePages_Free不变,但进程smaps里AnonHugePages有值,说明用的是 THP,不是你配的 HugeTLB —— 那就是 THP 没关干净
最易被忽略的是 hugetlb_shm_group:MySQL 启动时用 shmget 分配共享内存,不设这个组 ID,哪怕其他全对,也会 fallback 到普通页。查 MySQL 进程 gid:ps -o pid,gid,comm -C mysqld,然后 echo ,并写入 /etc/sysctl.conf 持久化。










