DB-유

Setting Up Swap Space on Linux

· linux, memory, swap, performance

Most cloud images ship with no swap. On a 1 or 2 GB VPS that means the first memory spike makes the OOM killer pick a victim, and it picked MySQL more than once for me. A few seconds of swapping beats that every time. A small swap file gives the kernel somewhere to park cold pages and turns a crash into a slowdown you can see in monitoring.

I use a swap file, not a partition, on CentOS 7 or Ubuntu 16.04/18.04. You need sudo and enough free disk (df -h /).

What's there now

free -h
swapon --show
cat /proc/swaps

If swapon --show prints nothing, there's no swap. The old "twice RAM" rule is outdated. For servers I go roughly equal to RAM up to 4 GB, then 2 to 4 GB flat for anything larger. Servers don't hibernate, so that reason is gone.

Create the file

fallocate is instant and works on ext4 and XFS on any current kernel:

sudo fallocate -l 2G /swapfile

If the filesystem doesn't support fallocate, fall back to dd. It's slower because it really writes the blocks:

sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress

Lock down permissions before formatting. A world-readable swap file can expose anything that was ever in memory:

sudo chmod 600 /swapfile
ls -lh /swapfile

Format and turn it on

sudo mkswap /swapfile
sudo swapon /swapfile
swapon --show
free -h

mkswap prints the UUID and size; swapon --show should now list /swapfile with type file.

Make it survive a reboot

Add a line to /etc/fstab:

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Check the entry with sudo swapoff /swapfile && sudo swapon -a && swapon --show. swapon -a activates everything in fstab, which is what boot does. I always run this rather than trusting a typo-free line.

On CentOS 7 with SELinux enforcing, a swap file under / may be labelled unlabeled_t or root_t and swapon can be denied. Give it the right type:

sudo semanage fcontext -a -t swapfile_t /swapfile
sudo restorecon -v /swapfile

Swappiness

vm.swappiness sets how willing the kernel is to swap application memory instead of dropping page cache. The default of 60 suits desktops. On database or app servers I want swap as a safety net, not something in regular use:

sudo sysctl vm.swappiness=10
sudo sysctl vm.vfs_cache_pressure=50

Make it persistent in /etc/sysctl.d/99-swap.conf:

vm.swappiness = 10
vm.vfs_cache_pressure = 50

Load it with sudo sysctl -p /etc/sysctl.d/99-swap.conf. Don't set swappiness to 0 on kernels 3.5 and later. There it stops swapping anonymous memory almost entirely, which brings the OOM kills right back.

Checking

free -h
swapon --show
sysctl vm.swappiness
grep -i swap /etc/fstab

Reboot when convenient and run swapon --show again to prove the fstab entry works. vmstat 1 shows the si and so columns (swap in/out per second) if you want to watch it work.

If it complains

  • swapon: /swapfile: swapon failed: Invalid argument right after fallocate: on some kernels and filesystems (older XFS, btrfs) fallocated files have holes the swap code rejects. Recreate with dd.
  • swapon failed: Operation not permitted on CentOS 7: SELinux. Check ausearch -m avc -ts recent and apply the swapfile_t label from above.
  • swapon: /swapfile: insecure permissions 0644, 0600 suggested: you skipped chmod 600. It works anyway, but fix it.
  • Slow server, swap heavily used while RAM has plenty of buff/cache: swappiness is too high. Lower it, then swapoff -a && swapon -a to pull pages back.
  • Swap use creeping up day by day is a leak or an undersized instance, not a swap problem. Swap just buys you time to find it.