ZFS no Ubuntu Server: pools, snapshots e scrub, passo a passo
| |

ZFS no Ubuntu Server: pools, snapshots e scrub, passo a passo

ZFS é, ao mesmo tempo, gerenciador de volumes e sistema de arquivos. A diferença que importa na prática: cada bloco grava um checksum e cada leitura confere esse checksum, então corrupção silenciosa de disco — aquela que ext4 e XFS simplesmente não detectam — é pega e, com redundância (mirror ou RAIDZ), corrigida sozinha. Some a isso snapshots instantâneos e compressão transparente, e o ZFS resolve de uma vez três problemas que hoje exigem ferramentas separadas: integridade, backup local rápido e economia de espaço.

Por que trocar ext4 por ZFS num servidor Linux

Ext4 e XFS confiam que o disco nunca mente. Na prática, discos mentem: setor realocado silenciosamente, bit flip em cache de escrita, firmware com bug. Sem checksum fim a fim, esses erros chegam direto na aplicação — um banco de dados pode gravar um valor corrompido sem nenhum alerta. O ZFS calcula um checksum (fletcher4 ou SHA-256, configurável) para cada bloco no momento da escrita e revalida a cada leitura; se houver redundância no pool, o bloco ruim é reconstruído automaticamente e registrado em zpool status.

O segundo motivo é operacional: snapshot no ZFS é copy-on-write, custa espaço só pelas mudanças e é instantâneo mesmo em volumes de centenas de gigabytes — não tem o custo de I/O de um rsync completo nem a complexidade de LVM thin snapshots. É a base que RAIDZ, Proxmox e TrueNAS usam por baixo.

Instalando o ZFS no Ubuntu Server

No Ubuntu 26.04 LTS (Resolute Raccoon) e também no 24.04 LTS, o ZFS vem empacotado oficialmente — não é preciso compilar módulo nem adicionar PPA de terceiros:

sudo apt update
sudo apt install zfsutils-linux

Confirme que o módulo carregou e veja a versão do OpenZFS instalada:

lsmod | grep zfs
zfs version

Isso instala só o essencial para gerenciar pools num disco de dados — diferente de instalar o Ubuntu inteiro com root em ZFS, que é outra decisão (feita no instalador) e não é necessária para o que este guia cobre.

Identificando os discos e definindo o ashift certo

Antes do zpool create, identifique os discos por ID estável, não por /dev/sdX — a letra pode mudar entre boots e, se mudar no disco errado, o pool não monta:

ls -l /dev/disk/by-id/ | grep -v part

O parâmetro mais importante da criação do pool é o ashift, porque ele não pode ser alterado depois sem recriar o pool do zero. Ele define o tamanho de bloco físico que o ZFS assume no disco: ashift=9 para setor de 512 bytes, ashift=12 para 4K (Advanced Format). A maioria dos discos e SSDs atuais usa 4K nativo, mas alguns reportam 512 bytes por compatibilidade — confira antes de assumir:

cat /sys/block/sdX/queue/physical_block_size

Se o valor vier 4096, force ashift=12 explicitamente na criação do pool, mesmo que o ZFS tente adivinhar certo por padrão. Errar o ashift não trava o pool, mas degrada performance de escrita de forma permanente — é o erro de configuração de ZFS mais comum e mais caro de corrigir depois.

Criando o pool: disco único, mirror ou RAIDZ

Escolha a topologia pela tolerância a falha que o servidor precisa. Disco único não tem redundância — o checksum detecta corrupção, mas não tem como corrigir:

sudo zpool create -o ashift=12 dados /dev/disk/by-id/ata-DISCO1

Mirror (RAID 1) tolera a perda de um disco entre dois, com leitura mais rápida por poder ler os dois em paralelo:

sudo zpool create -o ashift=12 dados mirror \
  /dev/disk/by-id/ata-DISCO1 /dev/disk/by-id/ata-DISCO2

RAIDZ1 tolera a perda de um disco entre três ou mais, com menos desperdício de espaço que mirror (equivalente a RAID 5, mas sem o write hole do RAID tradicional, porque o ZFS nunca grava uma faixa parcial):

sudo zpool create -o ashift=12 dados raidz1 \
  /dev/disk/by-id/ata-DISCO1 /dev/disk/by-id/ata-DISCO2 /dev/disk/by-id/ata-DISCO3

Com quatro discos ou mais e necessidade de tolerar duas falhas simultâneas, troque para raidz2. Confirme o resultado:

sudo zpool status dados
sudo zpool list

Datasets e as propriedades que valem configurar

Pool é o contêiner; dataset é onde os dados realmente ficam, e cada dataset herda propriedades do pai, podendo sobrescrever. Crie um dataset por função em vez de jogar tudo na raiz do pool — assim cada serviço tem sua própria cota e seus próprios snapshots:

sudo zfs create dados/postgresql
sudo zfs create dados/backups

Três propriedades mudam o resultado prático:

sudo zfs set compression=zstd dados
sudo zfs set atime=off dados
sudo zfs set quota=200G dados/backups

