Skip to content

Your First Pool

Two pools in this chapter: a practice pool built from files, where every command in this guide can be tried with nothing at stake, and then the shape of a real pool, with the decisions you must make before you build it for real.

Do the practice pool first, even if you aim to build the real thing today. ZFS commands are unforgiving in one specific way: they mostly do exactly what you said, including when what you said was a mistake.

The practice pool: storage made of files

ZFS does not care whether a "disk" is a disk. A plain file works, which makes files the cheapest possible rehearsal space. Make three 1 GB files:

mkdir -p ~/zfs-practice
cd ~/zfs-practice
truncate -s 1G disk1 disk2 disk3

(truncate makes sparse files — they only take real space as the pool fills them, which is why three "1 GB disks" cost almost nothing on disk. Check with ls -lh for the size they claim and du -h for the space they use.)

Now build a pool from two of them, as a mirror, leaving the third spare for chapter 8's disk surgery:

sudo zpool create -f practice \
  $HOME/zfs-practice/disk1 \
  $HOME/zfs-practice/disk2

The -f is there because ZFS quite reasonably hesitates to build a pool from files in a home directory. On real disks you will not need it, and should not use flags that silence hesitation until you know what the hesitation means.

Check what success looks like:

$ zpool status practice
  pool: practice
 state: ONLINE
config:
        NAME                       STATE
        practice                   ONLINE
          /home/you/zfs-practice/disk1  ONLINE
          /home/you/zfs-practice/disk2  ONLINE
errors: No known data errors
$ zfs list
NAME       USED  AVAIL  REFER  MOUNTPOINT
practice   104K  960M      24K  /practice

Your pool exists, and it is already a mounted filesystem at /practice. Copy some files into it. You are now running real ZFS — checksums, copy-on-write, all of it — on two imaginary disks. Chapters 5, 6 and 7 all work on this pool.

When you have finished practising, the whole thing goes away cleanly:

sudo zpool destroy practice
rm ~/zfs-practice/disk*

Building a real pool: the decisions

Decision 1: which shape of vdev

Chapter 2's table is the whole menu. The honest guidance for a home server:

  • Two disks → a mirror. Simple, fast to repair (a replacement disk copies one surviving disk), and the easiest shape to grow later — you can swap both disks for bigger ones, one at a time, and the pool grows when the second swap finishes.
  • Four or more disks → RAIDZ2 is the usual sweet spot: any two disks can die and the pool survives, at a cost of two disks' worth of space.
  • RAIDZ1 (survive one disk) is widely considered thin ice for large modern disks, because rebuilding a failed disk means reading every remaining disk end to end — a second failure, or one unreadable spot, during that long rebuild is the classic way RAID5-style arrays die. The guide repeats the community's advice: mirrors for two, RAIDZ2 for a shelf of disks.
  • One disk is allowed, and this guide won't pretend otherwise: checksums still catch corruption, but there is no second copy to heal from. Treat a single-disk pool as a filesystem with a great alarm system, and keep chapter 10's backups close.

Whatever shape you choose, every vdev in the pool should offer the same protection. Adding one bare disk as a new vdev to a mirror pool does not add "a bit more space" — it adds a part of the pool that kills everything when it dies.

Decision 2: whole disks, by ID

Give ZFS whole disks, not partitions, and name them by their permanent IDs, never by sda-style letters, which are assigned in discovery order and can shuffle between boots:

ls -l /dev/disk/by-id/

You are looking for entries like ata-WDC_WD40EFRX-XXXX_WD-WCC4... — the disk's own serial identity. A pool built from by-id names can be exported and imported on another machine and ZFS will find its disks again whatever letters they were given (chapter 8 uses this; chapter 10 leans on it).

Decision 3: the settings at creation

A few properties are worth setting at birth, because changing them later only affects new writes — or, for ashift, cannot be changed at all:

sudo zpool create \
  -o ashift=12 \
  -O compression=lz4 \
  -O atime=off \
  -O xattr=sa \
  -O mountpoint=/tank \
  tank mirror \
  /dev/disk/by-id/<disk-one> \
  /dev/disk/by-id/<disk-two>

Plain meanings: ashift=12 matches the 4K sectors of every modern disk (a wrong guess here costs performance forever). compression=lz4 turns on compression that is fast enough to leave on for everything (chapter 5). atime=off stops ZFS recording a timestamp every time a file is merely read, which is write traffic nobody reads. xattr=sa stores extended attributes efficiently, which Linux desktops and Samba appreciate. -O sets those on the pool's root dataset; -o sets pool-level options.

Say it back, before you run it

zpool create makes no "are you sure?" worth the name, and it will happily destroy the contents of any disk you name. Read your command aloud. Check the IDs against the disks you meant. Then run it, and check:

zpool status tank
zfs list

Export, import: the pool is portable

A pool is not welded to the machine that made it. zpool export tank writes everything down and lets go; move the disks to another ZFS machine and zpool import tank picks the whole pool up, datasets, snapshots and all. Keep this in the back of your mind — it is what turns "the server died" from a disaster into an errand (chapter 10).