TL;DR — Resumo Rápido
Snapshots ZFS protegem dados no Linux com copy-on-write sem custo inicial. Aprenda a criar, reverter, clonar e replicar datasets com zfs send/receive e sanoid.
Os snapshots ZFS são uma das ferramentas de proteção de dados mais poderosas disponíveis no Linux. Ao contrário das abordagens tradicionais de backup que copiam datasets inteiros, os snapshots ZFS aproveitam a semântica de copy-on-write (COW) para capturar o estado exato de um sistema de arquivos em um ponto no tempo — instantaneamente e sem custo inicial de espaço. Este guia cobre desde os fundamentos do ZFS até pipelines de snapshots automatizados com sanoid e syncoid.
Pré-requisitos
- Ubuntu 22.04/24.04 LTS (ou qualquer distro com OpenZFS 2.1+)
- Um ou mais dispositivos de bloco para testes
- Acesso com
sudo - Familiaridade básica com nomes de dispositivos Linux (
/dev/sd*,/dev/vd*)
Conceitos Fundamentais do ZFS
Copy-on-Write (COW): O ZFS nunca sobrescreve dados ativos no mesmo lugar. Quando um bloco é modificado, o ZFS escreve a nova versão em um local livre e atualiza atomicamente o ponteiro. O bloco antigo permanece intacto — é isso que os snapshots exploram.
Pools e Datasets: Um pool (zpool) é o contêiner de armazenamento de nível superior formado por um ou mais vdevs. Um dataset (zfs create) é um sistema de arquivos montável dentro de um pool.
Checksums: Cada bloco carrega um checksum de 256 bits. Na leitura, o ZFS verifica o checksum e pode se auto-reparar a partir de uma cópia redundante se o bloco primário estiver corrompido.
Instalando ZFS no Ubuntu
sudo apt update
sudo apt install zfsutils-linux -y
zfs --version
Criando Pools
# Espelho (equivalente a RAID-1)
sudo zpool create tank mirror /dev/sdb /dev/sdc
# RAIDZ1 — 1 disco de paridade, tolera 1 falha
sudo zpool create tank raidz /dev/sdb /dev/sdc /dev/sdd
# RAIDZ2 — 2 discos de paridade, tolera 2 falhas (recomendado para >=6 discos)
sudo zpool create tank raidz2 /dev/sd{b,c,d,e,f,g}
zpool status tank
zpool list
Gerenciamento de Datasets
# Dataset com compressão LZ4
zfs create -o compression=lz4 tank/data
# Ponto de montagem explícito
zfs set mountpoint=/srv/data tank/data
# Compressão zstd para melhor razão
zfs set compression=zstd tank/data
# Ajuste de recordsize para bancos de dados
zfs set recordsize=16K tank/postgres # PostgreSQL
zfs set recordsize=128K tank/mysql # MySQL InnoDB
# Quotas e reservas
zfs set quota=500G tank/data
zfs set reservation=100G tank/data
Propriedades de monitoramento:
| Propriedade | Significado |
|---|---|
used | Espaço consumido pelo dataset + seus snapshots |
available | Espaço livre que o dataset ainda pode usar |
referenced | Espaço apenas do dataset ativo (exclui snapshots) |
compressratio | Razão de compressão alcançada (ex. 2.14x) |
Fundamentos de Snapshots
Criando Snapshots
# Snapshot único
zfs snapshot tank/data@2026-03-22
# Snapshot recursivo
zfs snapshot -r tank@2026-03-22
# Com timestamp do shell
zfs snapshot tank/data@$(date +%Y-%m-%dT%H%M)
Listando Snapshots
zfs list -t snapshot
zfs list -t snapshot -o name,used,referenced,creation
Revertendo (Rollback)
zfs rollback tank/data@2026-03-22
# Se existirem snapshots mais recentes
zfs rollback -r tank/data@2026-03-21
Acessar Conteúdo de um Snapshot sem Reverter
ls /srv/data/.zfs/snapshot/
# Restaurar um arquivo individual
cp /srv/data/.zfs/snapshot/2026-03-22/importante.sql /srv/data/restaurado.sql
Destruindo Snapshots
zfs destroy tank/data@2026-03-20
# Faixa de snapshots
zfs destroy tank/data@2026-03-01%2026-03-15
Clones: Snapshots Graváveis
Um clone é um dataset gravável derivado de um snapshot, ideal para ambientes de staging.
# Criar um clone
zfs clone tank/data@2026-03-22 tank/data-staging
# Ponto de montagem
zfs set mountpoint=/srv/staging tank/data-staging
# Promover o clone a independente
zfs promote tank/data-staging
Send/Receive: Replicação ZFS
Envio Completo Inicial
# Cópia local
zfs send tank/data@2026-03-22 | zfs receive backup/data
# Por SSH com compressão
zfs send -c tank/data@2026-03-22 | ssh backup-host zfs receive backup/data
Envios Incrementais
# -i = incremento único
zfs send -ci tank/data@2026-03-21 tank/data@2026-03-22 | \
ssh backup-host zfs receive -F backup/data
# -I = inclui snapshots intermediários
zfs send -cI tank/data@2026-03-20 tank/data@2026-03-22 | \
ssh backup-host zfs receive -F backup/data
Retomar Transferências Interrompidas
zfs get receive_resume_token backup/data
zfs send -t <token> | ssh backup-host zfs receive -s backup/data
Referência de Flags de Replicação
| Flag | Efeito |
|---|---|
-c | Comprime o stream |
-i | Incremental entre dois snapshots |
-I | Incremental incluindo snapshots intermediários |
-R | Replica dataset recursivamente |
-s | Salva estado de retomada no receptor |
-v | Saída detalhada |
Snapshots Automatizados com Sanoid
Instalar Sanoid
sudo apt install sanoid -y
Configurar Políticas
# /etc/sanoid/sanoid.conf
[tank/data]
use_template = production
recursive = yes
[template_production]
hourly = 24
daily = 30
monthly = 3
autosnap = yes
autoprune = yes
Habilitar o Timer do Systemd
sudo systemctl enable --now sanoid.timer
sudo sanoid --take-snapshots --verbose
sudo sanoid --prune-snapshots --verbose
Syncoid para Replicação
syncoid tank/data backup-host:backup/data
syncoid --recursive tank backup-host:backup
Scrubbing e Auto-reparação
sudo zpool scrub tank
zpool status tank | grep -A5 scrub
echo "0 2 1 * * root /sbin/zpool scrub tank" | sudo tee /etc/cron.d/zfs-scrub
ZFS vs. Alternativas
| Recurso | ZFS | Btrfs | LVM + ext4 | XFS |
|---|---|---|---|---|
| Copy-on-write | Sim | Sim | Não | Não |
| RAID integrado | Sim (RAIDZ) | Sim (limitado) | Via LVM | Não |
| Snapshots nativos | Sim | Sim | Via LVM | Não |
| Replicação send/receive | Sim (nativo) | Sim | Não | Não |
| Checksums / auto-reparação | Sim | Sim (limitado) | Não | Não |
| Compressão | Sim (lz4, zstd) | Sim | Não | Não |
| Cache ARC/L2ARC | Sim | Não | Não | Não |
| Maturidade em produção (Linux) | Alta (OpenZFS) | Média | Muito alta | Muito alta |
Padrões de Produção
Boot Environments
sudo zfs snapshot -r rpool/ROOT/ubuntu@before-upgrade
Docker no ZFS
echo '{"storage-driver": "zfs"}' | sudo tee /etc/docker/daemon.json
sudo systemctl restart docker
zfs set recordsize=128K tank/docker
Recordsize para Bancos de Dados
| Banco de Dados | recordsize recomendado | Motivo |
|---|---|---|
| PostgreSQL | 8K ou 16K | Coincide com página de 8K |
| MySQL InnoDB | 16K | Coincide com página InnoDB |
| MySQL MyISAM | 128K | Favorece varreduras sequenciais |
| MongoDB | 16K | Página WiredTiger padrão |
| SQLite | 4K | Coincide com página padrão |
Casos Especiais e Advertências
- Nunca importe o mesmo pool em dois hosts simultaneamente: causa split-brain e corrupção.
- Deduplicação raramente vale a pena: Requer ~5 GB de RAM por TB de dados únicos.
- Swap no ZFS: Evite usar um zvol ZFS como swap — podem ocorrer deadlocks sob pressão extrema de memória.
Resumo
- Snapshots ZFS são cópias instantâneas e eficientes em espaço baseadas em copy-on-write.
- Use
zfs snapshotpara snaps manuais e sanoid para gerenciamento automatizado por políticas. zfs send | zfs receivereplica datasets eficientemente — apenas blocos alterados trafegam pela rede.- O scrubbing mensal detecta corrupção silenciosa antes que se propague.
- Snapshots no mesmo pool não substituem backups fora do pool — sempre replique para um host separado.