Using multiple swap partitions in a specific order on Linux
It's possible, on Linux, to have multiple swap partitions and/or swapfiles so that your swapspace is spread across multiple physical devices.
It's also sometimes desirable to set an order of priority for these, so that paging uses the fastest underlying storage first.
This documentation details how to set up a mix of swap files and partitions and tell the kernel how to prioritise it's swapsources Linux.
My use-case
Wanting multiple swap sources sounds like quite an obscure thing to require in the modern age, so I thought it'd be useful to quickly detail the use-case that led me to this.
I have a Lenovo Thinkpad X1 Carbon, it's a lovely bit of hardware.
Unfortunately, some poor decisions have collided: Lenovo decided to solder the RAM in, and at purchase time the laptop was under-specced with 16GB RAM (can always upgrade it right? not like it's Apple who solder stuff in. Oh wait...).
However, the SSD is blazing fast. In the old days, you knew you were swapping because your system started being sluggish - that's just not the case here.
The inevitable result is that I tend to first find out that I'm in swap when I've exhausted it (and available RAM). Waiting for OOMKiller to return (most of) your system to you isn't the smoothest of workflows. Because there's only 16GB of RAM, it happens all too frequently.
In an ideal world, you'd upgrade the RAM, but ... yeah, thanks Lenovo...
A secondary solution would be to expand the swapfile. But, all that's really doing is moving the goal-posts, I'd still only find out I've exhausted things when the system crunches to a halt.
What I wanted to implement, instead, was a secondary, slower swap source using a flash drive.
Initial swaps get the benefit of the NVMe (giving almost seamless performance) but as we move further in, we should switch to another slower source so that I get some of the traditional swap lag as a warning that things are about to go wrong.
By default, the Linux kernel will load-balance across multiple swap sources, which isn't what I want. I need the system to exhaust the pool of fast swap storage before moving onto the slower safety net.
Creating Swap
In this example, we'll set up a swapfile and a partition - there's no requirement to mix types, you can use just files or partitions.
Check what swap you currently have
# cat /proc/swaps
Filename Type Size Used Priority
/swapfile file 2096636 13056 -2
Become root
sudo -i
Disable the swap
swapoff /swapfile
Let's expand our pagefile to 4GB whilst here
fallocate -l 4G /swapfile
mkswap /swapfile
Next we'll create a swap partition on our USB stick
lsblk # get the device/partition name, mine is sdd1
mkswap /dev/sdd1
The output of mkswap
will provide a UUID
mkswap: /dev/sda1: warning: wiping old ext4 signature.
Setting up swapspace version 1, size = 28.7 GiB (30765199360 bytes)
no label, UUID=833085e3-7ab8-4341-8cb5-cc51d5d9f7d0
We'll use this in fstab
as device naming can change between reboots.
Enabling and prioritising swap
Next, we need to edit /etc/fstab
to add our swap sources, and specify the priority in which they should be used
vi /etc/fstab
/swapfile none swap sw,pri=2 0 0
UUID=833085e3-7ab8-4341-8cb5-cc51d5d9f7d0 none swap sw,nofail,pri=1 0 0
The highest priority wins, so in this example, /swapfile
will be used before the flash drive.
We've include nofail
for the flash drive so that if it isn't present (or has failed etc) the system won't abort booting.
We then just need to tell the system to put both into use
swapon -a
We should now be able to see both swap sources in use, as well as their priority
# cat /proc/swaps
Filename Type Size Used Priority
/swapfile file 4194300 0 2
/dev/sda1 partition 30044140 0 1
The system should also automatically bring both online at boot.
Conclusion
It's incredibly simple to specify the order in which swap sources should be used - in fact, it's harder to search for the information than it is to put it in place: the kernel will honour the ordering specified in fstab
with the pri
option.
Although it's not been done in this example, you can specify multiple sources with the same priority, so if you wanted to balance writes across one tier, you could do something like
/swapfile none swap sw,pri=3 0 0
UUID=833085e3-7ab8-4341-8cb5-cc51d5d9f7d0 none swap sw,nofail,pri=2 0 0
UUID=abcde-f01 none swap sw,nofail,pri=1 0 0
UUID=01234-567 none swap sw,nofail,pri=1 0 0
Which would cause the kernel to balance across devices for the final tier of swap sources.