Música 🎶 Palestina 🇵🇸 Programación Sociedad Tecnología

PostgreSQL 18 y ZFS

30/10/2025 11:54 Por Karim Mribti
​Vamos a lo concreto y afinado para PostgreSQL sobre ZFS en Linux (Ubuntu 24.04, ZFS 2.4)! Esto te da latencia baja, menos amplificación de escritura y buen uso de RAM/CPU.


1) Creación del pool (alineación y layout)

  • Usa bloques de 4 KiB (ashift=12). Si tus NVMe anuncian 8 KiB nativos, ashift=13.

  • Evita RAID-Z para PG de alta escritura; prefiere mirror (o striped mirrors) por latencia/IOPS.

  • No habilites dedup (caro en RAM/CPU).

# Ejemplo: 2× NVMe en espejo sudo zpool create -o ashift=12 \ zpg mirror /dev/nvme0n1 /dev/nvme1n1

Opcionales de alto rendimiento (si tienes discos extra):

  • SLOG (ZIL dedicado) en mirror con SSD enterprise con PLP (latencia muy baja). Mejora commits/WAL sync.

  • special vdev (mirror) para metadatos y bloques pequeños; acelera catálogos e índices.

# Con SLOG y special vdev sudo zpool create -o ashift=12 zpg \ mirror /dev/nvme0n1 /dev/nvme1n1 \ log mirror /dev/nvme2n1 /dev/nvme3n1 \ special mirror /dev/nvme4n1 /dev/nvme5n1

2) Datasets separados y propiedades clave

Separa datos (PGDATA) y WAL (pg_wal) para tunear de forma distinta.

sudo zfs create -o mountpoint=/var/lib/postgresql zpg/pg sudo zfs create -o mountpoint=/var/lib/postgresql/18/main zpg/pg/data sudo zfs create -o mountpoint=/var/lib/postgresql/18/main/pg_wal zpg/pg/wal

Propiedades comunes (ambos datasets)

# Cosas que reducen overhead sudo zfs set atime=off zpg/pg sudo zfs set xattr=sa zpg/pg sudo zfs set acltype=posixacl zpg/pg sudo zfs set relatime=off zpg/pg sudo zfs set dnodesize=auto zpg/pg sudo zfs set redundant_metadata=most zpg/pg sudo zfs set compression=lz4 zpg/pg # lz4 es casi gratis y ahorra I/O

Datos (tablas/índices): alinea a páginas de PG (8 KiB)

sudo zfs set recordsize=8K zpg/pg/data sudo zfs set primarycache=all zpg/pg/data # caché útil para datos/índices sudo zfs set secondarycache=all zpg/pg/data # si usas L2ARC # Si tienes special vdev, manda los bloques pequeños allí: sudo zfs set special_small_blocks=8K zpg/pg/data

WAL (pg_wal): latencia de fsync y evitar contaminar ARC

sudo zfs set recordsize=8K zpg/pg/wal # alinear a bloques WAL de 8K sudo zfs set logbias=throughput zpg/pg/wal # optimiza sync write/streaming sudo zfs set primarycache=metadata zpg/pg/wal # no llenes ARC con WAL sudo zfs set secondarycache=off zpg/pg/wal sudo zfs set compression=lz4 zpg/pg/wal # OK; overhead mínimo # Con special vdev, también: sudo zfs set special_small_blocks=8K zpg/pg/wal

No uses sync=disabled en producción: arriesga corrupción tras cortes de luz. Mantén sync=standard. Si tienes SLOG con PLP, ya tendrás commits rápidos.

3) Memoria: ARC vs PostgreSQL

Deja RAM suficiente a PostgreSQL (shared_buffers, work_mem, etc.). Limita ARC.

Ejemplo con 256 GB RAM:

  • PostgreSQL shared_buffers: 32–64 GB (según tu carga).

  • ARC (zfs_arc_max): ~64–96 GB. Ajusta para que el sistema no swapee.

# /etc/modprobe.d/zfs.conf (crea/edita) options zfs zfs_arc_max=96G # aplicar tras reinicio o descargando módulo; verifica: cat /sys/module/zfs/parameters/zfs_arc_max

Otros ajustes ZFS razonables (por defecto modernos ya están bien):

# Mantener prefetch habilitado (útil para secuenciales grandes) # zfs_prefetch_disable=0 por defecto en versiones recientes.

4) Montaje, permisos y journal de sistema

  • Asegúrate de que el servicio de PostgreSQL arranque después de importar el pool ZFS (systemd units suelen manejarlo, pero revísalo).

  • Propietario de rutas:

sudo chown -R postgres:postgres /var/lib/postgresql

5) Snapshots/replicación (sin penalizar)

  • Usa snapshots frecuentes (p. ej., cada hora/día) del dataset data. Evita snapshot muy frecuentes del wal (crece mucho).

sudo zfs snapshot zpg/pg/data@pre-upgrade-$(date +%F)
  • Para réplicas, zfs send | ssh zfs receive sobre data; WAL ya viaja con la replicación nativa de PG (streaming) si la usas.

6) Verificación rápida

zfs get -r recordsize,primarycache,secondarycache,logbias,compression,atime,\ xattr,acltype,redundant_metadata,special_small_blocks zpg/pg zdb -C zpg | grep -E 'ashift|ashift='

7) Notas prácticas y matices

  • LZ4 vs ZSTD: en cargas muy write-heavy de PG, LZ4 suele rendir mejor (menos CPU y latencia). Tú ya lo has observado: mantén lz4.

  • SLOG: aporta más si tu pool de datos no es ultra-rápido o si tienes muchas transacciones con synchronous_commit=on. Si tus NVMe ya son de baja latencia, la ganancia puede ser moderada; con SLOG dedicado y PLP, los commits bajan notablemente su p99.

  • special vdev: marca diferencia en catálogos/índices y pequeñas lecturas aleatorias. Requiere SSD rápido y mirror (es crítico para la integridad).

  • copies=: deja copies=1 (eleva mucho la escritura). Metadata ya va duplicada en mirrors/special.

  • Dedup=off: PostgreSQL no se beneficia; costaría mucha RAM.

Comentarios

Agregar comentario
Cargando comentarios...