Существует большое количество различных how-to по использованию в качестве области страничного обмена на FreeBSD томов на ZFS. В большинстве из них рекомендуют отключать контрольные суммы. Но далеко не везде вспоминают про другие свойства тома, такие как размер блока и настройка кэширования.
С одной стороны, при создании тома ZFS по умолчанию устанавливается размер блока 8КБ, а на архитектурах i386 и amd64 обычно используется размер страницы равный 4КБ, что может отрицательно повлиять на производительность подсистемы страничного обмена.
С другой стороны, для созданного тома по умолчанию включено кэширование всех данных, таким образом при работе с областью страничного обмена система пытается кэшировать в памяти данные из этой области. Т.е. расходует память, которой как раз и не хватает, что и стало причиной обращения к этой области.
Правильная команда для создания тома для области страничного обмена должна быть примерно такой:
zfs create -o org.freebsd:swap=on \
-o volblocksize=4K \
-o checksum=off \
-o primarycache=metadata \
-V 4G rpool/swap
Небольшой комментарий по поводу свойства org.freebsd:swap
, про которое везде говорят, но не объясняют почему оно именно такое. В ZFS изначально не предусмотрено никаких специальных свойств для обозначения тома как области страничного обмена, и в Solaris она подключается используя традиционный /etc/vfstab
. Разработчики FreeBSD вполне логично посчитали, что это не всегда удобно и было бы удобнее перенести это в свойства тома. ZFS предоставляет возможность создания определённых пользователем свойств, имена которых состоят из имени модуля и имени свойства, разделённых двоеточием. Именно пользовательские свойства и задействовали разрабочики FreeBSD, с одной стороны не внося изменений в сам ZFS и сохранив совместимость реализаций, с другой стороны избавив пользователя от необходимости указывать область обмена в /etc/fstab
. Для подключения областей подкачки выполняется загрузочный скрипт /etc/rc.d/zvol
, который ищет тома включенным свойством org.freebsd:swap
, и выполняет для них swapon
.
К сожалению ZFS не позволяет изменять размер блока у уже созданного тома. Если в системе уже создана и подключена область обмена с неправильным размером блока, можно пересоздать том следующим скриптом:
OPTS="-o org.freebsd:swap=on
-o volblocksize=4K
-o checksum=off
-o primarycache=metadata"
DEV=/dev/zvol/
swapinfo | grep "^$DEV" | cut -d ' ' -f 1 | while read swap
do
swapoff $swap
zvol=`echo $swap | sed "s@^$DEV@@"`
size=`zfs get -H -o value volsize $zvol`
zfs destroy $zvol
zfs create $OPTS -V $size $zvol
swapon $swap
done
Скрипт сработает в случае, если у системы есть свободная память или другие области страничного обмена для переноса занятого из временно удаляемых областей подкачки. В противном случае необходимо создать и подключить временную область, после чего выполнить скрипт.
PS. Примечательно, что установщик Solaris при создании области страничного обмена всё делает правильно.