compression=zstd comprime com custo de CPU baixo e normalmente melhora a velocidade de I/O, porque menos bytes físicos trafegam até o disco — não é uma troca de espaço por performance, é as duas coisas juntas na maioria das cargas. atime=off elimina a escrita de metadado a cada leitura de arquivo, que a maioria dos serviços de servidor não usa e que gera I/O desnecessário. quota evita que um dataset sozinho (um log mal comportado, um backup que cresceu) consuma o pool inteiro e trave os demais serviços.

Snapshots: proteção contra erro humano, não só contra disco

Snapshot captura o estado do dataset num instante, sem copiar dados — só referencia os blocos atuais e passa a rastrear o que muda a partir daí. É a defesa mais rápida contra rm -rf no diretório errado ou migration de banco que deu problema:

sudo zfs snapshot dados/postgresql@antes-da-migration
sudo zfs list -t snapshot

Para voltar ao estado do snapshot:

sudo zfs rollback dados/postgresql@antes-da-migration

Para levar o snapshot para outro servidor ou outro pool — o jeito mais eficiente de fazer backup incremental de um volume ZFS, porque só os blocos novos trafegam na rede:

sudo zfs send dados/postgresql@antes-da-migration | \
  ssh usuario@servidor-backup sudo zfs receive dados-backup/postgresql

Snapshot não substitui backup fora do servidor — se o pool inteiro falhar, os snapshots falham com ele. zfs send para outro host é o que fecha essa lacuna.

Scrub automático: a verificação que detecta disco falhando antes da falha

Scrub lê todo bloco alocado no pool e confere o checksum contra o que está armazenado, corrigindo o que a redundância permitir corrigir e reportando o que não permitir. É o que detecta um disco degradando antes que a segunda falha simultânea destrua dados de verdade — sem scrub periódico, corrupção silenciosa só aparece quando já é tarde.

O pacote zfsutils-linux do Ubuntu já traz unidades systemd prontas para isso, só é preciso habilitar para o pool específico:

sudo systemctl enable --now zfs-scrub-monthly@dados.timer
systemctl list-timers | grep zfs

Discos de uso doméstico/SOHO costumam usar cadência semanal por serem mais sujeitos a erro; discos enterprise com maior MTBF toleram mensal — liste as unidades disponíveis no servidor (systemctl list-unit-files | grep zfs-scrub) e habilite a que corresponder à cadência desejada para o pool. Scrub consome I/O real, então agende para fora do horário de pico; o ZFS prioriza I/O de aplicação sobre o do scrub automaticamente, mas em disco já sobrecarregado a diferença se sente.

Monitoramento do dia a dia

Três comandos cobrem a rotina de verificação:

sudo zpool status -v dados
sudo zfs list -r dados
sudo zpool iostat 2

zpool status -v é o que importa monitorar de fora — via Zabbix, cron com mail ou script próprio — porque um estado diferente de ONLINE (DEGRADED, FAULTED) significa que o pool está operando sem a redundância completa prevista, mesmo que os serviços continuem respondendo normalmente.

Perguntas frequentes

ZFS precisa de muita RAM para funcionar bem?
Não para uso normal. O ZFS usa RAM disponível como cache de leitura (ARC) e libera sob pressão de memória, então mais RAM ajuda mas não é obrigatória. A exceção é dedup (deduplicação), que exige RAM proporcional ao volume de dados — por isso a recomendação prática é evitar dedup e usar compression=zstd, que entrega a maior parte do ganho de espaço sem o custo de memória.

Posso usar ZFS com discos de tamanhos diferentes?
Sim, mas o pool usa o espaço do menor disco do grupo redundante (mirror ou RAIDZ) — misturar tamanhos desperdiça a capacidade extra dos discos maiores. Para aproveitar tudo, use discos iguais no mesmo vdev.

Dá para expandir um RAIDZ adicionando um disco só?
Desde o OpenZFS 2.3, sim, com zpool attach para expansão de RAIDZ (RAIDZ expansion), mas o Ubuntu precisa ter essa versão do pacote — confira com zpool version antes de planejar a expansão dessa forma. Antes dessa funcionalidade, a única forma suportada era substituir o vdev inteiro por um maior.

ZFS substitui backup?
Não. Snapshot e RAIDZ protegem contra erro humano e falha de disco dentro do mesmo servidor, mas não contra incêndio, roubo ou falha do servidor inteiro. zfs send para outro host, físico ou na nuvem, é a parte que falta para um plano de backup completo.

Funciona em VM ou só em servidor físico?
Funciona em VM, mas com uma ressalva: o ZFS já faz seu próprio gerenciamento de redundância e cache, então uma VM com disco virtual sobre um storage que já faz RAID (como a maioria dos hypervisors) duplica esse trabalho sem ganho real. O cenário ideal é ZFS com acesso direto aos discos físicos (passthrough) ou direto no host.

Conclusão

ZFS troca a simplicidade do ext4 por uma camada de proteção que a maioria dos servidores Linux não tem hoje: checksum fim a fim, autocorreção com redundância, snapshot instantâneo e compressão que normalmente paga a própria conta em performance. Para quem já mantém dados em produção sem isso, o caminho mais seguro é começar num dataset de teste, confirmar o ashift correto, habilitar o scrub automático e só depois migrar as cargas que realmente importam.

Gostou? Compartilhe.

Posts Similares

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *