禁用透明的大页面


63

我们正在RAID机器中安装SAP HANA 。作为安装步骤的一部分,提到:

 To disable the usage of transparent hugepages set the kernel settings 
 at runtime with echo never > /sys/kernel/mm/transparent_hugepage/enabled 

因此,如果要永久更改而不是运行时,是否应该在/proc/vmstat文件中添加以上行?


2
请注意,如果您在使用此处提到的某些解决方案,那么在还运行“调整”的系统上,调整可能会覆盖这些解决方案。有关更多信息,请参见此处:bugzilla.redhat.com/show_bug.cgi?
id

Answers:


80

为了使这样的选项永久化,通常将它们添加到文件中/etc/sysctl.conf。您可以使用此命令查看可用选项的完整列表:

$ sysctl -a

$ sudo sysctl -a | head -5
kernel.sched_child_runs_first = 0
kernel.sched_min_granularity_ns = 6000000
kernel.sched_latency_ns = 18000000
kernel.sched_wakeup_granularity_ns = 3000000
kernel.sched_shares_ratelimit = 750000

您可以hugepage像这样在输出中查找:

$ sudo sysctl -a | grep hugepage
vm.nr_hugepages = 0
vm.nr_hugepages_mempolicy = 0
vm.hugepages_treat_as_movable = 0
vm.nr_overcommit_hugepages = 0

不在那里吗?

但是通过输出我没有看到transparent_hugepage。在Google上,我确实浏览了更多Oracle网页,其中讨论了这个主题。该页面的标题为:在Linux(x86-64)上为Oracle配置HugePages

特别是在该页面上,他们提到了如何禁用大页面功能

摘抄

禁用“透明HugePages”的首选方法是在“ /etc/grub.conf”文件的内核引导行中添加“ transparent_hugepage = never”。

   title Oracle Linux Server (2.6.39-400.24.1.el6uek.x86_64)
            root (hd0,0)
            kernel /vmlinuz-2.6.39-400.24.1.el6uek.x86_64 ro root=/dev/mapper/vg_ol6112-lv_root rd_NO_LUKS  KEYBOARDTYPE=pc KEYTABLE=uk
    LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16  rd_NO_DM rd_LVM_LV=vg_ol6112/lv_swap rd_LVM_LV=vg_ol6112/lv_root rhgb quiet numa=off
    transparent_hugepage=never
            initrd /initramfs-2.6.39-400.24.1.el6uek.x86_64.img

必须重新引导服务器才能生效。

或者,您可以将命令添加到/etc/rc.local文件中。

if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
   echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
   echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi

我想我会选择第二个选项,因为当您从一个内核升级到下一个内核时,第一个选项有被设置的风险。

重新启动后,您可以确认它与以下命令一起使用:

$ cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]

6
通过在大多数发行版的/ etc / default / grub中的GRUB_CMDLINE_LINUX_DEFAULT选项中添加transparent_hugepage = never,可以使第一个选项在内核更新后仍然有效。
2014年

