mysql 8.0 启用 large-pages 需同时满足内核大页配置、用户 memlock 权限、systemd limitmemlock 设置及 my.cnf 中严格语法(仅写 large-pages),缺一不可;否则 show variables 显示 on 但 pmap 或 innodb status 无大页使用痕迹。

MySQL 8.0 要真正用上 large-pages,光在 my.cnf 里写一行就完事?不行。90% 的失败案例都卡在内核参数、用户权限、systemd 限制这三关——SHOW VARIABLES LIKE 'large_pages' 显示 ON,但 pmap -x $(pidof mysqld) | grep huge 没输出,或 INNODB STATUS 里找不到 Large pages used,说明根本没生效。
确认系统支持并查看当前 HugePages 状态
别跳过这步。很多机器 Hugepagesize 是 2048 kB(即 2MB),但有些新 CPU 支持 1GB 大页,而 MySQL 8.0 只认 2MB 页;如果 /proc/meminfo 里 Hugepagesize 是 0 或空,说明内核没启用 hugetlbfs 支持(极少见,但 RHEL/CentOS 6 默认关闭)。
- 运行
grep -i huge /proc/meminfo,重点看HugePages_Total和Hugepagesize - 若
HugePages_Total: 0,且Hugepagesize: 2048 kB,说明支持但未分配——可以继续 - 若
Hugepagesize: 0,需检查内核是否编译了CONFIG_HUGETLB_PAGE=y,或换用标准发行版内核(Ubuntu/Debian/CentOS 7+ 默认支持) -
AnonHugePages是透明大页(THP)的用量,MySQL 不用它;配置前建议先禁用 THP:echo never > /sys/kernel/mm/transparent_hugepage/enabled
分配大页池并设置 mysql 用户锁页权限
MySQL 进程必须能「锁定」物理大页内存,否则即使内核有页,mysqld 也申请不到。这需要三重保障:内核预留页数、用户 memlock 上限、以及(可选但推荐)hugetlb_shm_group 组授权。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 算好页数:假设
innodb_buffer_pool_size = 20G,用 2MB 页,则至少要20 * 1024 / 2 = 1024页。实际多留 5%~10%,设为1100 - 写入
/etc/sysctl.conf:vm.nr_hugepages = 1100,然后执行sudo sysctl -p - 检查生效:
cat /proc/meminfo | grep HugePages_Total应返回1100 - 在
/etc/security/limits.conf加两行:mysql soft memlock unlimited和mysql hard memlock unlimited(注意用户名要和mysqld实际运行用户一致,如mysqld服务文件里User=指定的) - 如果用 systemd 启动,必须补上
LimitMEMLOCK=infinity到/usr/lib/systemd/system/mysqld.service的[Service]段,否则 limits.conf 被忽略
my.cnf 中正确启用 large-pages
MySQL 8.0 的 large-pages 是启动时一次性行为,不支持动态开启,且语法极其严格:不能带等号、不能加引号、不能写在错误段落里。
- 只允许出现在
[mysqld]段下,写成:large-pages(纯关键字,无值) - 禁止写法:
large-pages=ON、large_pages=1、"large-pages"、large-pages = 1—— 全部静默失效 - 确保
innodb_buffer_pool_size是 2MB 的整数倍(如2048M、4096M),否则剩余部分仍走普通页,浪费且难排查 - 重启前先停掉 mysqld:
sudo systemctl stop mysqld,再启动,避免残留进程干扰
验证是否真生效,而非假 ON
SELECT @@large_pages; 返回 1 只代表配置被读取,不代表内存已映射。真生效必须看到物理页被占用、且 InnoDB 主动使用。
- 查进程内存映射:
pmap -x $(pidof mysqld) | grep huge,应有若干行输出,每行 size ≥ 2048 KB - 进 MySQL 执行:
SHOW ENGINE INNODB STATUS\G,搜索Large pages used字样,出现即表示 buffer pool 已成功落在大页上 - 对比
/proc/meminfo:启动前后HugePages_Free应明显减少(如从 1100 → 1024),差值 ≈ buffer pool 占用页数 - 如果
HugePages_Free不变,大概率是mysqld启动用户没权限锁页,或 systemd 的LimitMEMLOCK没配
最易被忽略的一点:MySQL 的 large-pages 只作用于 InnoDB buffer pool 和额外内存池(如 log buffer),不覆盖连接线程栈、sort buffer 等。所以即使全开,PageTables 值下降幅度也有限——要看 /proc/meminfo 的 PageTables 是否显著降低(比如从 40MB → 5MB),才是 TLB 压力真正缓解的信号。










