MySQL启用large-pages失败主因是内核未配vm.nr_hugepages、limits.conf未设memlock、systemd覆盖ulimit或mysqld非root/CAP_IPC_LOCK权限启动;需依次配置sysctl、limits、service文件,并在[mysqld]段写large-pages(无等号),再验证pmap和INNODB STATUS。

MySQL 启用 large-pages 失败的常见报错
直接启动 mysqld 时看到 Failed to set up huge pages 或 Cannot allocate memory for huge pages,基本是内核没配、权限不足、或 MySQL 用户没被授权访问大页。不是配置文件写对了就能跑起来。
- Linux 默认不启用透明大页(
transparent_hugepage),而 MySQLlarge-pages要求的是显式大页(hugetlbpage),两者不能混用 -
mysqld进程必须以 root 或有CAP_IPC_LOCK权限的用户启动,普通 mysql 用户默认锁不住大页内存 - 内核参数
vm.nr_hugepages必须提前分配,且值要 ≥ MySQL 预期申请量(比如 2MB 页 × 1024 = 2GB)
配置 /etc/sysctl.conf 和 /etc/security/limits.conf
这俩文件漏改一个,large-pages 就会静默退回到普通页——不会报错,但 SHOW VARIABLES LIKE 'large_pages' 显示 ON,实际没生效。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 在
/etc/sysctl.conf加:vm.nr_hugepages = 1024(按需调整,单位是 2MB 页) - 运行
sudo sysctl -p生效,再用cat /proc/meminfo | grep Huge确认HugePages_Total不为 0 - 在
/etc/security/limits.conf加两行:mysql soft memlock unlimited和mysql hard memlock unlimited(假设 MySQL 服务用户是mysql) - 重启
mysqld前,确保它由 systemd 启动时未覆盖 ulimit:检查/usr/lib/systemd/system/mysqld.service是否含LimitMEMLOCK=infinity
my.cnf 中开启 large-pages 的关键写法
large-pages 是 mysqld 启动时一次性申请的全局行为,不能动态 SET,也不支持只对 buffer pool 开启。配置写错位置或加了引号就无效。
- 必须放在
[mysqld]段下,写成large-pages(无等号、无值、无引号) - 不要写成
large-pages=ON或large_pages=1,MySQL 会忽略 - 搭配使用
innodb_buffer_pool_size时要注意:buffer pool 会被映射到大页,所以innodb_buffer_pool_size应该是大页大小的整数倍(如 2MB × N),否则剩余部分仍走普通页 - 启动后执行
SELECT @@large_pages;,返回 1 才算真正启用;再看SHOW ENGINE INNODB STATUS\G里是否有Large pages used字样
为什么有些机器开了 large-pages 反而变慢
大页不是银弹。在小内存、高并发短连接、或 NUMA 架构不均的机器上,反而可能增加延迟或引发 OOM。
- 大页无法 swap,一旦分配就常驻物理内存,
vm.swappiness=0是配套底线 - NUMA 系统下,若 mysqld 绑定在某个 node,但
vm.nr_hugepages分配在其他 node,会导致跨 node 访问,延迟飙升 - Percona Server 或 MariaDB 的
large-pages实现更激进,MySQL 官方版相对保守;5.7+ 支持更好,5.6 及更早版本容易因内存碎片失败 - 监控时别只盯
SHOW VARIABLES,用pmap -x $(pgrep mysqld)查 RSS 中有多少是hugepage标记的段
sysctl、漏一行 limits.conf、或者 systemd 的 memlock 被覆盖,都会让 MySQL 表面成功启动,实则退化回普通页,还很难察觉。

















