56

I use mongodb 3.0 and I find a warning:

MongoDB shell version: 3.0.0
connecting to: test
Server has startup warnings: 
2015-03-13T16:28:29.405+0800 I CONTROL  [initandlisten] 
2015-03-13T16:28:29.406+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2015-03-13T16:28:29.406+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2015-03-13T16:28:29.406+0800 I CONTROL  [initandlisten] 
2015-03-13T16:28:29.407+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2015-03-13T16:28:29.407+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2015-03-13T16:28:29.407+0800 I CONTROL  [initandlisten]

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

~# cat /sys/kernel/mm/transparent_hugepage/defrag
[always] madvise never

I try to use echo, but it's not permanent, after reboot it will be reset.

echo never > /sys/kernel/mm/transparent_hugepage/defrag

How do I modify /sys/kernel/mm/transparent_hugepage/enabled permanently?

Feng Yu
  • 877
  • 3
  • 8
  • 17
  • 1
    There may be good answers below, but IMO you should have a look at the official documentation of MongoDB: http://docs.mongodb.org/master/tutorial/transparent-huge-pages/ – hgoebl Sep 19 '15 at 11:17

7 Answers7

77

You can

  1. install the sysfsutils package:

    sudo apt install sysfsutils
    
  2. and append a line with that setting to /etc/sysfs.conf:

    kernel/mm/transparent_hugepage/enabled = never
    

This is the cleanest solution, because it keeps all the sysfs configuration in one place instead of relying on custom start-up scripts. The other answers, with the scripts and conditional expressions, are suitable if you don't know through which path the kernel will expose that setting, i. e. if you don't even have a rough idea of the kernel version running on the affected machine.

David Foerster
  • 36,264
  • 56
  • 94
  • 147
  • 4
    This did nothing for me on Ubuntu 14.04 on an AWS EC2 instance. I don't know much about sysfs.conf but it does seem to be an Ubuntu supported configuration, yet the file didn't exist on our system previously, and adding it and rebooting didn't change the mongo output warnings at all. Also tried clayzermk1's advice below, 'defrag' warning still appeared. The official mongo docs init script did remove both warnings. – Neek Oct 07 '15 at 04:56
  • What's the output of cat /sys/kernel/mm/transparent_hugepage/enabled? Does it exist at all? sysfs.conf is normally evaluated at boot by /etc/init.d/sysutils. Is it enabled? What happens, when you invoke /etc/init.d/sysutils start? – David Foerster Oct 07 '15 at 06:52
  • $ cat /sys/kernel/mm/transparent_hugepage/enabled [always] madvise never $ ls -l /etc/sysfs.conf ls: cannot access /etc/sysfs.conf: No such file or directory $ ls -l /etc/init.d/sysutils ls: cannot access /etc/init.d/sysutils: No such file or directory It seems these AWS EC2 Ubuntu instances don't come with sysutils installed at all. Since the recommended Mongo docs did fix my problem, I'm hesitant to install sysutils and mess with the EC2 instance when I'm not sure what I'm doing. – Neek Oct 09 '15 at 03:57
  • I'm not surprised at the different system configuration of EC2. That's exactly why they're off topic here. – David Foerster Oct 10 '15 at 16:25
  • 3
    I also don't have sysfs.conf file and /etc/init.d/sysutils. ubuntu 16.04 – HEX May 21 '16 at 13:51
  • Shouldn't this be /etc/sysctl.conf? – unhammer Nov 16 '16 at 08:50
  • 1
    @unhammer: No, the two have a different scopes. sysctl is for settings that you could also achieve with kernel parameters; sysfs.conf is for entries in /sys. – David Foerster Nov 16 '16 at 09:02
  • @HEX On Ubuntu 16.04 systemd is used, thus after changing /etc/sysfs.conf sysfsutils service has to be restarted using systemctl restart sysfsutils.service ... did the job for me here. – Thomas Urban Mar 19 '17 at 22:30
  • @cepharum: Yes, sysfs.conf is read by a service (usually upon boot). That is true for other versions of Ubuntu too. – David Foerster Mar 20 '17 at 07:24
  • @DavidFoerster My comment was somewhat ambiguous indeed as I was basically referring to reason for missing /etc/init.d/sysutils in Ubuntu 16.04 and later ... – Thomas Urban Mar 20 '17 at 08:12
  • This doesn't solve the /sys/kernel/mm/transparent_hugepage/defrag warning – orszaczky Jun 14 '17 at 11:16
  • @orszaczky: That wasn't the question as far as I understand it. You're welcome to open a new question about that. :-) – David Foerster Jun 14 '17 at 14:53
  • After following the answer, I still need to run systemctl daemon-reload followed by systemctl restart mongodb to get rid of the error (on Ubuntu 17.04) – Yohanes Gultom Aug 15 '17 at 11:35
  • @YohanesGultom: Obviously the setting can only apply to newly created processes. This only applies when the setting was modified at runtime, i. e. not at boot time, which means it outside of the scope of this question. – David Foerster Aug 15 '17 at 14:30
  • For me, it seems the redis-server is started before this setting change. If I look at the shell cat /sys/kernel/mm/transparent_hugepage/enabled or restart redis, everything seems ok. Any thoughts? – navossoc Mar 05 '18 at 12:36
  • 1
    @navossoc: Could you please open a new question if you have a new or follow-up question? The comment section is not suitable or meant for new questions or extended discussion. You’re welcome to send me a comment with a notification to draw my attention to it. Thanks. – David Foerster Mar 05 '18 at 12:46
  • I have found this to be the easiest way in Ubuntu 18.04 and cleanest solution to persist disabling THP – SteamerJ Mar 29 '19 at 20:06
