mysql启用large-pages失败主因是内核未预分配大页、mysql用户无memlock权限或systemd服务缺失cap_ipc_lock能力;需依次配置vm.nr_hugepages、limits.conf和service文件,large-pages须为[mysqld]段内独立布尔项,验证需查@@large_pages值及innodb status中的“large pages used”。

MySQL 启动失败并报 Failed to set up huge pages 或 Cannot allocate memory for huge pages,基本可以断定不是配置写错了,而是底层大页资源根本没准备好——内核没分配、权限没给够、或 systemd 拦截了限制。静默退回到普通页是常态,SELECT @@large_pages; 返回 1 才算真正生效。
检查 vm.nr_hugepages 是否已分配且不过量
大页内存由内核预分配,必须在 MySQL 启动前就存在,且总量不能超过物理内存。常见错误是设得太大,比如 vm.nr_hugepages=2820(≈5.5GB)而系统只有 1.8GB 内存,会导致系统启动失败甚至卡死在 rescue 模式。
- 查当前分配:
cat /proc/meminfo | grep -i huge,确认HugePages_Total> 0 - 估算需求数:按
innodb_buffer_pool_size+ 10% 算,每页默认 2MB,例如 buffer pool 设为 4G,则至少要4096 / 2 + 10% ≈ 2250页 - 写入
/etc/sysctl.conf并生效:echo "vm.nr_hugepages = 2048" >> /etc/sysctl.conf && sysctl -p - 切忌直接写超限值,RHEL/CentOS 上过大值可能让系统无法正常启动,需进 rescue 模式修复
确认 MySQL 用户有 memlock 权限
即使内核给了大页,MySQL 进程也得有锁住它们的权限,否则照样 fallback。Linux 的 memlock 限制默认极低(通常 64KB),必须显式放开。
- 编辑
/etc/security/limits.conf,追加两行(假设运行用户是mysql):mysql soft memlock unlimitedmysql hard memlock unlimited - 该设置对 systemd 启动的服务无效——因为 systemd 会覆盖 ulimit,所以这步只是基础,不能替代下一步
- 验证是否生效:用
su - mysql -c 'ulimit -l'查看,返回unlimited或极大数值(如 18446744073709551615)才算成功
检查 systemd service 文件是否放行 CAP_IPC_LOCK
MySQL 必须以具备 CAP_IPC_LOCK 能力的用户启动,才能锁定大页。systemd 默认不授予该能力,且会屏蔽 limits.conf 中的 memlock 设置。
- 检查服务文件,如
/usr/lib/systemd/system/mysqld.service或/etc/systemd/system/mysqld.service - 确保含这两行:
LimitMEMLOCK=infinityCapabilityBoundingSet=CAP_IPC_LOCK - 改完后执行:
systemctl daemon-reload && systemctl restart mysqld - 若漏掉
CapabilityBoundingSet,即使ulimit -l显示 unlimited,MySQL 仍拿不到大页,日志里还是报错
验证 large-pages 配置写法与实际生效状态
large-pages 是个脆弱的布尔开关,写错一个字符就静默失效,且无法动态开启。它不接受等号、值、引号,也不支持放在其他段落里。
- 只允许出现在
[mysqld]段内,且必须是独立一行:large-pages - 禁止写法:
large-pages=1、large_pages=ON、large-pages="1"、set-variable=large-pages - 启动后立刻验证:
执行SELECT @@large_pages;—— 返回1才算配置被识别
再执行SHOW ENGINE INNODB STATUS\G,搜索输出中是否有Large pages used - 注意:如果
innodb_buffer_pool_size不是大页大小(默认 2MB)的整数倍,剩余部分仍走普通页,性能提升打折扣
最容易被忽略的是三者缺一不可:内核预分配、用户 memlock 权限、systemd 的 CAP_IPC_LOCK 授权。少一个,large-pages 就只是个摆设,MySQL 日志里也不会明确告诉你缺哪块——它只会安静地退回小页模式。