1
如果输出cat /sys/kernel/mm/transparent_hugepage/enabled[always] madvise never,则状态为always或已启用(请注意[]括号中的内容always
ub3rst4r 2014年

4
不要混淆大页面和透明大页面。后者会引起很多问题,主要是CPU使用率过高,同时不断尝试对内存进行碎片整理并将正常的4kB页面转换为巨大的2MB页面。
Marki555

2
@Rwky-根据您的建议进行调整时-我强调在保存文件后的下一个动作是执行sudo update-grub以获取新的设置“用石头写”。+1指向grub文件行。
法伦2015年

2
作为EC2上的更新,cloudimg添加了/etc/default/grub.d/50-cloudimg-settings.cfg文件,该文件覆盖了/ etc / default / grub中的设置,并添加了文件/etc/default/grub.d/内容为GRUB_CMDLINE_LINUX_DEFAULT =“ $ GRUB_CMDLINE_LINUX_DEFAULT transparent_hugepage = never”的99-transparent-hugepage.cfg将解决此问题。
Rwky

13

我只是想添加这个问题,因为我试图在CentOS v6上禁用透明的大页面,以便为MariaDB启用TokuDB。我添加了@slm提到的脚本/etc/rc.local,它禁用了透明的大页面。但是,由于启动脚本在Linux中的工作方式,/etc/rc.local是在启动所有服务之后执行的。因此,在MariaDB已经启动并且TokuDB引擎不会初始化之后,透明的大页面被禁用了。禁用透明大页面的唯一其他方法是添加transparent_hugepage=never到内核​​参数。

我注意到@Rwky的评论You can make the first option survive kernel updates by adding transparent_hugepage=never to the GRUB_CMDLINE_LINUX_DEFAULT option in /etc/default/grub on most distributions.,发现CentOS不支持该/etc/default/grub文件,并且担心transparent_hugepage=never在更新时从内核参数中消失。但不必担心,CentOS设置为将对grub中的内核参数所做的任何更改都保留在其中,因此在更新时,这些更改将被保留。

另外,修改grub内核参数的正确方法是使用grubby。我创建了这个简单的脚本来添加transparent_hugepage=never到每个内核grubby

#!/bin/sh

if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi

for KERNEL in /boot/vmlinuz-*; do
    grubby --update-kernel="$KERNEL" --args='transparent_hugepage=never'
done

对于这样的选项,我仍可能会尝试将其添加到/中,etc/sysctl.conf因为这将始终适用于可能安装在包装盒上的任何内核。
slm

我只是想补充一下,如果您修改<code> / etc / default / grub </ code>文件,则需要以grub-mkconfig“ root”身份运行以生成grub的实际配置文件。
seattlegaucho 2014年

3
对于EC2 ubuntu实例,我必须修改/etc/default/grub.d/50-cloudimg-settings.cfg文件而不是/etc/default/grub使其生效。
zhengyue 2015年

我正在使用CentOS 6.6。我已经修改了,/etc/rc.local但是对我不起作用。能否请您向我解释根本原因。
Sandeep Singh 2015年

@ s.singh正如我所说,/etc/rc.local is executed after all the services are started因此需要在内核级别禁用它
ub3rst4r 2015年

6

这是使用puppet的实现:

exec { "disable_transparent_hugepage_enabled":
  command => "/bin/echo never > /sys/kernel/mm/transparent_hugepage/enabled",
  unless  => "/bin/grep -c '\[never\]' /sys/kernel/mm/transparent_hugepage/enabled 2>/dev/null",
}

exec { "disable_transparent_hugepage_defrag":
  command => "/bin/echo never > /sys/kernel/mm/transparent_hugepage/defrag",
  unless  => "/bin/grep -c '\[never\]' /sys/kernel/mm/transparent_hugepage/defrag 2>/dev/null",
}

6

在EC2 Ubuntu 16.04上,以上所有内容均不适用于我,但这确实可行:

sudo apt install hugepages
sudo hugeadm --thp-never

4

由于内核行transparent_hugepage=never仅禁用了我所需要的一半(两者都使恼人的mongodb故障/日志丢失),因此我没有在systemd启动脚本中坚持下来,但是现在有了:echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled。它可以在systemctl启动脚本(正确配置为in in /etc/systemd/system)中运行,也可以直接从cli中运行。


您能否扩展说明以包含“正确配置的脚本”以及如何设置所有内容的步骤?MongoDB的官方说明docs.mongodb.org/manual/tutorial/transparent-huge-pages显示了旧方法,尽管现在systemd更常见,但最好以systemd方式使用它。
ssasa

3

如果是Redis,它还会发出警告,建议禁用THP。但是,如错误报告所述,许多发行版/etc/rc.local是在服务之后执行的,并且在它们重新启动之前不会对其产生影响。还要注意,在虚拟环境(例如Digitalocean)中,您无法控制GRUB设置。

在这种情况下的解决方法是使用专用的init脚本来禁用透明大内存页该页面显示,由设置X-Start-Before。例如,Redis的Debian 初始化脚本:

#!/bin/bash
### BEGIN INIT INFO
# Provides:          disable-thp
# Required-Start:    $local_fs
# Required-Stop:
# X-Start-Before:    redis-server
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Disable THP
# Description:       disables Transparent Huge Pages (THP) on boot
### END INIT INFO

case $1 in
start)
  if [ -d /sys/kernel/mm/transparent_hugepage ]; then
    echo 'never' > /sys/kernel/mm/transparent_hugepage/enabled
    echo 'never' > /sys/kernel/mm/transparent_hugepage/defrag
  else
    return 0
  fi
;;
esac 

正是我想要的。
nelaaro

2

感谢githubPyYoshi
我找到了systemd的这个例子

创建文件

sudo vim /etc/systemd/system/disable-transparent-huge-pages.service

将此放入服务文件

[Unit]
Description=Disable Transparent Huge Pages

[Service]
Type=oneshot
ExecStart=/usr/bin/sh -c "/usr/bin/echo "never" | tee /sys/kernel/mm/transparent_hugepage/enabled"
ExecStart=/usr/bin/sh -c "/usr/bin/echo "never" | tee /sys/kernel/mm/transparent_hugepage/defrag"

[Install]
WantedBy=multi-user.target

对于debian / ubuntu用户

[Unit]
Description=Disable Transparent Huge Pages

[Service]
Type=oneshot
ExecStart=/bin/sh -c "/usr/bin/echo "never" | tee /sys/kernel/mm/transparent_hugepage/enabled"
ExecStart=/bin/sh -c "/usr/bin/echo "never" | tee /sys/kernel/mm/transparent_hugepage/defrag"

[Install]
WantedBy=multi-user.target

然后启用服务

systemctl enable disable-transparent-huge-pages
systemctl start disable-transparent-huge-pages
systemctl status disable-transparent-huge-pages

1

如果遇到问题

-bash: /sys/kernel/mm/transparent_hugepage/khugepaged/defrag: Permission denied

即使使用sudo,也请尝试以下命令:

sudo /bin/bash -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled'
sudo /bin/bash -c 'echo never > /sys/kernel/mm/transparent_hugepage/defrag'

嗨,欢迎使用Unix SE!注意,如果您还要解释命令的作用,那就更好了。
user259412 '18

1

这是Ansible的快速技巧(我不想管理的模板/etc/rc.local):

- name: Disable Transparent Huge Pages at boot
  lineinfile:
    dest: /etc/rc.local
    line: "if [ -d /sys/kernel/mm/transparent_hugepage ]; then echo 'never' > /sys/kernel/mm/transparent_hugepage/enabled ; echo 'never' > /sys/kernel/mm/transparent_hugepage/defrag ; fi"
  register: transparent_hugepage
- name: Disable disabled rc.local
  lineinfile:
    dest: /etc/rc.local
    line: 'exit 0'
    state: absent
- name: Disable Transparent Huge Pages at run time 1/2
  command: echo never > /sys/kernel/mm/transparent_hugepage/defrag
  when: transparent_hugepage|changed
- name: Disable Transparent Huge Pages at run time 2/2
  command: echo never > /sys/kernel/mm/transparent_hugepage/enabled
  when: transparent_hugepage|changed

0

在带有YAST和GRUB引导程序的SLES11 SP3中,我们必须transparent_hugepage=never在[YAST-bootloader-edit-line中带有可选的内核参数]中添加。注意:此工具更改文件/boot/grub/menu.lst

仅在进行此更改并重新启动后,才会禁用THP。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.