26

The MongoDB docs have a few suggestions. http://docs.mongodb.org/manual/reference/transparent-huge-pages/

The "preferred" way is to edit /etc/default/grub and append transparent_hugepage=never to GRUB_CMDLINE_LINUX_DEFAULT then run update-grub to rebuild the GRUB configuration.

The following two-liner will do just that. Make sure to verify the output!

sed -r 's/GRUB_CMDLINE_LINUX_DEFAULT="[a-zA-Z0-9_= ]*/& transparent_hugepage=never/' /etc/default/grub | sudo tee /etc/default/grub
sudo update-grub

Note that update-grub is a wrapper for grub-mkconfig. grub-mkconfig will clobber entries in /etc/default/grub with those from /etc/default/grub.d/*. If by chance you are running on AWS, you will need to instead edit /etc/default/grub.d/50-cloudimg-settings.cfg.

The "alternate" method is to edit /etc/rc.local and add the following before exit 0:

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

Personally, I ended up doing both the "preferred" and "alternate" methods since they aren't mutually exclusive and it eliminates the warning about defrag.

* Worked for me on Ubuntu 14.04, MongoDB 3.0.2, and AWS.

clayzermk1
  • 361
  • 2
  • 5
17

Here's a solution that has been tested to work on Ubuntu 16.04 on AWS EC2. Ubuntu 16.04 uses the systemd init system, and this config file expresses that these settings should be changed before MongoDB boots up.

Create a file named /etc/systemd/system/mongodb-hugepage-fix.service and add the following content:

[Unit]
Description="Disable Transparent Hugepage before MongoDB boots"
#WARN: check service name on your system
# If you are using MongoDB Cloud, service name is "mongodb-mms-automation-agent.service"
Before=mongodb.service      

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled'
ExecStart=/bin/bash -c 'echo never > /sys/kernel/mm/transparent_hugepage/defrag'

[Install]
#WARN: check service name on your system
# If you are using MongoDB Cloud, service name is "mongodb-mms-automation-agent.service"
RequiredBy=mongodb.service

To load the file into systemd:

systemctl daemon-reload

To activate the file as a boot-time dependency of MongoDB

systemctl enable mongodb-hugepage-fix

If you want to activate the changes immediately (before the next boot)

systemctl start mongodb-hugepage-fix
systemctl restart mongod

This solution is not suitable for Ubuntu 14.04, which uses the Upstart init solution instead of systemd.

8

Append the following lines below into of /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

This will run when you reboot the server.

PKumar
  • 2,952
  • 1
    Is there a config file about this? rc.local is not a good idea, because rc.local will execute at the end of system start up. So mongodb service will still use the default setting. – Feng Yu Mar 16 '15 at 14:24
  • 3
    edit the /etc/default/grub file and make changes to the line "GRUB_CMDLINE_LINUX_DEFAULT="transparent_hugepage=never" and run the update-grub command then restart the server – PKumar Mar 18 '15 at 07:51
  • 2
    Thanks, it works. But, is there a similar way to modify /sys/kernel/mm/transparent_hugepage/defrag? When I reboot, mongo shell also tells me "** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'." – Feng Yu Mar 18 '15 at 13:59
  • @FengYu try this page https://docs.mongodb.org/manual/tutorial/transparent-huge-pages/ – PKumar Oct 20 '15 at 13:55
1

Since we are deploying machines with Ansible I don't like modifying rc files.

I tried using sysfsutils / sysfs.conf but ran into timing issues when starting the services on fast (or slow machines). It looked like sometimes mongod was started before sysfsutils. Sometimes it worked, sometimes it did not.

Since mongod is an upstart process I found that the cleanest solution was to add the file /etc/mongo_vm_settings.conf with the following content:

# Ubuntu upstart file at /etc/init/mongod_vm_settings.conf
#
#   This file will set the correct kernel VM settings for MongoDB
#   This file is maintained in Ansible

start on (starting mongod)
script
  echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
  echo "never" > /sys/kernel/mm/transparent_hugepage/defrag
end script

This will run the script just before mongod will be started. Restart mongod (sudo service mongod restart) and done.

Whyhankee
  • 111
1

After reading a little bit in the warning log I've added these two lines in /etc/sysfs.conf y voilá

kernel/mm/transparent_hugepage/enabled = never
kernel/mm/transparent_hugepage/defrag = never

Reboot the machine after applying these changes.

Ulv3r
  • 11
0

GRUB will change after upgrade, and rc.local will run only after mongo is started, so maybe we should add service mongo restart at the end of rc.local like this

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

wait 1 && servie mongod restart

or maybe someone successfully added the lines above to init script in Ubuntu 14.04?

Edik Mkoyan
  • 349
  • 1
  • 3
  • 11