Capítulo 23. El Sistema de Archivos Z (ZFS)

This translation may be out of date. To help with the translations please access the FreeBSD translations instance.

ZFS es un sistema de archivos avanzado diseñado para resolver los principales problemas encontrados en software previo de subsistemas de almacenamiento.

Desarrollado originalmente en Sun Microsystems™, el desarrollo continuo de ZFS de código abierto se ha trasladado al Proyecto OpenZFS.

ZFS tiene tres objetivos principales de diseño:

  • Integridad de los datos: Todos los datos incluyen una suma de comprobación de los datos. ZFS calcula las sumas de comprobación y las escribe junto con los datos. Al leer esos datos posteriormente, ZFS recalcula las sumas de comprobación. Si las sumas de comprobación no coinciden, lo que significa detectar uno o más errores de datos, ZFS intentará corregir automáticamente los errores cuando estén disponibles bloques de duplicado, espejo o paridad.

  • Almacenamiento agrupado: añadir dispositivos de almacenamiento físico a un grupo, y asignar espacio de almacenamiento desde ese grupo compartido. El espacio está disponible para todos los sistemas de archivos y volúmenes, y aumenta al añadir nuevos dispositivos de almacenamiento al grupo.

  • Rendimiento: los mecanismos de caché proporcionan un mayor rendimiento. ARC es una caché de lectura avanzada basada en memoria. ZFS proporciona una segunda caché de lectura basada en disco con L2ARC, y una caché de escritura síncrona basada en disco denominada ZIL.

Una lista completa de características y terminología se encuentra en Características y Terminología de ZFS.

23.1. Qué hace diferente a ZFS

Más que un sistema de archivos, ZFS es fundamentalmente diferente de los sistemas de archivos tradicionales. La combinación de los roles tradicionalmente separados de administrador de volúmenes y sistema de archivos proporciona a ZFS ventajas únicas. El sistema de archivos ahora es consciente de la estructura subyacente de los discos. Los sistemas de archivos tradicionales podían existir en un solo disco a la vez. Si había dos discos entonces era necesario crear dos sistemas de archivos separados. Una configuración RAID de hardware tradicional evitaba este problema presentando al sistema operativo un único disco lógico formado por el espacio proporcionado por los discos físicos sobre el cual el sistema operativo colocaba un sistema de archivos. Incluso con soluciones RAID por software como las proporcionadas por GEOM, el sistema de archivos UFS que reside sobre el RAID cree que está tratando con un solo dispositivo. La combinación de ZFS del administrador de volúmenes y el sistema de archivos resuelve esto y permite la creación de sistemas de archivos que comparten un grupo de almacenamiento disponible. Una gran ventaja de la conciencia de ZFS del diseño físico del disco es que los sistemas de archivos existentes crecen automáticamente al añadir discos adicionales al grupo. Este nuevo espacio luego está disponible para los sistemas de archivos. ZFS también puede aplicar diferentes propiedades a cada sistema de archivos. Esto hace útil crear sistemas de archivos y conjuntos de datos separados en lugar de un único sistema de archivos monolítico.

23.2. Guía de Inicio Rápido

El instalador de FreeBSD puede instalar el sistema directamente en un grupo ZFS, una configuración conocida como Root-on-ZFS; véase Root-on-ZFS Guiado. Esta sección muestra cómo crear y administrar grupos y conjuntos de datos ZFS adicionales en un sistema en ejecución.

FreeBSD puede montar grupos y conjuntos de datos ZFS durante la inicialización del sistema. Para activarlo, ejecute:

# sysrc zfs_enable="YES"

Esto añade zfs_enable="YES" a /etc/rc.conf. Ejecutar service zfs enable realiza el mismo cambio.

Luego inicie el servicio:

# service zfs start

Los ejemplos en esta sección asumen tres discos SATA con los nombres de dispositivo ada0, ada1 y ada2. Los usuarios de hardware SCSI/SAS deberían usar en su lugar nombres de dispositivo da, y los usuarios de almacenamiento NVMe nombres de dispositivo nda.

23.2.1. Grupo de Disco Único

Primero cree una partición GPT en un disco vacío. Luego añada una partición de tipo freebsd-zfs a partir de la cual se crea un grupo único y no redundante:

# gpart create -s gpt ada1
# gpart add -t freebsd-zfs ada1
# zpool create example /dev/ada1p1

Para ver el nuevo grupo, revise la salida de df:

# df /example
Filesystem     1K-blocks    Used    Avail Capacity  Mounted on
example         17547136       0 17547136     0%    /example

Esta salida muestra la creación y montaje del grupo example, y que ahora es accesible como un sistema de archivos. Cree archivos para que los usuarios naveguen:

# cd /example
# ls
# touch testfile
# ls -al
total 4
drwxr-xr-x   2 root  wheel    3 Aug 29 23:15 .
drwxr-xr-x  21 root  wheel  512 Aug 29 23:12 ..
-rw-r--r--   1 root  wheel    0 Aug 29 23:15 testfile

Este grupo aún no utiliza ninguna característica o propiedad avanzada de ZFS. Para crear un conjunto de datos en este grupo con compresión activada:

# zfs create example/compressed
# zfs set compression=gzip example/compressed

El conjunto de datos example/compressed es ahora un sistema de archivos comprimido ZFS. Intente copiar algunos archivos grandes a /example/compressed.

Desactive la compresión con:

# zfs set compression=off example/compressed

Para desmontar un sistema de archivos, use zfs umount y luego verifique con df:

# zfs umount example/compressed
# df
Filesystem   1K-blocks    Used    Avail Capacity  Mounted on
example       17547008       0 17547008     0%    /example

Para volver a montar el sistema de archivos y hacerlo accesible nuevamente, use zfs mount y verifique con df:

# zfs mount example/compressed
# df
Filesystem         1K-blocks    Used    Avail Capacity  Mounted on
example             17547008       0 17547008     0%    /example
example/compressed  17547008       0 17547008     0%    /example/compressed

Ejecutar mount muestra el grupo y los sistemas de archivos:

# mount
/dev/ada0p1 on / (ufs, local)
devfs on /dev (devfs, local)
/dev/ada0p2 on /usr (ufs, local, soft-updates)
example on /example (zfs, local)
example/compressed on /example/compressed (zfs, local)

Use los conjuntos de datos ZFS como cualquier sistema de archivos después de su creación. Establezca otras características disponibles por conjunto de datos cuando sea necesario. El siguiente ejemplo crea un nuevo sistema de archivos llamado data. Asume que el sistema de archivos contiene archivos importantes y lo configura para almacenar dos copias de cada bloque de datos.

# zfs create example/data
# zfs set copies=2 example/data

Use df para ver los datos y el uso de espacio:

# df
Filesystem        1K-blocks    Used    Avail Capacity  Mounted on
/dev/ada0p1         2026030  235234  1628714    13%    /
devfs                     1       1        0   100%    /dev
/dev/ada0p2        54098308 1032864 48737580     2%    /usr
example            17547008       0 17547008     0%    /example
example/compressed 17547008       0 17547008     0%    /example/compressed
example/data       17547008       0 17547008     0%    /example/data

Observe que todos los sistemas de archivos en el grupo tienen el mismo espacio disponible. Usar df en estos ejemplos muestra que los sistemas de archivos usan el espacio que necesitan y todos obtienen del mismo grupo. ZFS elimina conceptos como volúmenes y particiones, y permite que varios sistemas de archivos compartan el mismo grupo.

Para destruir los sistemas de archivos y luego el grupo que ya no se necesitan:

# zfs destroy example/compressed
# zfs destroy example/data
# zpool destroy example

23.2.2. RAID-Z

Los discos fallan. Una forma de evitar la pérdida de datos por fallos de disco es utilizar RAID. ZFS admite esta característica en su diseño de pools. Los pools RAID-Z requieren tres o más discos pero proporcionan más espacio utilizable que los pools en espejo.

Este ejemplo crea un pool RAID-Z. Primero se crean las particiones GPT en cada disco, luego se especifican estas particiones GPT para añadirlas al pool usando la palabra clave raidz:

# gpart create -s gpt ada0
# gpart add -t freebsd-zfs ada0
# gpart create -s gpt ada1
# gpart add -t freebsd-zfs ada1
# gpart create -s gpt ada2
# gpart add -t freebsd-zfs ada2
# zpool create storage raidz ada0p1 ada1p1 ada2p1

Se recomienda mantener el número de dispositivos utilizados en una configuración RAID-Z entre tres y nueve. Para entornos que requieran un único pool que conste de 10 discos o más, considere dividirlo en grupos RAID-Z más pequeños. Si hay dos discos disponibles, la mirroring de ZFS proporciona redundancia si se requiere. Consulte zpool(8) para más detalles.

El ejemplo anterior creó el zpool storage. Este ejemplo crea un nuevo sistema de archivos llamado home en ese pool:

# zfs create storage/home

Habilitar compresión y almacenar una copia adicional de directorios y archivos:

# zfs set copies=2 storage/home
# zfs set compression=gzip storage/home

Para que este sea el nuevo directorio home de los usuarios, copie los datos de usuario a este directorio y cree los enlaces simbólicos apropiados:

# cp -rp /home/* /storage/home
# rm -rf /home /usr/home
# ln -s /storage/home /home
# ln -s /storage/home /usr/home

Los datos de usuario ahora se almacenan en el recién creado /storage/home. Pruebe añadiendo un nuevo usuario e iniciando sesión como ese usuario.

Crear una instantánea del sistema de archivos para revertir más tarde:

# zfs snapshot storage/home@2026-07-11

ZFS crea instantáneas de un dataset, no de un directorio o archivo individual.

El carácter @ es un delimitador entre el nombre del sistema de archivos o volumen y el nombre de la instantánea. Antes de eliminar un directorio importante, haga una copia de seguridad del sistema de archivos, luego revierta a una instantánea anterior en la que el directorio aún exista:

# zfs rollback storage/home@2026-07-11

Para listar todas las instantáneas disponibles, ejecute ls en el directorio .zfs/snapshot del sistema de archivos. Por ejemplo, para ver la instantánea tomada:

# ls /storage/home/.zfs/snapshot

Escriba un script para tomar instantáneas regulares de los datos de usuario. Con el tiempo, las instantáneas pueden usar mucho espacio en disco. Elimine la instantánea anterior usando el comando:

# zfs destroy storage/home@2026-07-11

Después de las pruebas, haga que /storage/home sea el verdadero /home con este comando:

# zfs set mountpoint=/home storage/home

Ejecute df y mount para confirmar que el sistema ahora trata el sistema de archivos como el verdadero /home:

# mount
/dev/ada0p1 on / (ufs, local)
devfs on /dev (devfs, local)
/dev/ada0p2 on /usr (ufs, local, soft-updates)
storage on /storage (zfs, local)
storage/home on /home (zfs, local)
# df
Filesystem   1K-blocks    Used    Avail Capacity  Mounted on
/dev/ada0p1    2026030  235240  1628708    13%    /
devfs                1       1        0   100%    /dev
/dev/ada0p2   54098308 1032826 48737618     2%    /usr
storage       26320512       0 26320512     0%    /storage
storage/home  26320512       0 26320512     0%    /home

Esto completa la configuración RAID-Z. Añada actualizaciones de estado diarias sobre los sistemas de archivos creados a las ejecuciones nocturnas de periodic(8) añadiendo esta línea a /etc/periodic.conf:

daily_status_zfs_enable="YES"

periodic(8) también puede ejecutar scrubs programados del pool; vea Scrubbing a Pool.

23.2.3. Recuperación de RAID-Z

Todo RAID de software tiene un método para monitorizar su estado. Visualice el estado de los dispositivos RAID-Z utilizando:

# zpool status -x

Si todos los pools están Online y todo es normal, el mensaje mostrará:

all pools are healthy

Si hay un problema, quizás un disco esté en estado Offline, el estado del pool se verá así:

  pool: storage
 state: DEGRADED
status: One or more devices has been taken offline by the administrator.
        Sufficient replicas exist for the pool to continue functioning in a
        degraded state.
action: Online the device using 'zpool online' or replace the device with
        'zpool replace'.
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        storage     DEGRADED     0     0     0
          raidz1-0  DEGRADED     0     0     0
            ada0p1  ONLINE       0     0     0
            ada1p1  OFFLINE      0     0     0
            ada2p1  ONLINE       0     0     0

errors: No known data errors

"OFFLINE" muestra que el administrador puso ada1p1 fuera de línea usando:

# zpool offline storage ada1p1

Apague el equipo ahora y reemplace ada1p1. Recreé la partición GPT de tipo freebsd-zfs en el nuevo disco. Encienda el equipo y devuelva ada1p1 al pool:

# zpool replace storage ada1p1

A continuación, compruebe el estado de nuevo, esta vez sin -x para mostrar todos los pools:

# zpool status storage
  pool: storage
 state: ONLINE
  scan: resilvered 3.21G in 00:04:36 with 0 errors on Sat Jul 11 10:32:19 2026
config:

        NAME        STATE     READ WRITE CKSUM
        storage     ONLINE       0     0     0
          raidz1-0  ONLINE       0     0     0
            ada0p1  ONLINE       0     0     0
            ada1p1  ONLINE       0     0     0
            ada2p1  ONLINE       0     0     0

errors: No known data errors

En este ejemplo, todo es normal.

23.2.4. Verificación de Datos

ZFS utiliza sumas de comprobación (checksums) para verificar la integridad de los datos almacenados. La creación de sistemas de archivos las habilita automáticamente.

¡Desactivar las sumas de comprobación es posible pero no es recomendable! Las sumas de comprobación ocupan poco espacio de almacenamiento y proporcionan integridad de datos. La mayoría de las funciones de ZFS no funcionarán correctamente con las sumas de comprobación desactivadas. Desactivar estas sumas de comprobación no aumentará el rendimiento de forma perceptible.

Verificar las sumas de comprobación de los datos (llamado scrubbing o limpieza) garantiza la integridad del pool storage con:

# zpool scrub storage

La duración de una limpieza depende de la cantidad de datos almacenados. Cantidades mayores de datos tardarán proporcionalmente más en verificarse. Dado que la limpieza es intensiva en E/S, ZFS permite que se ejecute una única limpieza en cada pool a la vez. Una vez completada la limpieza, visualice el estado con zpool status:

# zpool status storage
  pool: storage
 state: ONLINE
  scan: scrub repaired 0B in 00:19:16 with 0 errors on Sat Jul 11 10:32:19 2026
config:

        NAME        STATE     READ WRITE CKSUM
        storage     ONLINE       0     0     0
          raidz1-0  ONLINE       0     0     0
            ada0p1  ONLINE       0     0     0
            ada1p1  ONLINE       0     0     0
            ada2p1  ONLINE       0     0     0

errors: No known data errors

Mostrar la fecha de finalización de la última limpieza ayuda a decidir cuándo iniciar otra. Las limpiezas rutinarias ayudan a proteger los datos de la corrupción silenciosa y garantizan la integridad del pool.

Consulte zfs(8) y zpool(8) para conocer otras opciones de ZFS.

23.3. Administración de zpool

La administración de ZFS utiliza dos utilidades principales. La utilidad zpool controla la operación del pool y permite agregar, eliminar, reemplazar y gestionar discos. La utilidad zfs permite crear, destruir y gestionar datasets, tanto sistemas de archivos como volúmenes.

23.3.1. Creación y Destrucción de Pools de Almacenamiento

La decisión más importante al crear un pool de almacenamiento ZFS es elegir qué tipos de vdevs agruparán los discos físicos. Consulte la lista de tipos de vdev para obtener detalles sobre las opciones posibles. Los tipos de vdev determinan las características de redundancia, capacidad y rendimiento de un pool. El diseño de un pool no está fijo para siempre en el momento de la creación. Los espejos permiten agregar nuevos discos a la vdev, y las bandas se actualizan a espejos adjuntando un nuevo disco a la vdev. Las vdevs RAID-Z crecen un disco a la vez con expansión de RAID-Z, lo que requiere OpenZFS 2.3 o posterior, disponible por primera vez en FreeBSD 15.0. Agregar nuevas vdevs expande un pool en cualquier momento, y eliminar vdevs de nivel superior es posible dentro de ciertos límites. Reconfigurar un pool en funcionamiento requiere tiempo y ancho de banda de E/S, por lo que elegir tipos de vdevs adecuados desde el principio sigue siendo importante.

Cree un pool de espejo simple en discos que contengan particiones GPT de tipo freebsd-zfs:

# zpool create mypool mirror /dev/ada1p1 /dev/ada2p1
# zpool status
  pool: mypool
 state: ONLINE
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada1p1  ONLINE       0     0     0
            ada2p1  ONLINE       0     0     0

errors: No known data errors

Para crear más de una vdev con un solo comando, especifique grupos de discos separados por la palabra clave del tipo de vdev, mirror en este ejemplo:

# zpool create mypool mirror /dev/ada1p1 /dev/ada2p1 mirror /dev/ada3p1 /dev/ada4p1
# zpool status
  pool: mypool
 state: ONLINE
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada1p1  ONLINE       0     0     0
            ada2p1  ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            ada3p1  ONLINE       0     0     0
            ada4p1  ONLINE       0     0     0

errors: No known data errors

Los pools también pueden usar particiones en lugar de discos completos. Poner ZFS en una partición separada permite que el mismo disco tenga otras particiones para otros propósitos. En particular, permite agregar particiones con código de arranque y sistemas de archivos necesarios para el booteo. Esto permite bootear desde discos que también son miembros de un pool. ZFS no añade penalización de rendimiento en FreeBSD al usar una partición en lugar de un disco completo. Usar particiones también permite al administrador sub-dimensionar los discos, usando menos de la capacidad total. Si un disco de reemplazo futuro del mismo tamaño nominal que el original tiene en realidad una capacidad ligeramente menor, la partición más pequeña aún encajará, utilizando el disco de reemplazo.

Cree un pool RAID-Z2 usando particiones:

# zpool create mypool raidz2 /dev/ada0p1 /dev/ada1p1 /dev/ada2p1 /dev/ada3p1 /dev/ada4p1 /dev/ada5p1
# zpool status
  pool: mypool
 state: ONLINE
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          raidz2-0  ONLINE       0     0     0
            ada0p1  ONLINE       0     0     0
            ada1p1  ONLINE       0     0     0
            ada2p1  ONLINE       0     0     0
            ada3p1  ONLINE       0     0     0
            ada4p1  ONLINE       0     0     0
            ada5p1  ONLINE       0     0     0

errors: No known data errors

ZFS alinea y dimensiona sus escrituras más pequeñas para cada vdev en función del valor ashift de la vdev, el logaritmo en base 2 del tamaño de sector. OpenZFS detecta el tamaño de sector que los discos reportan al crear una vdev y elige ashift en consecuencia. Algunas unidades reportan sectores de 512 bytes por compatibilidad mientras usan sectores de 4096 bytes internamente. Cree pools en dichas unidades con un -o ashift=12 explícito para forzar una alineación de 4096 bytes:

# zpool create -o ashift=12 mypool mirror /dev/ada1p1 /dev/ada2p1

Establecer la variable sysctl(8) vfs.zfs.vdev.min_auto_ashift en 12 da el mismo resultado para la creación del pool y para operaciones posteriores de zpool add y zpool attach. ashift es una propiedad de cada vdev, no del pool en su conjunto. Se fija al crear la vdev y no puede cambiar posteriormente, así que verifíquelo antes de comprometer datos a un pool.

Destruya un pool que ya no necesite para reutilizar los discos. Destruir un pool requiere desmontar primero los sistemas de archivos en ese pool. Si cualquier dataset está en uso, la operación de desmontaje falla sin destruir el pool. Fuerce la destrucción del pool con -f. Esto puede causar un comportamiento indefinido en aplicaciones que tenían archivos abiertos en esos datasets.

23.3.2. Propiedades del Pool

Al igual que los datasets, los pools tienen propiedades que reportan estado y controlan el comportamiento. Muestre todas las propiedades de un pool con zpool get all mypool, o nombre propiedades específicas:

# zpool get health,capacity mypool
NAME    PROPERTY  VALUE   SOURCE
mypool  health    ONLINE  -
mypool  capacity  27%     -

Cambie una propiedad editable con zpool set:

# zpool set comment="Backup pool" mypool
# zpool get comment mypool
NAME    PROPERTY  VALUE        SOURCE
mypool  comment   Backup pool  local

Propiedades como size, capacity, fragmentation y health son valores de estado de solo lectura. Otras cambian cómo se comporta el pool; este capítulo utiliza autoexpand para hacer crecer un pool automáticamente (Hacer Crecer un Pool), autoreplace con discos de repuesto en caliente (Discos de Repuesto en Caliente y Reemplazo Automático con zfsd), autotrim en pools SSD (TRIM e Inicialización) y compatibility para pools portables (Actualizar un Pool de Almacenamiento). Establezca propiedades al crear el pool pasando -o a zpool create, como se mostró con ashift anteriormente. zpoolprops(7) describe cada propiedad del pool.

23.3.3. Adición y Eliminación de Dispositivos

Existen dos formas de agregar discos a un pool: adjuntando un disco a un vdev existente con zpool attach, o añadiendo vdevs al pool con zpool add. Algunos tipos de vdev permiten agregar discos al vdev después de su creación. Los vdevs RAID-Z solo aceptan discos nuevos mediante expansión de RAID-Z.

Un pool creado con un solo disco carece de redundancia. Puede detectar corrupción pero no puede repararla, porque no hay otra copia de los datos. La propiedad copies puede ser capaz de recuperarse de un fallo pequeño como un sector defectuoso, pero no proporciona el mismo nivel de protección que el mirroring o RAID-Z. Comenzando con un pool que consiste en un vdev de disco único, use zpool attach para agregar un nuevo disco al vdev, creando un espejo. También use zpool attach para agregar discos nuevos a un grupo de espejo, aumentando la redundancia y el rendimiento de lectura. Al particionar los discos utilizados para el pool, replique el diseño del primer disco en el segundo. Use gpart backup y gpart restore para facilitar este proceso.

Actualice el vdev de disco único (stripe) ada0p3 a un espejo adjuntando ada1p3:

# zpool status
  pool: mypool
 state: ONLINE
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          ada0p3    ONLINE       0     0     0

errors: No known data errors
# zpool attach mypool ada0p3 ada1p3
Make sure to wait until resilver is done before rebooting.
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1
partcode written to ada1p1
bootcode written to ada1
# zpool status
  pool: mypool
 state: ONLINE
status: One or more devices is currently being resilvered.  The pool will
        continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
  scan: resilver in progress since Sat Jul 11 11:15:25 2026
        738M scanned at 105M/s, 522M issued at 74.6M/s, 781M total
        522M resilvered, 66.84% done, 00:00:03 to go
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0  (resilvering)

errors: No known data errors
# zpool status
  pool: mypool
 state: ONLINE
  scan: resilvered 781M in 00:00:16 with 0 errors on Sat Jul 11 11:18:36 2026
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0

errors: No known data errors

Cuando agregar discos al vdev existente no es una opción, un método alternativo es añadir otro vdev al pool. Añadir vdevs proporciona un mayor rendimiento distribuyendo las escrituras a través de los vdevs. Cada vdev proporciona su propia redundancia. Mezclar tipos de vdev como mirror y RAID-Z es posible pero se desaconseja. Agregar un vdev no redundante a un pool que contiene vdevs de espejo o RAID-Z pone en riesgo los datos de todo el pool. Distribuir las escrituras significa que un fallo del disco no redundante resultará en la pérdida de una fracción de cada bloque escrito en el pool.

ZFS distribuye los datos (stripes) a través de cada uno de los vdevs. Por ejemplo, con dos vdevs de espejo, esto es efectivamente un RAID 10 que distribuye las escrituras a través de dos conjuntos de espejos. ZFS asigna el espacio para que cada vdev alcance el 100% de llenado al mismo tiempo. Tener vdevs con diferentes cantidades de espacio libre reducirá el rendimiento, ya que más escrituras de datos irán al vdev menos lleno.

Al adjuntar dispositivos nuevos a un pool de arranque, recuerde actualizar el código de arranque.

Adjunte un segundo grupo de espejo (ada2p3 y ada3p3) al espejo existente:

# zpool status
  pool: mypool
 state: ONLINE
  scan: resilvered 781M in 00:00:16 with 0 errors on Sat Jul 11 12:11:56 2026
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0

errors: No known data errors
# zpool add mypool mirror ada2p3 ada3p3
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada2
partcode written to ada2p1
bootcode written to ada2
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada3
partcode written to ada3p1
bootcode written to ada3
# zpool status
  pool: mypool
 state: ONLINE
  scan: resilvered 781M in 00:00:16 with 0 errors on Sat Jul 11 09:58:28 2026
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            ada2p3  ONLINE       0     0     0
            ada3p3  ONLINE       0     0     0

errors: No known data errors

zpool add también adjunta dispositivos de registro (log) y caché (cache) dedicados a un pool existente. Un vdev log almacena el registro de intenciones de ZFS (ZFS intent log) en almacenamiento separado de baja latencia, acelerando las escrituras síncronas como las emitidas por bases de datos y NFS. Se recomienda dispositivos de registro en espejo, porque perder un dispositivo de registro no reflejado junto con un bloqueo del sistema le cuesta al pool los últimos segundos de escrituras síncronas; consulte Escrituras Síncronas, el ZIL y el SLOG para obtener orientación sobre dimensionamiento y ajuste. Un vdev cache extiende el ARC con un segundo nivel de caché de lectura en almacenamiento rápido. Los dispositivos de caché no necesitan redundancia, ya que ZFS lee cualquier bloque que no pueda leer de la caché desde los discos originales del pool. El contenido de la caché, el L2ARC, sobrevive a los reinicios por defecto.

Agregue un vdev de registro en espejo y un dispositivo de caché NVMe a un pool existente:

# zpool add mypool log mirror ada4p2 ada5p2
# zpool add mypool cache nda0p2
# zpool status mypool
  pool: mypool
 state: ONLINE
  scan: resilvered 781M in 00:00:16 with 0 errors on Sat Jul 11 09:58:28 2026
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            ada2p3  ONLINE       0     0     0
            ada3p3  ONLINE       0     0     0
        logs
          mirror-2  ONLINE       0     0     0
            ada4p2  ONLINE       0     0     0
            ada5p2  ONLINE       0     0     0
        cache
          nda0p2    ONLINE       0     0     0

errors: No known data errors

zpool detach elimina discos individuales de un vdev de espejo cuando permanece suficiente redundancia. Si queda un solo disco en un grupo de espejo, ese grupo deja de ser un espejo y se convierte en una distribución (stripe), arriesgando todo el pool si ese disco restante falla.

Elimine un disco de un grupo de espejo de tres vías:

# zpool status
  pool: mypool
 state: ONLINE
  scan: scrub repaired 0B in 00:01:11 with 0 errors on Sat Jul 11 03:14:02 2026
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0
            ada2p3  ONLINE       0     0     0

errors: No known data errors
# zpool detach mypool ada2p3
# zpool status
  pool: mypool
 state: ONLINE
  scan: scrub repaired 0B in 00:01:11 with 0 errors on Sat Jul 11 03:14:02 2026
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0

errors: No known data errors

zpool remove elimina vdevs de nivel superior completos de un pool. ZFS evacúa el vdev copiando todos sus datos asignados a los otros vdevs en el pool, y luego desacopla los discos. La eliminación funciona para dispositivos de repuesto en caliente (hot spares), caché, registro (log), especiales (special) y de deduplicación (dedup), y para vdevs de datos que son discos únicos o espejos. Los vdevs de datos no son removibles de pools que contienen un vdev RAID-Z de nivel superior, y todos los vdevs de nivel superior en el pool deben usar el mismo ashift. La evacuación se ejecuta en segundo plano y el pool permanece en línea durante todo el proceso; supervise el progreso con zpool status. Después de que se complete la eliminación, ZFS mantiene una tabla en memoria que mapea los bloques del vdev eliminado a sus nuevas ubicaciones. La tabla es pequeña pero permanente; zpool remove -n estima su uso de memoria antes de iniciar una eliminación.

Elimine uno de los dos vdevs de espejo de un pool:

# zpool remove mypool mirror-1
# zpool status mypool
  pool: mypool
 state: ONLINE
  scan: scrub repaired 0B in 00:01:11 with 0 errors on Sat Jul 11 03:14:02 2026
remove: Evacuation of mirror in progress since Sat Jul 11 10:15:31 2026
        1.71G copied out of 2.32G at 111M/s, 73.71% done, 0h0m to go
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            ada2p3  ONLINE       0     0     0
            ada3p3  ONLINE       0     0     0

errors: No known data errors
# zpool status mypool
  pool: mypool
 state: ONLINE
  scan: scrub repaired 0B in 00:01:11 with 0 errors on Sat Jul 11 03:14:02 2026
remove: Removal of vdev 1 copied 2.32G in 0h0m, completed on Sat Jul 11 10:15:53 2026
        10.9K memory used for removed device mappings
config:

        NAME          STATE     READ WRITE CKSUM
        mypool        ONLINE       0     0     0
          mirror-0    ONLINE       0     0     0
            ada0p3    ONLINE       0     0     0
            ada1p3    ONLINE       0     0     0
          indirect-1  ONLINE       0     0     0

errors: No known data errors

La entrada indirect-1 es un marcador de posición para los bloques reasignados del vdev eliminado y no contiene discos. Cancele una eliminación en curso con zpool remove -s.

23.3.4. Expansión de RAID-Z

La expansión de RAID-Z aumenta un vdev RAID-Z existente de un disco a la vez, sin cambiar su nivel de paridad.

La expansión de RAID-Z requiere OpenZFS 2.3 o posterior, disponible por primera vez en FreeBSD 15.0. Los pools creados en versiones anteriores necesitan habilitar la característica raidz_expansion con zpool upgrade antes de expandir.

Para expandir un vdev RAID-Z, ejecute zpool attach con el nombre del vdev RAID-Z como se muestra en zpool status y el nuevo disco:

# zpool attach mypool raidz2-0 ada6p3

La expansión redistribuye los datos existentes a través del conjunto ampliado de discos en segundo plano mientras el pool permanece en línea y en uso. Añada -w para que zpool attach espere hasta que la expansión se complete. zpool status informa del progreso en la línea expand::

# zpool status mypool
  pool: mypool
 state: ONLINE
  scan: scrub repaired 0B in 06:14:36 with 0 errors on Sat Jul 11 04:31:19 2026
expand: expansion of raidz2-0 in progress since Sat Jul 11 09:42:12 2026
        1.83T / 5.36T copied at 186M/s, 34.14% done, 05:31:43 to go
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          raidz2-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0
            ada2p3  ONLINE       0     0     0
            ada3p3  ONLINE       0     0     0
            ada4p3  ONLINE       0     0     0
            ada5p3  ONLINE       0     0     0
            ada6p3  ONLINE       0     0     0

errors: No known data errors

Cuando la expansión finaliza, la capacidad del nuevo disco queda disponible:

# zpool status mypool | grep expand:
expand: expanded raidz2-0 copied 5.36T in 08:23:35, on Sat Jul 11 18:05:47 2026

Los bloques escritos antes de la expansión mantienen su antigua proporción de datos a paridad y continúan ocupando espacio en consecuencia. La ganancia de capacidad completa del nuevo disco se aplica por tanto a los datos escritos después de la expansión, mientras que los datos antiguos solo se benefician cuando se reescriben, por ejemplo con zfs rewrite. Repita el procedimiento para aumentar un vdev en varios discos, conectando uno cada vez.

23.3.5. Pools dRAID

dRAID es una variante de RAID-Z que distribuye la capacidad de repuesto en caliente a través de todos los discos del vdev. Un vdev dRAID se construye a partir de grupos RAID-Z internos más repuestos distribuidos opcionales, todos distribuidos uniformemente sobre cada disco. Cuando un disco falla, ZFS reconstruye en el repuesto distribuido leyendo y escribiendo en todos los discos restantes en paralelo, completando en una fracción del tiempo que lleva una resilverización en un solo disco de repuesto. Reemplazar el disco fallado luego lo reconstruye desde el repuesto distribuido, restaurando la protección completa. dRAID está dirigido a pools con muchos discos, donde los tiempos de reconstrucción de RAID-Z se vuelven peligrosamente largos.

El tipo de vdev especifica el diseño completo, según zpoolconcepts(7):

draid[parity][:datad][:childrenc][:sparess]

parity es el nivel de paridad de los grupos internos, de 1 a 3, por defecto 1. data es el número de dispositivos de datos por grupo de redundancia, por defecto 8. children es el número total de discos, sirviendo como comprobación cruzada al enumerar muchos dispositivos. spares es el número de repuestos en caliente distribuidos, por defecto 0.

Cree un pool a partir de un vdev dRAID de 24 discos con doble paridad, 8 discos de datos por grupo de redundancia y 2 repuestos distribuidos:

# zpool create mypool draid2:8d:24c:2s ada0 ada1 ada2 ada3 ada4 ada5 ada6 ada7 ada8 ada9 ada10 ada11 ada12 ada13 ada14 ada15 ada16 ada17 ada18 ada19 ada20 ada21 ada22 ada23

Los repuestos distribuidos aparecen bajo spares en zpool status, con nombres como draid2-0-0 para el primer repuesto del primer vdev.

dRAID intercambia eficiencia de espacio por velocidad de reconstrucción. A diferencia de RAID-Z, dRAID utiliza un ancho de banda fijo, rellenando las escrituras más pequeñas con ceros. Con el valor predeterminado de 8 discos de datos y sectores de 4 KB, la asignación mínima es de 32 KB, lo que reduce la capacidad utilizable y la efectividad de la compresión para conjuntos de datos dominados por bloques pequeños. La capacidad de los repuestos distribuidos también se compromete por adelantado, independientemente de que un disco falle o no. Emparejar un pool dRAID con un vdev especial mantiene los metadatos y bloques pequeños fuera de las bandas anchas y recupera gran parte de la eficiencia perdida. Para pools con un puñado de discos, RAID-Z sigue siendo la mejor opción.

23.3.6. Clases de Asignación Especiales

Las clases de asignación especiales dedican vdevs a tipos específicos de datos del pool. Un vdev especial almacena metadatos del pool como bloques indirectos y dnodes, y opcionalmente los bloques de datos de archivos pequeños. Un vdev dedup almacena las tablas de deduplicación. Colocar estos metadatos en dispositivos rápidos como espejos NVMe acelera operaciones intensivas en metadatos como el recorrido de directorios, zfs list y búsquedas de deduplicación en pools de discos por lo demás más lentos.

Añada un vdev especial en espejo a un pool existente:

# zpool add mypool special mirror nda0 nda1

Las nuevas asignaciones de metadatos irán entonces al vdev especial; los metadatos existentes permanecen donde están hasta que se reescriban.

Establecer la propiedad de conjunto de datos special_small_blocks hace que el vdev especial también almacene bloques de datos hasta el tamaño dado:

# zfs set special_small_blocks=16K mypool/projects

Los valores válidos son cero, lo que desactiva el almacenamiento de bloques de datos en la clase especial, o una potencia de dos desde 512 bytes hasta 1 MB en FreeBSD 14.x; FreeBSD 15.0 acepta valores hasta el tamaño máximo de bloque de 16 MB. Establecer la propiedad al recordsize del conjunto de datos envía todos los bloques de datos de ese conjunto a la clase especial. Cuando un vdev especial se llena, las nuevas asignaciones vuelven a la clase normal en lugar de fallar.

Un vdev especial no es una caché. Contiene la única copia de los metadatos del pool asignados a él, y perderlo destruye el pool. Iguale la redundancia de los vdevs especiales y dedup a la redundancia de los vdevs de datos, por ejemplo usando un espejo.

Eliminar un vdev especial o dedup con zpool remove es posible, sujeto a las restricciones descritas en Añadir y Eliminar Dispositivos. En la práctica, el requisito de ashift coincidente a menudo impide la eliminación cuando el vdev especial utiliza dispositivos con un tamaño de sector diferente al de los vdevs de datos.

23.3.7. Comprobación del Estado de un Pool

El estado del pool es importante. Si una unidad se desconecta o ZFS detecta un error de lectura, escritura o de suma de comprobación, el contador de errores correspondiente aumenta. La salida de status muestra la configuración y el estado de cada dispositivo en el pool y el estado del pool completo. También se muestran las acciones a tomar y los detalles sobre el último scrub.

# zpool status
  pool: mypool
 state: ONLINE
  scan: scrub repaired 0B in 02:25:36 with 0 errors on Sat Jul 11 06:51:26 2026
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          raidz2-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0
            ada2p3  ONLINE       0     0     0
            ada3p3  ONLINE       0     0     0
            ada4p3  ONLINE       0     0     0
            ada5p3  ONLINE       0     0     0

errors: No known data errors

Las opciones ajustan la salida a la tarea en cuestión:

  • -v muestra información detallada de errores de datos, imprimiendo una lista completa de los errores encontrados desde el último scrub completo del pool, incluyendo los nombres de los archivos afectados.

  • -x muestra el estado de los pools con errores o pools que no están disponibles por otros motivos, ocultando los pools sanos.

  • -s muestra el número de operaciones de E/S lentas en cada vdev hoja, es decir, operaciones que no se completaron en 30 segundos.

  • -e muestra solo los vdevs no saludables, manteniendo la salida breve para pools con muchos dispositivos; esta opción requiere FreeBSD 14.1 o posterior.

  • -p muestra los números como valores exactos y analizables en lugar de valores redondeados legibles para humanos.

  • -t muestra el estado TRIM de cada vdev.

Consulte zpool-status(8) para obtener la lista completa de opciones.

23.3.8. Borrado de Errores

Al detectar un error, ZFS incrementa los contadores de errores de lectura, escritura o de suma de comprobación. Borre el mensaje de error y reinicie los contadores con zpool clear mypool. Borrar el estado de error puede ser importante para scripts automatizados que alertan al administrador cuando el pool encuentra un error. Sin borrar los errores antiguos, los scripts pueden fallar al reportar errores posteriores.

23.3.9. Sustitución de un Dispositivo Funcional

Puede ser deseable reemplazar un disco por otro diferente. Al reemplazar un disco funcional, el proceso mantiene el disco antiguo en línea durante la sustitución. El pool nunca entra en un estado degradado, reduciendo el riesgo de pérdida de datos. Ejecutar zpool replace copia los datos del disco antiguo al nuevo. Después de que la operación se complete, ZFS desconecta el disco antiguo del vdev. Si el nuevo disco es más grande que el antiguo, puede ser posible expandir el zpool, utilizando el nuevo espacio. Véase Expansión de un Pool.

Sustituya un dispositivo funcional en el pool:

# zpool status
  pool: mypool
 state: ONLINE
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0

errors: No known data errors
# zpool replace mypool ada1p3 ada2p3
Make sure to wait until resilvering finishes before rebooting.

When booting from the pool 'mypool', update the boot code on the newly attached disk 'ada2p3'.

Assuming GPT partitioning is used and ada0 is the new boot disk, use the following command:

        gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada2
# zpool status
  pool: mypool
 state: ONLINE
status: One or more devices is currently being resilvered.  The pool will
        continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
  scan: resilver in progress since Sat Jul 11 14:21:35 2026
        781M / 781M scanned, 604M / 781M issued at 101M/s
        604M resilvered, 77.39% done, 00:00:01 to go
config:

        NAME             STATE     READ WRITE CKSUM
        mypool           ONLINE       0     0     0
          mirror-0       ONLINE       0     0     0
            ada0p3       ONLINE       0     0     0
            replacing-1  ONLINE       0     0     0
              ada1p3     ONLINE       0     0     0
              ada2p3     ONLINE       0     0     0  (resilvering)

errors: No known data errors
# zpool status
  pool: mypool
 state: ONLINE
  scan: resilvered 781M in 00:00:17 with 0 errors on Sat Jul 11 14:21:52 2026
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada2p3  ONLINE       0     0     0

errors: No known data errors

En vdevs en espejo, añadir -s a zpool replace o zpool attach realiza un resilver secuencial en lugar de un resilver de curación. Un resilver secuencial copia los datos en orden de disco sin verificar la suma de comprobación de cada bloque, restaurando la redundancia mucho más rápido. Dado que la copia omite la verificación de la suma de comprobación, ZFS inicia un scrub del pool automáticamente después de que el resilver secuencial se complete. El resilver secuencial funciona en vdevs en espejo y dRAID, no en RAID-Z. Reinicie un resilver en curso desde el principio con zpool resilver mypool.

23.3.10. Gestión de Dispositivos Fallidos

Cuando un disco de un pool falla, el vdev al que pertenece el disco entra en estado degradado. Los datos siguen estando disponibles, pero con un rendimiento reducido porque ZFS calcula los datos que faltan a partir de la redundancia disponible. Para restaurar el vdev a un estado completamente funcional, reemplace el dispositivo físico fallido. Se le indica entonces a ZFS que inicie la operación resilverización. ZFS recalcula los datos del dispositivo fallido a partir de la redundancia disponible y los escribe en el dispositivo de reemplazo. Tras su finalización, el vdev vuelve al estado en línea.

Si el vdev no tiene ninguna redundancia, o si los dispositivos han fallado y no hay suficiente redundancia para compensarlo, el pool entra en estado en fallo. A menos que se puedan reconectar suficientes dispositivos, el pool se vuelve inoperativo, requiriendo una restauración de datos a partir de copias de seguridad.

Al reemplazar un disco fallido, el nombre del disco fallido cambia al GUID del nuevo disco. No se requiere un nuevo parámetro de nombre de dispositivo para zpool replace si el dispositivo de reemplazo tiene el mismo nombre de dispositivo.

Reemplace un disco fallido usando zpool replace:

# zpool status
  pool: mypool
 state: DEGRADED
status: One or more devices could not be opened.  Sufficient replicas exist for
        the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using 'zpool online'.
   see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-2Q
config:

        NAME                    STATE     READ WRITE CKSUM
        mypool                  DEGRADED     0     0     0
          mirror-0              DEGRADED     0     0     0
            ada0p3              ONLINE       0     0     0
            316502962686821739  UNAVAIL      0     0     0  was /dev/ada1p3

errors: No known data errors
# zpool replace mypool 316502962686821739 ada2p3
# zpool status
  pool: mypool
 state: DEGRADED
status: One or more devices is currently being resilvered.  The pool will
        continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
  scan: resilver in progress since Sat Jul 11 14:52:21 2026
        781M / 781M scanned, 641M / 781M issued at 128M/s
        640M resilvered, 82.04% done, 00:00:01 to go
config:

        NAME                        STATE     READ WRITE CKSUM
        mypool                      DEGRADED     0     0     0
          mirror-0                  DEGRADED     0     0     0
            ada0p3                  ONLINE       0     0     0
            replacing-1             UNAVAIL      0     0     0
              15732067398082357289  UNAVAIL      0     0     0  was /dev/ada1p3/old
              ada2p3                ONLINE       0     0     0  (resilvering)

errors: No known data errors
# zpool status
  pool: mypool
 state: ONLINE
  scan: resilvered 781M in 00:00:17 with 0 errors on Sat Jul 11 14:52:38 2026
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada2p3  ONLINE       0     0     0

errors: No known data errors

23.3.11. Discos de Reserva (Hot Spares) y Reemplazo Automático con zfsd

Los pools con vdevs redundantes pueden registrar discos de reserva (hot spare) que permanecen en espera para reemplazar un dispositivo fallido. Un disco de reserva debe ser al menos tan grande como el dispositivo que reemplaza. Especifique discos de reserva en el momento de creación del pool listándolos después de la palabra clave spare, como en zpool create mypool mirror ada0p3 ada1p3 spare ada3p3, o añádalos a un pool existente con zpool add:

# zpool add mypool spare ada3p3
# zpool status
  pool: mypool
 state: ONLINE
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0
        spares
          ada3p3    AVAIL

errors: No known data errors

Un disco de reserva permanece inactivo, mostrado como AVAIL, hasta que un dispositivo falla. Active un disco de reserva manualmente con zpool replace, nombrando el dispositivo fallido y el de reserva:

# zpool replace mypool ada1p3 ada3p3
# zpool status
  pool: mypool
 state: DEGRADED
status: One or more devices could not be opened.  Sufficient replicas exist for
        the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using 'zpool online'.
   see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-2Q
  scan: resilvered 781M in 00:00:21 with 0 errors on Sat Jul 11 09:14:33 2026
config:

        NAME          STATE     READ WRITE CKSUM
        mypool        DEGRADED     0     0     0
          mirror-0    DEGRADED     0     0     0
            ada0p3    ONLINE       0     0     0
            spare-1   DEGRADED     0     0     0
              ada1p3  UNAVAIL      0     0     0  cannot open
              ada3p3  ONLINE       0     0     0
        spares
          ada3p3      INUSE     currently in use

errors: No known data errors

El reemplazo por el disco de reserva es temporal por diseño, y el pool permanece en este estado hasta que un administrador lo resuelva. Después de reemplazar físicamente el disco fallido y resilverizar el nuevo dispositivo con zpool replace, devuelva el disco de reserva al estado de espera con zpool detach mypool ada3p3. Para promover el disco de reserva a miembro permanente del vdev en su lugar, desvincule el dispositivo fallido con zpool detach mypool ada1p3.

La propiedad de pool autoreplace, desactivada por defecto, controla qué sucede cuando un nuevo disco aparece en la misma ubicación física que un dispositivo que previamente pertenecía al pool. Con autoreplace establecido en on, ZFS reemplaza automáticamente el dispositivo antiguo por el nuevo disco, sin requerir un comando zpool replace:

# zpool set autoreplace=on mypool

En FreeBSD, las reacciones automáticas a fallos, incluyendo el respeto a autoreplace, son realizadas por zfsd(8), el demonio de gestión de fallos de ZFS en el sistema base. El demonio no está habilitado por defecto. Habilítelo e inícielo con:

# sysrc zfsd_enable="YES"
# service zfsd start

zfsd(8) escucha eventos del pool y:

  • Activa un disco de reserva cuando un dispositivo desaparece de un vdev redundante o cuando un vdev se degrada o entra en fallo.

  • Marca un vdev como en fallo cuando produce más de 50 errores de E/S o más de 8 operaciones de E/S retrasadas en un período de 60 segundos, y luego activa un disco de reserva.

  • Marca un vdev como degradado cuando produce más de 50 errores de checksum en un período de 60 segundos, y luego activa un disco de reserva.

  • Vuelve a poner en línea un dispositivo cuando reaparece, desencadenando una resilverización de los datos escritos mientras estaba ausente.

  • Reemplaza un dispositivo faltante con un nuevo disco que aparece en la misma ubicación física cuando el pool tiene autoreplace establecido en on.

  • Devuelve los discos de reserva al estado de espera una vez que se completa la resilverización de un reemplazo permanente.

FreeBSD utiliza zfsd(8) para la gestión de fallos. El ZFS Event Daemon (ZED) que se encuentra en las plataformas OpenZFS de Linux no es parte de FreeBSD.

Inspeccione el flujo de eventos que impulsa estas decisiones con zpool events. Añadir -v muestra la carga útil completa de cada evento, y -f mantiene el comando en ejecución, imprimiendo nuevos eventos a medida que llegan. ZFS también entrega estos eventos a devd(8). Las reglas en /etc/devd/zfs.conf los registran en el registro del sistema y sirven como plantilla para acciones personalizadas, como enviar correo cuando un pool se degrada.

23.3.12. Limpieza de un Pool

Realice limpiezas de los pools de forma rutinaria, idealmente al menos una vez al mes. La operación scrub es intensiva en disco y reducirá el rendimiento mientras se ejecuta. Evite los períodos de alta demanda al programar scrub, o reduzca su impacto con los ajustes del planificador de E/S descritos en Ajustes Avanzados.

# zpool scrub mypool
# zpool status
  pool: mypool
 state: ONLINE
  scan: scrub in progress since Sat Jul 11 20:52:54 2026
        130G / 8.60T scanned at 649M/s, 116G / 8.60T issued at 580M/s
        0B repaired, 1.32% done, 04:15:41 to go
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          raidz2-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0
            ada2p3  ONLINE       0     0     0
            ada3p3  ONLINE       0     0     0
            ada4p3  ONLINE       0     0     0
            ada5p3  ONLINE       0     0     0

errors: No known data errors

Pause una limpieza en ejecución con zpool scrub -p mypool cuando interfiera con otro trabajo; ejecutar zpool scrub mypool nuevamente la reanuda desde donde se detuvo. Para cancelar una operación de limpieza en su lugar, ejecute zpool scrub -s mypool. zpool scrub -w mypool espera hasta que la limpieza se complete antes de regresar, lo que es útil en scripts. Después de que una limpieza reporte errores, zpool scrub -e mypool realiza una limpieza de errores que solo vuelve a verificar los bloques con errores conocidos, finalizando mucho más rápido que una limpieza completa. La limpieza de errores requiere OpenZFS 2.2, incluido por primera vez en FreeBSD 14.0.

periodic(8) puede ejecutar limpiezas automáticamente. Para limpiar cada pool cuya última limpieza tenga más de 35 días, agregue esta línea a /etc/periodic.conf:

daily_scrub_zfs_enable="YES"

Establezca daily_scrub_zfs_default_threshold="días" para cambiar el número de días entre limpiezas. periodic.conf(5) también describe umbrales por pool. Establecer daily_status_zfs_enable="YES" agrega una verificación de salud del pool al reporte diario de periodic(8).

23.3.13. Autoreparación

Las sumas de comprobación almacenadas con los bloques de datos permiten que el sistema de archivos se autorepare. Esta característica reparará automáticamente los datos cuya suma de comprobación no coincida con la registrada en otro dispositivo que forme parte del pool de almacenamiento. Por ejemplo, una configuración en espejo con dos discos donde una unidad está empezando a funcionar mal y ya no puede almacenar los datos correctamente. Esto es peor cuando los datos no se accedieron durante mucho tiempo, como con el almacenamiento de archivo a largo plazo. Los sistemas de archivos tradicionales necesitan ejecutar comandos que verifiquen y reparen los datos como fsck(8). Estos comandos toman tiempo y, en casos severos, un administrador debe decidir qué operación de reparación realizar. Cuando ZFS detecta un bloque de datos con una suma de comprobación que no coincide, intenta leer los datos del disco espejo. Si ese disco puede proporcionar los datos correctos, ZFS se los dará a la aplicación y corregirá los datos en el disco con la suma de comprobación incorrecta. Esto ocurre sin ninguna interacción de un administrador del sistema durante la operación normal del pool.

El siguiente ejemplo muestra este comportamiento de autoreparación creando un pool en espejo de las particiones /dev/ada0p1 y /dev/ada1p1.

# zpool create healer mirror /dev/ada0p1 /dev/ada1p1
# zpool status healer
  pool: healer
 state: ONLINE
config:

    NAME        STATE     READ WRITE CKSUM
    healer      ONLINE       0     0     0
      mirror-0  ONLINE       0     0     0
       ada0p1   ONLINE       0     0     0
       ada1p1   ONLINE       0     0     0

errors: No known data errors
# zpool list
NAME     SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
healer   960M   111K   960M        -         -     0%     0%  1.00x    ONLINE  -

Copie algunos datos importantes al pool para protegerlos de errores de datos utilizando la función de autoreparación y cree una suma de comprobación del pool para una comparación posterior.

# cp /some/important/data /healer
# zpool list
NAME     SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
healer   960M  67.7M   892M        -         -     0%     7%  1.00x    ONLINE  -
# sha1 /healer > checksum.txt
# cat checksum.txt
SHA1 (/healer) = 2753eff56d77d9a536ece6694bf0a82740344d1f

Simule corrupción de datos escribiendo datos aleatorios al principio de uno de los discos en el espejo. Para evitar que ZFS repare los datos cuando los detecte, exporte el pool antes de la corrupción e impórtelo de nuevo después.

Esta es una operación peligrosa que puede destruir datos vitales, mostrada aquí únicamente para demostración. No lo intente durante la operación normal de un pool de almacenamiento. Tampoco debería ejecutarse este ejemplo de corrupción intencional en ningún disco con un sistema de archivos que no sea ZFS en otra partición del mismo. No utilice ningún otro nombre de dispositivo de disco que no sean los que forman parte del pool. ¡Asegúrese de que existan copias de seguridad adecuadas del pool y pruébelas antes de ejecutar el comando!

# zpool export healer
# dd if=/dev/random of=/dev/ada1p1 bs=1m count=200
200+0 records in
200+0 records out
209715200 bytes transferred in 62.992162 secs (3329227 bytes/sec)
# zpool import healer

El estado del pool muestra que un dispositivo ha experimentado un error. Tenga en cuenta que las aplicaciones que leen datos del pool no recibieron ningún dato incorrecto. ZFS proporcionó datos del dispositivo ada0p1 con las sumas de comprobación correctas. Para encontrar el dispositivo con la suma de comprobación incorrecta, busque aquel cuya columna CKSUM contenga un valor distinto de cero.

# zpool status healer
  pool: healer
 state: ONLINE
status: One or more devices has experienced an unrecoverable error.  An
        attempt was made to correct the error.  Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
        using 'zpool clear' or replace the device with 'zpool replace'.
   see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-9P
config:

    NAME        STATE     READ WRITE CKSUM
    healer      ONLINE       0     0     0
      mirror-0  ONLINE       0     0     0
       ada0p1   ONLINE       0     0     0
       ada1p1   ONLINE       0     0     1

errors: No known data errors

ZFS detectó el error y lo manejó utilizando la redundancia presente en el dispositivo espejo no afectado ada0p1. Una comparación de la suma de comprobación con la original revelará si el pool vuelve a ser consistente.

# sha1 /healer >> checksum.txt
# cat checksum.txt
SHA1 (/healer) = 2753eff56d77d9a536ece6694bf0a82740344d1f
SHA1 (/healer) = 2753eff56d77d9a536ece6694bf0a82740344d1f

Genere sumas de comprobación antes y después de la manipulación intencional mientras los datos del pool aún coinciden. Esto muestra cómo ZFS es capaz de detectar y corregir cualquier error automáticamente cuando las sumas de comprobación difieren. Tenga en cuenta que esto es posible con suficiente redundancia presente en el pool. Un pool que consta de un solo dispositivo no tiene capacidades de autoreparación. Esa es también la razón por la que las sumas de comprobación son tan importantes en ZFS; no las desactive por ningún motivo. ZFS no requiere fsck(8) o un programa similar de verificación de consistencia del sistema de archivos para detectar y corregir esto, y mantiene el pool disponible mientras hay un problema. Ahora se requiere una operación de limpieza para sobrescribir los datos corruptos en ada1p1.

# zpool scrub healer
# zpool status healer
  pool: healer
 state: ONLINE
status: One or more devices has experienced an unrecoverable error.  An
        attempt was made to correct the error.  Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
        using 'zpool clear' or replace the device with 'zpool replace'.
   see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-9P
  scan: scrub in progress since Sat Jul 11 10:34:02 2026
        40.8M scanned at 20.4M/s, 24.9M issued at 12.4M/s, 67.0M total
        9.63M repaired, 37.16% done, 00:00:03 to go
config:

    NAME        STATE     READ WRITE CKSUM
    healer      ONLINE       0     0     0
      mirror-0  ONLINE       0     0     0
       ada0p1   ONLINE       0     0     0
       ada1p1   ONLINE       0     0   627  (repairing)

errors: No known data errors

La operación de limpieza lee datos de ada0p1 y reescribe cualquier dato con una suma de comprobación incorrecta en ada1p1, mostrado por la salida (repairing) de zpool status. Después de que la operación se completa, el estado del pool cambia a:

# zpool status healer
  pool: healer
 state: ONLINE
status: One or more devices has experienced an unrecoverable error.  An
        attempt was made to correct the error.  Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
        using 'zpool clear' or replace the device with 'zpool replace'.
   see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-9P
  scan: scrub repaired 66.5M in 00:00:06 with 0 errors on Sat Jul 11 10:34:08 2026
config:

    NAME        STATE     READ WRITE CKSUM
    healer      ONLINE       0     0     0
      mirror-0  ONLINE       0     0     0
       ada0p1   ONLINE       0     0     0
       ada1p1   ONLINE       0     0 2.72K

errors: No known data errors

Después de que la operación de limpieza se completa con todos los datos sincronizados desde ada0p1 a ada1p1, borre los mensajes de error del estado del pool ejecutando zpool clear.

# zpool clear healer
# zpool status healer
  pool: healer
 state: ONLINE
  scan: scrub repaired 66.5M in 00:00:06 with 0 errors on Sat Jul 11 10:34:08 2026
config:

    NAME        STATE     READ WRITE CKSUM
    healer      ONLINE       0     0     0
      mirror-0  ONLINE       0     0     0
       ada0p1   ONLINE       0     0     0
       ada1p1   ONLINE       0     0     0

errors: No known data errors

El pool ahora está de vuelta a un estado completamente funcional, con todos los contadores de errores ahora en cero.

23.3.14. TRIM e inicialización

Las unidades de estado sólido y el almacenamiento con aprovisionamiento fino funcionan mejor cuando ZFS les indica qué bloques ya no están en uso. zpool trim pasa esa información a cada dispositivo del grupo que admita los comandos TRIM o UNMAP:

# zpool trim mypool

Recorte un único dispositivo nombrándolo después del grupo, como en zpool trim mypool nda0p3. zpool trim -w espera hasta que el recorte se complete, -c cancela un recorte en ejecución y -s lo suspende; ejecutar zpool trim nuevamente reanuda un recorte suspendido. En dispositivos que lo admitan, zpool trim --secure solicita un TRIM seguro, donde el dispositivo garantiza el borrado de los datos almacenados en los bloques recortados.

zpool status -t muestra el progreso del recorte para cada dispositivo:

# zpool status -t mypool
  pool: mypool
 state: ONLINE
  scan: scrub repaired 0B in 00:12:33 with 0 errors on Sat Jul 11 03:31:11 2026
config:

    NAME        STATE     READ WRITE CKSUM
    mypool      ONLINE       0     0     0
      mirror-0  ONLINE       0     0     0
        nda0p3  ONLINE       0     0     0  (23% trimmed, started at Sat Jul 11 09:15:04 2026)
        nda1p3  ONLINE       0     0     0  (22% trimmed, started at Sat Jul 11 09:15:04 2026)

errors: No known data errors

Establecer la propiedad de grupo autotrim en on hace que ZFS emita pequeños comandos TRIM de forma continua a medida que el grupo libera espacio:

# zpool set autotrim=on mypool

El recorte automático omite pequeñas regiones liberadas y pone una carga extra constante en los dispositivos. Para la mayoría de los sistemas, dejar autotrim desactivado y ejecutar un zpool trim completo de forma programada da mejores resultados. En FreeBSD 14.1 y posteriores, periodic(8) ejecuta dicho recorte diariamente cuando /etc/periodic.conf contiene daily_trim_zfs_enable="YES".

zpool initialize es la contraparte del recorte: escribe un patrón en todo el espacio no asignado de los dispositivos especificados, o en cada dispositivo elegible del grupo cuando no se dan nombres de dispositivo. Esto fuerza al almacenamiento subyacente a asignar el espacio por adelantado, evitando la latencia de la primera escritura en discos virtuales con aprovisionamiento fino, y ejercita nuevos dispositivos antes de confiarles datos.

# zpool initialize mypool

Al igual que con el recorte, -c cancela una inicialización, -s la suspende y -w espera a que finalice; -u elimina el estado de inicialización de los dispositivos. Consulte zpool-trim(8) y zpool-initialize(8) para obtener detalles.

23.3.15. Puntos de control del grupo

zpool checkpoint guarda el estado de todo el grupo, incluyendo cada conjunto de datos y la configuración del grupo, de modo que una posterior reversión devuelva el grupo al estado exacto que tenía al crear el punto de control. Cree un punto de control antes de operaciones administrativas arriesgadas como actualizar el sistema operativo, habilitar nuevas características del grupo o reorganizar conjuntos de datos:

# zpool checkpoint mypool

Un grupo contiene como máximo un punto de control a la vez. La columna CKPOINT de zpool list muestra cuánto espacio consume el punto de control a medida que el grupo diverge del estado guardado:

# zpool list mypool
NAME     SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
mypool  4.50T  1.42T  3.08T     221M         -     4%    31%  1.00x    ONLINE  -

Para revertir, exporte el grupo e impórtelo de nuevo con --rewind-to-checkpoint:

# zpool export mypool
# zpool import --rewind-to-checkpoint mypool

La reversión descarta todo cambio realizado en el grupo después de crear el punto de control, incluyendo instantáneas más recientes y cambios de propiedades. Descarte un punto de control que ya no sea necesario para liberar el espacio que ocupa; -w espera hasta que el descarte se complete:

# zpool checkpoint -d -w mypool

Mientras exista un punto de control, ZFS rechaza operaciones que cambian la estructura del grupo: zpool remove, zpool attach, zpool detach, zpool split y zpool reguid. El espacio liberado después de crear el punto de control no se reclama hasta que este se descarta, por lo que un punto de control de larga duración en un grupo activo puede llenarlo.

Un punto de control no es un sustituto de las instantáneas o las copias de seguridad. Protege contra errores administrativos por un corto período, reside en los mismos discos que el grupo y la reversión descarta todo lo escrito después de su creación.

Consulte zpool-checkpoint(8) para obtener detalles.

23.3.16. Expandir un grupo

El dispositivo más pequeño en cada vdev limita el tamaño utilizable de un grupo redundante. Reemplace el dispositivo más pequeño con un dispositivo más grande. Después de completar una operación de reemplazo o resincronización, el grupo puede crecer para usar la capacidad del nuevo dispositivo. Por ejemplo, considere un espejo de una unidad de 1 TB y una de 2 TB. El espacio utilizable es de 1 TB. Al reemplazar la unidad de 1 TB con otra de 2 TB, el proceso de resincronización copia los datos existentes en la nueva unidad. Como ambos dispositivos tienen ahora capacidad de 2 TB, el espacio disponible del espejo crece a 2 TB.

El grupo no utiliza la nueva capacidad automáticamente por defecto. Establezca la propiedad de grupo autoexpand en on antes de reemplazar los dispositivos y el grupo crecerá tan pronto como el último dispositivo más pequeño abandone el vdev:

# zpool set autoexpand=on mypool

De lo contrario, inicie la expansión usando zpool online -e en cada dispositivo. Después de expandir todos los dispositivos, el espacio extra estará disponible para el grupo.

Para expandir un vdev RAID-Z añadiendo un disco en lugar de reemplazar los existentes, consulte Expansión de RAID-Z.

23.3.17. Importación y Exportación de Pools

Exporte los pools antes de moverlos a otro sistema. ZFS desmonta todos los conjuntos de datos, marcando cada dispositivo como exportado pero aún bloqueado para evitar su uso por otros discos. Esto permite que los pools se importen en otras máquinas, otros sistemas operativos que admiten ZFS e incluso diferentes arquitecturas de hardware (con algunas salvedades, véase zpool(8)). Cuando un conjunto de datos tiene archivos abiertos, utilice zpool export -f para forzar la exportación del pool. Utilice esto con precaución. Los conjuntos de datos se desmontan forzosamente, lo que podría resultar en un comportamiento inesperado por parte de las aplicaciones que tenían archivos abiertos en esos conjuntos de datos.

Exporte un pool que no esté en uso:

# zpool export mypool

Importar un pool monta automáticamente los conjuntos de datos. Si este comportamiento no es deseado, utilice zpool import -N para prevenirlo. zpool import -o establece propiedades temporales para esta importación específica. zpool import -o altroot= permite importar un pool con un punto de montaje base en lugar de la raíz del sistema de archivos. Si el pool se utilizó por última vez en un sistema diferente y no se exportó correctamente, fuerce la importación usando zpool import -f. zpool import -a importa todos los pools que no parecen estar en uso por otro sistema.

zpool-import(8) también proporciona opciones para recuperar pools dañados. zpool import -F intenta retroceder el pool a un grupo de transacciones anterior cuando los más recientes están dañados, descartando los últimos segundos de escrituras. zpool import -m permite importar un pool cuyo dispositivo de registro dedicado falta. zpool import -o readonly=on importa el pool como solo lectura, impidiendo todas las escrituras, lo que es útil para análisis forense o cuando se rescatan datos de un pool que está fallando. zpool import -R /mnt combina altroot=/mnt con cachefile=none, evitando que una importación de rescate perturbe las rutas de montaje y la caché de pool del sistema en ejecución.

Liste todos los pools disponibles para importar:

# zpool import
   pool: mypool
     id: 9930174748043525076
  state: ONLINE
 action: The pool can be imported using its name or numeric identifier.
 config:

        mypool    ONLINE
          ada0p1  ONLINE

Importe el pool con un directorio raíz alternativo:

# zpool import -o altroot=/mnt mypool
# zfs list
NAME                 USED  AVAIL  REFER  MOUNTPOINT
mypool               110K  47.0G    31K  /mnt/mypool

Al arrancar, los scripts de inicio de ZFS habilitados por zfs_enable="YES" en /etc/rc.conf importan cada pool registrado en /etc/zfs/zpool.cache. Importar un pool lo añade a ese archivo de caché automáticamente; la propiedad de pool cachefile controla este comportamiento. Los pools importados con cachefile=none no regresan automáticamente después de un reinicio.

23.3.17.1. Importación de un Pool Cifrado con GELI

La opción Encrypt Disks del instalador de FreeBSD cifra las particiones del pool con geli(8), descrita en Cifrado de Particiones de Disco, en lugar de con cifrado nativo de ZFS. En el sistema instalado, el cargador solicita la frase de contraseña y adjunta los proveedores antes de montar el pool raíz, pero ZFS mismo no sabe nada sobre el cifrado: al arrancar desde medios de rescate o mover los discos a otro host, zpool import no encuentra el pool hasta que se adjuntan los proveedores GELI.

Adjunte la partición cifrada freebsd-zfs de cada disco en el pool, proporcionando la frase de contraseña, luego importe el pool:

# geli attach ada0p4
Enter passphrase:
# zpool import -f -R /mnt zroot

Utilice gpart show para identificar las particiones freebsd-zfs; con el diseño predeterminado del instalador, la partición cifrada es p4. Los sistemas instalados con el diseño heredado, que mantiene un pool de arranque no cifrado separado, almacenan adicionalmente un archivo de clave en /boot/encryption.key en ese pool; adjunte esos proveedores con geli attach -k /ruta/al/encryption.key.

23.3.18. Actualización de un Pool de Almacenamiento

Después de actualizar FreeBSD, o si importa un pool desde un sistema que utiliza una versión anterior, actualice manualmente el pool para hacer disponibles nuevas características en disco. Considere si el pool podría necesitar importarse en un sistema anterior antes de actualizar. La actualización es un proceso unidireccional. Es posible actualizar pools antiguos, pero no es posible revertir pools con características más nuevas.

Los pools ya no llevan un único número de versión. En su lugar, cada cambio de formato en disco es una bandera de característica individual, descrita en zpool-features(7). Una característica se habilita cuando el pool permite su uso y se vuelve activa una vez que el pool almacena datos que dependen de ella. Una característica habilitada pero inactiva no afecta la compatibilidad. Una vez que una característica está activa, el software sin soporte para ella ya no puede importar el pool, aunque los pools cuyas características activas son todas "compatibles de solo lectura" aún permiten importaciones de solo lectura.

zpool status informa cuando características admitidas no están habilitadas en un pool:

# zpool status mypool
  pool: mypool
 state: ONLINE
status: Some supported and requested features are not enabled on the pool.
        The pool can still be used, but some features are unavailable.
action: Enable all features using 'zpool upgrade'. Once this is done,
        the pool may no longer be accessible by software that does not support
        the features. See zpool-features(7) for details.
  scan: scrub repaired 0B in 00:11:03 with 0 errors on Sat Jul 11 03:15:41 2026
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p1  ONLINE       0     0     0
            ada1p1  ONLINE       0     0     0

errors: No known data errors

Ejecutar zpool upgrade sin argumentos lista cada pool con características deshabilitadas:

# zpool upgrade
This system supports ZFS pool feature flags.

Some supported features are not enabled on the following pools. Once a
feature is enabled the pool may become incompatible with software
that does not support the feature. See zpool-features(7) for details.

Note that the pool 'compatibility' feature can be used to inhibit
feature upgrades.

POOL  FEATURE
---------------
mypool
      zilsaxattr
      head_errlog
      blake3
      block_cloning
      vdev_zaps_v2

Utilice zpool upgrade -v para listar cada característica que el sistema en ejecución admite, junto con los números de versión heredados. Habilite todas las características admitidas en un pool:

# zpool upgrade mypool
This system supports ZFS pool feature flags.

Enabled the following features on 'mypool':
  zilsaxattr
  head_errlog
  blake3
  block_cloning
  vdev_zaps_v2

Los pools que deben permanecer importables en sistemas que ejecutan software ZFS más antiguo pueden restringir qué características zpool create y zpool upgrade habilitan mediante la propiedad de pool compatibility:

# zpool create -o compatibility=openzfs-2.1-freebsd mypool mirror /dev/ada0p1 /dev/ada1p1

Establecer la propiedad en un pool existente con zpool set también funciona. Cada conjunto de características nombrado corresponde a un archivo en /usr/share/zfs/compatibility.d, y el valor predeterminado off permite todas las características. Establecer la propiedad no deshabilita características que ya están habilitadas.

Actualice el código de arranque en sistemas que arrancan desde un pool para admitir las nuevas características del pool. Utilice gpart bootcode en la partición que contiene el código de arranque. Hay dos tipos de código de arranque disponibles, dependiendo de la forma en que el sistema arranca: GPT (la opción más común) y EFI (para sistemas más modernos).

Para arranque heredado usando GPT, utilice el siguiente comando:

# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1

Para sistemas que usan EFI para arrancar, ejecute el siguiente comando:

# mount -t msdosfs /dev/ada1p1 /boot/efi
# cp /boot/loader.efi /boot/efi/efi/boot/BOOTX64.efi
# cp /boot/loader.efi /boot/efi/efi/freebsd/loader.efi

Estas instrucciones se aplican a sistemas amd64. Dependiendo de la arquitectura, el archivo tiene un nombre diferente. Consulte uefi(8) para encontrar los nombres de los archivos específicos de la arquitectura.

Aplique el código de arranque a todos los discos arrancables en el pool. Véase gpart(8) para más información.

23.3.19. Visualización del Historial Registrado del Pool

ZFS registra los comandos que cambian el pool, incluyendo la creación de conjuntos de datos, el cambio de propiedades o el reemplazo de un disco. Revisar el historial sobre la creación de un pool es útil, al igual que comprobar qué usuario realizó una acción específica y cuándo. El historial no se guarda en un archivo de registro, sino que es parte del pool mismo. El comando para revisar este historial se llama acertadamente zpool history:

# zpool history
History for 'tank':
2026-07-11.10:24:05 zpool create tank mirror /dev/ada0p1 /dev/ada1p1
2026-07-11.18:50:58 zfs set atime=off tank
2026-07-11.18:51:09 zfs set checksum=fletcher4 tank
2026-07-11.18:51:18 zfs create tank/backup

La salida muestra comandos zpool y zfs que alteran el pool de alguna manera junto con una marca de tiempo. Comandos como zfs list no se incluyen. Cuando no se especifica un nombre de pool, ZFS muestra el historial de todos los pools.

zpool history puede mostrar aún más información al proporcionar las opciones -i o -l. -i muestra eventos iniciados por el usuario así como eventos internos registrados por ZFS.

# zpool history -i
History for 'tank':
2026-07-11.10:24:05 [txg:5] create pool version 5000; software version zfs-2.2.7-FreeBSD_gd75f9ee8b; uts myzfsbox 14.3-RELEASE 1403000 amd64
2026-07-11.18:50:53 [txg:50] set tank (21) atime=0
2026-07-11.18:50:58 zfs set atime=off tank
2026-07-11.18:51:04 [txg:53] set tank (21) checksum=7
2026-07-11.18:51:09 zfs set checksum=fletcher4 tank
2026-07-11.18:51:13 [txg:55] create tank/backup (39)
2026-07-11.18:51:18 zfs create tank/backup

Muestre más detalles añadiendo -l. Muestra los registros de historial en un formato largo, incluyendo información como el nombre del usuario que emitió el comando y el hostname en el que ocurrió el cambio.

# zpool history -l
History for 'tank':
2026-07-11.10:24:05 zpool create tank mirror /dev/ada0p1 /dev/ada1p1 [user 0 (root) on myzfsbox:global]
2026-07-11.18:50:58 zfs set atime=off tank [user 0 (root) on myzfsbox:global]
2026-07-11.18:51:09 zfs set checksum=fletcher4 tank [user 0 (root) on myzfsbox:global]
2026-07-11.18:51:18 zfs create tank/backup [user 0 (root) on myzfsbox:global]

La salida muestra que el usuario root creó el pool en espejo con los discos /dev/ada0p1 y /dev/ada1p1. El hostname myzfsbox también se muestra con cada comando. La visualización del hostname se vuelve importante cuando se exporta el pool desde un sistema y se importa en otro. Es posible distinguir los comandos emitidos en el otro sistema por el hostname registrado para cada comando.

Combine ambas opciones en zpool history para dar la información más detallada posible para cualquier pool dado. El historial del pool proporciona información valiosa al rastrear las acciones realizadas o cuando se necesita una salida más detallada para depuración.

23.3.20. Monitorización del Rendimiento

Un sistema de monitorización incorporado puede mostrar estadísticas de E/S del pool en tiempo real. Muestra la cantidad de espacio libre y utilizado en el pool, las operaciones de lectura y escritura realizadas por segundo y el ancho de banda de E/S utilizado. Por defecto, ZFS monitoriza y muestra todos los pools en el sistema. Proporcione un nombre de pool para limitar la monitorización a ese pool. Un ejemplo básico:

# zpool iostat
               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
data         288G  1.53T      2     11  11.3K  57.1K

Para ver continuamente la actividad de E/S, especifique un número como último parámetro, indicando un intervalo en segundos para esperar entre actualizaciones. La siguiente línea de estadísticas se imprime después de cada intervalo. Presione Ctrl+C para detener esta monitorización continua. Dé un segundo número en la línea de comandos después del intervalo para especificar el número total de estadísticas a mostrar.

Muestre estadísticas de E/S aún más detalladas con -v. Cada dispositivo en el pool aparece con una línea de estadísticas. Esto es útil para ver las operaciones de lectura y escritura realizadas en cada dispositivo, y puede ayudar a determinar si algún dispositivo individual está ralentizando el pool. Este ejemplo muestra un pool en espejo con dos dispositivos:

# zpool iostat -v
                            capacity     operations    bandwidth
pool                     alloc   free   read  write   read  write
-----------------------  -----  -----  -----  -----  -----  -----
data                      288G  1.53T      2     12  9.23K  61.5K
  mirror                  288G  1.53T      2     12  9.23K  61.5K
    ada1p1                   -      -      0      4  5.61K  61.7K
    ada2p1                   -      -      1      4  5.04K  61.7K
-----------------------  -----  -----  -----  -----  -----  -----

zpool iostat ofrece varias vistas más profundas de la canalización de E/S. -l añade columnas de latencia promedio, dividiendo el tiempo total de espera en tiempo de disco y tiempo pasado en las diversas colas de E/S. -q muestra el número de operaciones pendientes y activas en cada cola por vdev. -w imprime histogramas de latencia completos, y -r imprime histogramas de tamaño de solicitud para cada vdev hoja.

Las columnas de latencia de -l facilitan detectar un solo disco lento que ralentiza todo un vdev:

# zpool iostat -lv data
              capacity     operations     bandwidth    total_wait     disk_wait    syncq_wait    asyncq_wait  scrub   trim  rebuild
pool        alloc   free   read  write   read  write   read  write   read  write   read  write   read  write   wait   wait     wait
----------  -----  -----  -----  -----  -----  -----  -----  -----  -----  -----  -----  -----  -----  -----  -----  -----  -------
data         288G  1.53T    156    212  19.4M  26.6M   14ms  186ms    5ms  184ms    1us    2us    8ms    2ms      -      -        -
  mirror-0   288G  1.53T    156    212  19.4M  26.6M   14ms  186ms    5ms  184ms    1us    2us    8ms    2ms      -      -        -
    ada1p1      -      -     79    106   9.7M  13.3M    3ms    5ms    3ms    4ms    1us    2us    1ms    1ms      -      -        -
    ada2p1      -      -     77    106   9.7M  13.3M  212ms  187ms  208ms  183ms    1us    2us   15ms    3ms      -      -        -
----------  -----  -----  -----  -----  -----  -----  -----  -----  -----  -----  -----  -----  -----  -----  -----  -----  -------

En este ejemplo, ada2p1 necesita cientos de milisegundos de tiempo de disco para E/S que su socio de espejo ada1p1 completa en milisegundos de un solo dígito, mientras que ambos manejan un número similar de operaciones. Una escritura en el espejo solo se completa cuando el miembro más lento termina, por lo que la latencia de escritura de todo el vdev sigue a ada2p1. Una latencia alta con recuentos de operación normales, sin errores de lectura, escritura o suma de comprobación en zpool status, a menudo indica un disco que reintenta internamente y es candidato a reemplazo.

Los scripts que deben esperar a que finalice la actividad de fondo del pool pueden bloquearse en zpool wait:

# zpool wait -t scrub,resilver mypool

El comando regresa una vez que ninguna de las actividades nombradas, como scrub, resilver, trim o remove, está en progreso. Véase zpool-wait(8) para la lista completa de actividades.

zpool status, zpool list, zpool get y zfs list aceptan -j para producir salida JSON, que es más robusta para que los scripts analicen que las tablas legibles por humanos. La salida JSON requiere OpenZFS 2.3 o posterior, disponible por primera vez en FreeBSD 15.0.

23.3.21. División de un Pool de Almacenamiento

ZFS puede dividir un pool que consiste en uno o más vdevs en espejo en dos pools. A menos que se especifique lo contrario, ZFS desprende el último miembro de cada espejo y crea un nuevo pool que contiene los mismos datos. Asegúrese de hacer una prueba de simulación de la operación con -n primero. Esto muestra los detalles de la operación solicitada sin realizarla realmente. Esto ayuda a confirmar que la operación hará lo que el usuario pretende.

23.4. Administración de zfs

La utilidad zfs puede crear, destruir y administrar todos los conjuntos de datos ZFS existentes dentro de un pool. Para administrar el pool mismo, use zpool.

23.4.1. Creación y Destrucción de Conjuntos de Datos

A diferencia de los discos tradicionales y los administradores de volúmenes, el espacio en ZFS no se preasigna. Con los sistemas de archivos tradicionales, después de particionar y asignar el espacio, no hay forma de añadir un nuevo sistema de archivos sin añadir un nuevo disco. Con ZFS, es posible crear nuevos sistemas de archivos en cualquier momento. Cada conjunto de datos tiene propiedades que incluyen características como compresión, deduplicación, almacenamiento en caché y cuotas, así como otras propiedades útiles como solo lectura, sensibilidad a mayúsculas, compartición de archivos en red y un punto de montaje. Anidar conjuntos de datos dentro de otros es posible y los conjuntos de datos hijos heredarán propiedades de sus ancestros. Delegar, replicar, instantánea, jail permite administrar y destruir cada conjunto de datos como una unidad. Crear un conjunto de datos separado para cada tipo o conjunto de archivos diferente tiene ventajas. Los inconvenientes de tener un gran número de conjuntos de datos son que algunos comandos como zfs list serán más lentos, y que el montaje de cientos o incluso miles de conjuntos de datos ralentizará el proceso de arranque de FreeBSD.

Cree un nuevo conjunto de datos y habilite compresión LZ4 en él:

# zfs list
NAME                  USED  AVAIL  REFER  MOUNTPOINT
mypool                781M  93.2G   144K  none
mypool/ROOT           777M  93.2G   144K  none
mypool/ROOT/default   777M  93.2G   777M  /
mypool/tmp            176K  93.2G   176K  /tmp
mypool/usr            616K  93.2G   144K  /usr
mypool/usr/home       184K  93.2G   184K  /usr/home
mypool/usr/ports      144K  93.2G   144K  /usr/ports
mypool/usr/src        144K  93.2G   144K  /usr/src
mypool/var           1.20M  93.2G   608K  /var
mypool/var/crash      148K  93.2G   148K  /var/crash
mypool/var/log        178K  93.2G   178K  /var/log
mypool/var/mail       144K  93.2G   144K  /var/mail
mypool/var/tmp        152K  93.2G   152K  /var/tmp
# zfs create -o compress=lz4 mypool/usr/mydataset
# zfs list
NAME                   USED  AVAIL  REFER  MOUNTPOINT
mypool                 781M  93.2G   144K  none
mypool/ROOT            777M  93.2G   144K  none
mypool/ROOT/default    777M  93.2G   777M  /
mypool/tmp             176K  93.2G   176K  /tmp
mypool/usr             704K  93.2G   144K  /usr
mypool/usr/home        184K  93.2G   184K  /usr/home
mypool/usr/mydataset  87.5K  93.2G  87.5K  /usr/mydataset
mypool/usr/ports       144K  93.2G   144K  /usr/ports
mypool/usr/src         144K  93.2G   144K  /usr/src
mypool/var            1.20M  93.2G   610K  /var
mypool/var/crash       148K  極2G   148K  /var/crash
mypool/var/log         178K  93.2G   178K  /var/log
mypool/var/mail        144K  93.2G   極K  /var/mail
mypool/var/tmp         152K  93.2G   152K  /var/tmp

Destruir un conjunto de datos es mucho más rápido que eliminar los archivos en el conjunto de datos, ya que no implica escanear los archivos y actualizar los metadatos correspondientes.

Destruya el conjunto de datos creado:

# zfs list
NAME                   USED  AVAIL  REFER  MOUNTPOINT
mypool                 880M  93.1G   144K  none
mypool/ROOT            777M  93.1G   144K  none
mypool/極/default    777M  93.1G   777M  /
mypool/tmp             176K  93.1G   176K  /tmp
mypool/usr             101M  93.1G   144K  /usr
mypool/usr/home        184K  93.1G   184K  /usr/home
mypool/usr/mydataset   100M  93.1G   100M  /usr/mydataset
mypool/usr/ports       144K  93.1G   144K  /usr/ports
mypool/usr/src         144K  93.1G   144K  /usr/src
mypool/var            1.20M  93.1G   610K  /var
mypool/var/crash       148K  93.1G   148K  /極/crash
mypool/var/log         178K  93.1G   178K  /var/log
mypool/var/mail        144K  93.1G   144K  /var/mail
mypool/var/tmp         152K  93.1G   152K  /var/tmp
# zfs destroy mypool/usr/mydataset
# zfs list
NAME                  USED  AVAIL  REFER  MOUNTPOINT
mypool                781M  93.2G   144K  none
mypool/ROOT           777M  93.2G   144极  none
mypool/ROOT/default   777M  93.2G   777M  /
mypool/tmp            176K  93.2G   176K  /tmp
mypool/usr            616K  93.2G   144K  /usr
mypool/usr/home       184K  93.2G   184K  /usr/home
mypool/usr/ports      144K  93.2G   144K  /usr/ports
mypool/usr/src        144K  93.2G   144K  /usr/src
mypool/var           1.21M  93.2G   612K  /var
mypool/var/crash      148K  93.2G   148K  /var/crash
mypool/var/log        178K  93.2G   178K  /var/log
mypool/var/mail       144K  93.2G   144K  /var/mail
mypool/var/tmp        152K  93.2G   152K  /var/tmp

En las versiones modernas de ZFS, zfs destroy es asíncrono, y el espacio libre puede tardar minutos en aparecer en el grupo. Use zpool get freeing nombredegrupo para ver la propiedad freeing, que muestra cuánto espacio queda por reclamar en segundo plano. Use zpool wait -t free nombredegrupo para esperar hasta que la liberación en segundo plano se complete. Si hay conjuntos de datos secundarios, como instantáneas u otros conjuntos de datos, es imposible destruir el principal. Para destruir un conjunto de datos y sus secundarios, use -r para destruir recursivamente el conjunto de datos y sus secundarios. Use -n -v para listar los conjuntos de datos e instantáneas destruidos por esta operación, sin destruir realmente nada. El espacio reclamado al destruir instantáneas también se muestra.

23.4.2. Creación y Destrucción de Volúmenes

Un volumen es un tipo especial de conjunto de datos. En lugar de montarse como un sistema de archivos, se expone como un dispositivo de bloques bajo /dev/zvol/nombredelgrupo/conjuntodedatos. Esto permite usar el volumen para otros sistemas de archivos, para respaldar los discos de una máquina virtual, o para ponerlo a disposición de otros hosts de red usando protocolos como iSCSI o HAST.

Formatee un volumen con cualquier sistema de archivos o sin sistema de archivos para almacenar datos en bruto. Para el usuario, un volumen aparece como un disco normal. Poner sistemas de archivos ordinarios en estos zvols proporciona características que los discos ordinarios o sistemas de archivos no tienen. Por ejemplo, usar la propiedad de compresión en un volumen de 250 MB permite crear un sistema de archivos FAT comprimido.

# zfs create -V 250m -o compression=on tank/fat32
# zfs list tank
NAME USED AVAIL REFER MOUNTPOINT
tank 258M  670M   31K /tank
# newfs_msdos -F32 /dev/zvol/tank/fat32
# mount -极 msdosfs /dev/zvol/tank/fat32 /mnt
# df -h /mnt | grep fat32
Filesystem           Size Used Avail Capacity Mounted on
/dev/zvol/tank/fat32 249M  24k  249M     0%   /mnt
# mount | grep fat32
/dev/zvol/tank/fat32 on /mnt (msdosfs, local)

Crear un volumen reserva suficiente espacio en el grupo para contener el tamaño completo del volumen. Para omitir esa reserva, cree un volumen disperso, también conocido como volumen con aprovisionamiento fino, con -s:

# zfs create -s -V 250g tank/bigdisk

Los volúmenes dispersos permiten comprometer más espacio del que el grupo tiene realmente. Las escrituras en un volumen disperso pueden fallar con ENOSPC cuando el grupo se queda sin espacio, así que use volúmenes dispersos solo donde el consumidor del volumen tolere errores de escritura.

La propiedad volmode controla cómo ZFS expone un volumen al sistema operativo. Establecerla en full expone el volumen como un proveedor GEOM con funcionalidad máxima, y geom es un alias para full. Establecerla en dev expone el volumen como un nodo de dispositivo plano, ocultando cualquier partición que contenga. Los volúmenes con volmode establecido en none no se exponen fuera de ZFS en absoluto, pero aún admiten instantáneas, clones y replicación, lo que los hace útiles como objetivos de replicación. La propiedad por defecto es default, que defería al ajuste global del sistema zvol_volmode descrito en zfs(4).

Los volúmenes funcionan bien como discos virtuales para máquinas virtuales bhyve(8) y como almacenamiento de respaldo para extensiones iSCSI: declare el dispositivo de volumen como un LUN en ctl.conf(5) y sírvalo con ctld(8).

No coloque espacio de intercambio (swap) en volúmenes ZFS. Cuando el sistema tiene poca memoria, el propio ZFS necesita memoria para completar la escritura que liberaría memoria, y el sistema puede bloquearse. Consulte el problema de OpenZFS upstream openzfs/zfs#7734 para más detalles. Use una partición de intercambio dedicada en su lugar.

Destruir un volumen es muy similar a destruir un conjunto de datos de sistema de archivos regular. La operación es casi instantánea, pero puede tardar minutos en reclamar el espacio libre en segundo plano.

23.4.3. Renombrar un Conjunto de Datos

Para cambiar el nombre de un conjunto de datos, use zfs rename. Para cambiar el principal de un conjunto de datos, use también este comando. Renombrar un conjunto de datos para tener un conjunto de datos principal diferente cambiará el valor de aquellas propiedades heredadas del conjunto de datos principal. Renombrar un conjunto de datos lo desmonta y luego lo vuelve a montar en la nueva ubicación (heredada del nuevo conjunto de datos principal). Para prevenir este comportamiento, use -u.

Renombre un conjunto de datos y muévalo para que esté bajo un conjunto de datos principal diferente:

# zfs list
NAME                   USED  AVAIL  REFER  MOUNTPOINT
mypool                 780M  93.2G   144K  none
mypool/ROOT            777M  93.2G   144K  none
mypool/ROOT/default    777M  93.2G   777M  /
mypool/tmp             176K  93.2G   176K  /tmp
mypool/usr             704K  93.2极   144K  /usr
mypool/usr/home        184K  93.2G   184K  /usr/home
mypool/usr/mydataset  87.5K  93.2G  87.5K  /usr/mydataset
mypool/usr/ports       144K  93.2G   144K  /usr/ports
mypool/usr/src         144K  93.2G   144K  /usr/src
mypool/var            1.21M  93.2G   614K  /var
mypool/var/crash       148K  93.2G   148K  /var/crash
mypool/var/log         178K  93.2G   178K  /var/log
mypool/var/mail        144K  93.2G   144K  /var/mail
mypool/var/tmp         152K  93.2G   152K  /var/tmp
# zfs rename mypool/usr/mydataset mypool/var/newname
# zfs list
NAME                  USED  AVAIL  REFER  MOUNTPOINT
mypool                780M  93.2G   144K  none
mypool/ROOT           777M  93.2G   144K  none
mypool/ROOT/default   777M  93.2G   777M  /
mypool/tmp            176K  93.2G   176K  /tmp
mypool/usr            616K  93.2G   144K  /usr
mypool/usr/home       184K  93.2G   184K  /usr/home
mypool/usr/ports      144K  93.2G   144K  /usr/ports
mypool/usr/src        144K  93.2G   144K  /usr/src
mypool/var           1.29M  93.2G   614K  /var
mypool/var/crash      148K  93.2G   148K  /var/crash
mypool/var/log        178K  93.2G   178K  /var/log
mypool/var/mail       144K  93.2G   144K  /var/mail
mypool/var/newname   87.5K  93.2G  87.5K  /var/极wname
mypool/var/tmp        152K  93.2G   152K  /var/tmp

Renombrar instantáneas usa el mismo comando. Debido a la naturaleza de las instantáneas, el renombrado no puede cambiar su conjunto de datos principal. Para renombrar una instantánea recursiva, especifique -r; esto también renombrará todas las instantáneas con el mismo nombre en los conjuntos de datos secundarios.

# zfs list -t snapshot
NAME                                USED  AVAIL  REFER  MOUNTPOINT
mypool/var/newname@first_snapshot      0      -  87.5K  -
# zfs rename mypool/var/newname@first_snapshot new_snapshot_name
# zfs list -t snapshot
NAME                                   USED  AVAIL  REFER  MOUNTPOINT
mypool/var/newname@new_snapshot_name      0      -  87.5K  -

23.4.4. Establecimiento de Propiedades del Conjunto de Datos

Cada conjunto de datos ZFS tiene propiedades que controlan su comportamiento. La mayoría de las propiedades se heredan automáticamente del conjunto de datos principal, pero se pueden anular localmente. Establezca una propiedad en un conjunto de datos con zfs set propiedad=valor conjunto_de_datos. La mayoría de las propiedades tienen un conjunto limitado de valores válidos, zfs get mostrará cada propiedad posible y los valores válidos. Usar zfs inherit revierte la mayoría de las propiedades a sus valores heredados. También son posibles las propiedades definidas por el usuario. Se convierten en parte de la configuración del conjunto de datos y proporcionan más información sobre el conjunto de datos o su contenido. Para distinguir estas propiedades personalizadas de las suministradas como parte de ZFS, use dos puntos (:) para crear un espacio de nombres personalizado para la propiedad.

# zfs set custom:costcenter=1234 tank
# zfs get custom:costcenter tank
NAME PROPERTY           VALUE SOURCE
tank custom:costcenter  1234  local

Para eliminar una propiedad personalizada, use zfs inherit con -r. Si la propiedad personalizada no está definida en ninguno de los conjuntos de datos principales, esta opción la elimina (pero el historial del grupo aún registra el cambio).

# zfs inherit -r custom:costcenter tank
# zfs get custom:costcenter tank
NAME    PROPERTY           VALUE              SOURCE
tank    custom:costcenter  -                  -
# zfs get all tank | grep custom:costcenter
#

23.4.4.1. Obtención y Establecimiento de Propiedades de Compartición

Dos propiedades de conjunto de datos comúnmente utilizadas y útiles son las opciones de compartición NFS y SMB. Establecer estas define si y cómo ZFS comparte conjuntos de datos en la red. En FreeBSD, ZFS se integra con el servidor NFS en el sistema base: establecer la propiedad sharenfs exporta el conjunto de datos a través de mountd(8). ZFS escribe la entrada de exportación en /etc/zfs/exports, que mountd(8) lee además de /etc/exports. Compartir conjuntos de datos requiere que el servidor NFS esté habilitado en /etc/rc.conf:

zfs_enable="YES"
nfs_server_enable="YES"

El valor de sharenfs es on, off, o una lista de opciones de exports(5) para aplicar a la exportación.

Para obtener el estado actual de una compartición, ingrese:

# zfs get sharenfs mypool/usr/home
NAME             PROPERTY  VALUE    SOURCE
mypool/usr/home  sharenfs  on       local

Para habilitar la compartición de un conjunto de datos, ingrese:

#  zfs set sharenfs=on mypool/usr/home

Establezca otras opciones para compartir conjuntos de datos a través de NFS, como -alldirs, -maproot y -network. Para establecer opciones en un conjunto de datos compartido a través de NFS, ingrese:

#  zfs set sharenfs="-alldirs,-maproot=root,-network=192.168.1.0/24" mypool/usr/home

La propiedad sharesmb no es funcional en FreeBSD, ya que la biblioteca de compartición implementa solo NFS. Para servir un conjunto de datos a través de SMB, instale un paquete como net/samba422 y exporte la ruta del conjunto de datos montado en su configuración.

23.4.5. ACLs NFSv4

ZFS en FreeBSD almacena ACLs de estilo NFSv4 de forma nativa; la propiedad acltype del conjunto de datos tiene como valor predeterminado nfsv4. Cada archivo y directorio puede llevar una lista de control de acceso junto con los bits de permiso tradicionales, brindando un control más granular que el modelo propietario/grupo/otros. Muestre y edite estas listas con getfacl(1) y setfacl(1).

Muestre la ACL de un archivo:

% getfacl /usr/home/alice/notes.txt
# file: /usr/home/alice/notes.txt
# owner: alice
# group: alice
            owner@:rw-p--aARWcCos:-------:allow
            group@:r-----a-R-c--s:-------:allow
         everyone@:r-----a-R-c--极:-------:allow

Conceda a un usuario adicional acceso de escritura agregando una entrada allow:

% setfacl -m u:bob:rwp::allow /usr/home/alice/notes.txt

Dos propiedades del conjunto de datos controlan cómo las ACLs interactúan con el manejo de permisos tradicional. La propiedad aclmode (discard, groupmask, passthrough, o restricted) gobierna lo que sucede con la ACL cuando chmod(1) cambia los bits de permiso de un archivo. Con el valor predeterminado, discard, chmod elimina todas las entradas de ACL que no representan el nuevo modo de archivo. La propiedad aclinherit (discard, noallow, restricted, passthrough, o passthrough-x) gobierna qué entradas de ACL heredan los nuevos archivos y directorios de su directorio principal. Con el valor predeterminado, restricted, las entradas heredadas pierden los permisos write_acl y write_owner.

Consulte setfacl(1) y zfsprops(7) para la sintaxis completa de entrada y las descripciones de propiedades.

23.4.6. Gestión de Instantáneas

Las instantáneas son una de las características más potentes de ZFS. Una instantánea proporciona una copia de solo lectura, puntual del conjunto de datos. Con Copy-On-Write (COW), ZFS crea instantáneas rápidamente al preservar versiones más antiguas de los datos en disco. Si no existen instantáneas, ZFS reclama espacio para uso futuro cuando se reescriben o eliminan datos. Las instantáneas preservan espacio en disco al registrar solo las diferencias entre el conjunto de datos actual y una versión anterior. Permitiendo instantáneas en conjuntos de datos completos, no en archivos o directorios individuales. Una instantánea de un conjunto de datos duplica todo lo contenido en él. Esto incluye las propiedades del sistema de archivos, archivos, directorios, permisos, etc. Las instantáneas no usan espacio extra cuando se crean por primera vez, pero consumen espacio a medida que cambian los bloques a los que hacen referencia. Las instantáneas recursivas tomadas con -r crean instantáneas con el mismo nombre en el conjunto de datos y sus secundarios, proporcionando una instantánea puntual consistente de los sistemas de archivos. Esto puede ser importante cuando una aplicación tiene archivos en conjuntos de datos relacionados o que dependen unos de otros. Sin instantáneas, una copia de seguridad tendría copias de los archivos de diferentes puntos en el tiempo.

Las instantáneas en ZFS proporcionan una variedad de características que incluso otros sistemas de archivos con funcionalidad de instantáneas carecen. Un ejemplo típico del uso de instantáneas es como una forma rápida de respaldar el estado actual del sistema de archivos al realizar una acción riesgosa como una instalación de software o una actualización del sistema. Si la acción falla, revertir a la instantánea devuelve el sistema al mismo estado en que se creó la instantánea. Si la actualización fue exitosa, elimine la instantánea para liberar espacio. Sin instantáneas, una actualización fallida a menudo requiere restaurar copias de seguridad, lo cual es tedioso, consume tiempo y puede requerir tiempo de inactividad durante el cual el sistema es inutilizable. Revertir a instantáneas es rápido, incluso mientras el sistema se ejecuta en operación normal, con poco o ningún tiempo de inactividad. El ahorro de tiempo es enorme con sistemas de almacenamiento de múltiples terabytes considerando el tiempo requerido para copiar los datos desde la copia de seguridad. Las instantáneas no son un reemplazo para una copia de seguridad completa de un grupo, pero ofrecen una forma rápida y fácil de almacenar una copia de un conjunto de datos en un momento específico.

23.4.6.1. Creación de Instantáneas

Para crear instantáneas, use zfs snapshot conjunto_de_datos@nombre_de_instantánea. Agregar -r crea una instantánea recursivamente, con el mismo nombre en todos los conjuntos de datos secundarios.

Cree una instantánea recursiva de todo el grupo:

# zfs list -t all
NAME                                   USED  AVAIL  REFER  MOUNTPOINT
mypool                                 780M  93.2G   144K  none
mypool/ROOT                            777M  93.2G   144K  none
mypool/ROOT/default                    777M  93.2G   777M  /
mypool/tmp                             176K  93.2G   176K  /tmp
mypool/usr                             616K  93.2G   144K  /usr
mypool/usr/home                        184K  93.2G   184K  /usr/home
mypool/usr/ports                       144K  93.2G   144K  /usr/ports
mypool/usr/src                         144K  93.2G   144K  /usr/src
mypool/var                            1.29M  93.2G   616K  /var
mypool/var/crash                       148K  93.2G   148K  /var/crash
mypool/var/log                         178K  93.2G   178K  /var/log
mypool/var/mail                        144K  93.2G   144K  /var/mail
mypool/var/newname                    87.5K  93.2G  87.5K  /var/newname
mypool/var/newname@new_snapshot_name      0      -  87.5K  -
mypool/var/tmp                         152K  93.2G   152K  /var/t极
# zfs snapshot -r mypool@my_recursive_snapshot
# zfs list -t snapshot
NAME                                        USED  AVAIL  REFER  MOUNTPOINT
mypool@my_recursive_snapshot                   0      -   144K  -
mypool/ROOT@my_recursive_snapshot              0      -   144K  -
mypool/ROOT/default@my_recursive_snapshot      0      -   777M  -
mypool/tmp@my极ecursive_snapshot               0      -   176K  -
mypool/usr@my_recursive_snapshot               0      -   144K  -
mypool/usr/home@my_recursive_snapshot          0      -   184K  -
mypool/usr/ports@my_recursive_snapshot         0      -   144K  -
mypool/usr/src@my_recursive_snapshot           极      -   144K  -
mypool/var@my_recursive_snapshot               0      -   616K  -
mypool/var/crash@my_recursive_snapshot         0      -   148K  -
mypool/var/log@my_recursive_snapshot           0      -   178K  -
mypool/var/mail@my_recursive_snapshot          0      -   144K  -
mypool/var/newname@new_snapshot_name           0      -  87.5K  -
mypool/var/newname@my_recursive_snapshot       0      -  87.5K  -
mypool/var/tmp@my_recursive_snapshot           0      -   152K  -

Las instantáneas no se muestran mediante una operación normal de zfs list. Para listar instantáneas, agregue -t snapshot a zfs list. -t all muestra tanto sistemas de archivos como instantáneas.

Las instantáneas no se montan directamente, mostrando ninguna ruta en la columna MOUNTPOINT. ZFS no menciona espacio en disco disponible en la columna AVAIL, ya que las instantáneas son de solo lectura después de su creación. Compare la instantánea con el conjunto de datos original:

# zfs list -rt all mypool/usr/home
NAME                                    USED  AVAIL  REFER  MOUNTPOINT
mypool/usr/home                         184K  93.2G   184K  /usr/home
mypool/usr/home@my_recursive_snapshot      0      -   184K  -

Mostrar tanto el conjunto de datos como la instantánea juntos revela cómo funcionan las instantáneas de forma COW. Guardan los cambios (delta) realizados y no el contenido completo del sistema de archivos de nuevo. Esto significa que las instantáneas ocupan poco espacio al realizar cambios. Observe aún más el uso del espacio copiando un archivo al conjunto de datos y luego creando una segunda instantánea:

# cp /etc/passwd /var/tmp
# zfs snapshot mypool/var/tmp@after_cp
# zfs list -rt all mypool/var/tmp
NAME                                   USED  AVAIL  REFER  MOUNTPOINT
mypool/var/tmp                         206K  93.2G   118K  /var/tmp
mypool/var/tmp@my_recursive_snapshot    88K      -   152K  -
mypool/var/tmp@after_cp                   0      -   118K  -

La segunda instantánea contiene los cambios en el conjunto de datos después de la operación de copia. Esto produce enormes ahorros de espacio. Observe que el tamaño de la instantánea mypool/var/tmp@my_recursive_snapshot también cambió en la columna USED para mostrar los cambios entre ella y la instantánea tomada después.

23.4.6.2. Comparación de Instantáneas

ZFS proporciona un comando integrado para comparar las diferencias de contenido entre dos instantáneas. Esto es útil con muchas instantáneas tomadas a lo largo del tiempo cuando el usuario quiere ver cómo ha cambiado el sistema de archivos con el tiempo. Por ejemplo, zfs diff permite a un usuario encontrar la última instantánea que aún contiene un archivo eliminado por accidente. Hacer esto para las dos instantáneas creadas en la sección anterior produce esta salida:

# zfs list -rt all mypool/var/tmp
NAME                                   USED  AVAIL  REFER  MOUNTPOINT
mypool/var/tmp                         206K  93.2G   118K  /var/tmp
mypool/var/tmp@my_recursive_snapshot    88K      -   152K  -
mypool/var/tmp@after_cp                   0      -   118K  -
# zfs diff mypool/var/tmp@my_recursive_snapshot
M       /var/tmp/
+       /var/tmp/passwd

El comando enumera los cambios entre la instantánea especificada (en este caso mypool/var/tmp@my_recursive_snapshot) y el sistema de archivos en vivo. La primera columna muestra el tipo de cambio:

+

Añadir la ruta o archivo.

-

Eliminar la ruta o archivo.

M

Modificar la ruta o archivo.

R

Renombrar la ruta o archivo.

Comparando la salida con la tabla, queda claro que ZFS añadió passwd después de crear la instantánea mypool/var/tmp@my_recursive_snapshot. Esto también resultó en una modificación al directorio padre montado en /var/tmp.

Comparar dos instantáneas es útil cuando se utiliza la función de replicación de ZFS para transferir un conjunto de datos a un host diferente con fines de respaldo.

Compare dos instantáneas proporcionando el nombre completo del conjunto de datos y el nombre de la instantánea de ambos conjuntos de datos:

# cp /var/tmp/passwd /var/tmp/passwd.copy
# zfs snapshot mypool/var/tmp@diff_snapshot
# zfs diff mypool/var/tmp@my_recursive_snapshot mypool/var/tmp@diff_snapshot
M       /var/tmp/
+       /var/tmp/passwd
+       /var/tmp/passwd.copy
# zfs diff mypool/var/tmp@my_recursive_snapshot mypool/var/tmp@after_cp
M       /var/tmp/
+       /var/tmp/passwd

Un administrador de respaldos puede comparar dos instantáneas recibidas del host de envío y determinar los cambios reales en el conjunto de datos. Consulte la sección Replicación para obtener más información.

23.4.6.3. Retroceso de Instantánea

Cuando hay al menos una instantánea disponible, retroceda a ella en cualquier momento. Con mayor frecuencia, esto ocurre cuando el estado actual del conjunto de datos ya no es válido o se prefiere una versión anterior. Escenarios como pruebas de desarrollo local que salieron mal, actualizaciones del sistema defectuosas que dificultan la funcionalidad del sistema, o la necesidad de restaurar archivos o directorios eliminados son ocurrencias demasiado comunes. Para retroceder a una instantánea, use zfs rollback nombredeinstantánea. Si hay muchos cambios presentes, la operación tomará mucho tiempo. Durante ese tiempo, el conjunto de datos siempre permanece en un estado consistente, muy parecido a una base de datos que cumple con los principios ACID y está realizando un retroceso. Esto sucede mientras el conjunto de datos está activo y accesible sin requerir tiempo de inactividad. Una vez que se retrocede a la instantánea, el conjunto de datos tiene el mismo estado que tenía cuando se tomó la instantánea originalmente. Retroceder a una instantánea descarta todos los demás datos en ese conjunto de datos que no forman parte de la instantánea. Tomar una instantánea del estado actual del conjunto de datos antes de retroceder a uno anterior es una buena idea cuando se necesitan algunos datos más tarde. De esta manera, el usuario puede retroceder y avanzar entre instantáneas sin perder datos que aún son valiosos.

En el primer ejemplo, retroceda a una instantánea porque una operación descuidada de rm eliminó más datos de los deseados.

# zfs list -rt all mypool/var/tmp
NAME                                   USED  AVAIL  REFER  MOUNTPOINT
mypool/var/tmp                         262K  93.2G   120K  /var/tmp
mypool/var/tmp@my_recursive_snapshot    88K      -   152K  -
mypool/var/tmp@after_cp               53.5K      -   118K  -
mypool/var/tmp@diff_snapshot              0      -   120K  -
# ls /var/tmp
passwd          passwd.copy     vi.recover
# rm /var/tmp/passwd*
# ls /var/tmp
vi.recover

En este punto, el usuario nota la eliminación de archivos adicionales y quiere recuperarlos. ZFS proporciona una manera fácil de recuperarlos usando retrocesos, cuando se realizan instantáneas de datos importantes de forma regular. Para recuperar los archivos y comenzar de nuevo desde la última instantánea, ejecute el comando:

# zfs rollback mypool/var/tmp@diff_snapshot
# ls /var/tmp
passwd          passwd.copy     vi.recover

La operación de retroceso restauró el conjunto de datos al estado de la última instantánea. También es posible retroceder a una instantánea tomada mucho antes con otras instantáneas tomadas después. Al intentar hacer esto, ZFS emitirá esta advertencia:

# zfs list -rt snapshot mypool/var/tmp
NAME                                   USED  AVAIL  REFER  MOUNTPOINT
mypool/var/tmp@my_recursive_snapshot    88K      -   152K  -
mypool/var/tmp@after_cp               53.5K      -   118K  -
mypool/var/tmp@diff_snapshot              0      -   120K  -
# zfs rollback mypool/var/tmp@my_recursive_snapshot
cannot rollback to 'mypool/var/tmp@my_recursive_snapshot': more recent snapshots exist
use '-r' to force deletion of the following snapshots:
mypool/var/tmp@after_cp
mypool/var/tmp@diff_snapshot

Esta advertencia significa que existen instantáneas entre el estado actual del conjunto de datos y la instantánea a la que el usuario quiere retroceder. Para completar el retroceso elimine estas instantáneas. ZFS no puede rastrear todos los cambios entre los diferentes estados del conjunto de datos, porque las instantáneas son de solo lectura. ZFS no eliminará las instantáneas afectadas a menos que el usuario especifique -r para confirmar que esta es la acción deseada. Si esa es la intención, y comprende las consecuencias de perder todas las instantáneas intermedias, ejecute el comando:

# zfs rollback -r mypool/var/tmp@my_recursive_snapshot
# zfs list -rt snapshot mypool/var/tmp
NAME                                   USED  AVAIL  REFER  MOUNTPOINT
mypool/var/tmp@my_recursive_snapshot     8K      -   152K  -
# ls /var/tmp
vi.recover

La salida de zfs list -t snapshot confirma la eliminación de las instantáneas intermedias como resultado de zfs rollback -r.

23.4.6.4. Restauración de Archivos Individuales desde Instantáneas

Las instantáneas residen en un directorio oculto bajo el conjunto de datos padre: .zfs/snapshot/nombredeinstantánea. Por defecto, estos directorios no se mostrarán incluso al ejecutar un ls -a estándar. Aunque el directorio no se muestra, acceda a él como cualquier directorio normal. La propiedad llamada snapdir controla si estos directorios ocultos aparecen en un listado de directorios. Establecer la propiedad a visible permite que aparezcan en la salida de ls y otros comandos que tratan con el contenido del directorio.

# zfs get snapdir mypool/var/tmp
NAME            PROPERTY  VALUE    SOURCE
mypool/var/tmp  snapdir   hidden   default
# ls -a /var/tmp
.               ..              passwd          vi.recover
# zfs set snapdir=visible mypool/var/tmp
# ls -a /var/tmp
.               ..              .zfs            passwd          vi.recover

Restaurar archivos individuales a un estado anterior copiándolos desde la instantánea de vuelta al conjunto de datos padre. La estructura de directorios debajo de .zfs/snapshot tiene un directorio con el nombre de las instantáneas tomadas anteriormente para facilitar su identificación. El siguiente ejemplo muestra cómo restaurar un archivo desde el directorio oculto .zfs copiándolo desde la instantánea que contiene la última versión del archivo:

# rm /var/tmp/passwd
# ls -a /var/tmp
.               ..              .zfs            vi.recover
# ls /var/tmp/.zfs/snapshot
after_cp                my_recursive_snapshot
# ls /var/tmp/.zfs/snapshot/after_cp
passwd          vi.recover
# cp /var/tmp/.zfs/snapshot/after_cp/passwd /var/tmp

Incluso si la propiedad snapdir está establecida en oculto, ejecutar ls .zfs/snapshot aún listará el contenido de ese directorio. El administrador decide si mostrar estos directorios. Esta es una configuración por conjunto de datos. Copiar archivos o directorios desde este .zfs/snapshot oculto es bastante simple. Intentarlo al revés resulta en este error:

# cp /etc/rc.conf /var/tmp/.zfs/snapshot/after_cp/
cp: /var/tmp/.zfs/snapshot/after_cp/rc.conf: Read-only file system

El error recuerda al usuario que las instantáneas son de solo lectura y no pueden cambiar después de su creación. Tanto copiar archivos como eliminarlos de los directorios de instantáneas no está permitido porque eso cambiaría el estado del conjunto de datos que representan.

Las instantáneas consumen espacio en función de cuánto ha cambiado el sistema de archivos padre desde el momento de la instantánea. La propiedad used de una instantánea rastrea el espacio que usa la instantánea; su propiedad written muestra cuántos datos se escribieron entre la instantánea anterior y esta.

Para destruir instantáneas y reclamar el espacio, use zfs destroy conjuntodedatos@instantánea. Agregar -r elimina recursivamente todas las instantáneas con el mismo nombre bajo el conjunto de datos padre. Agregar -n -v al comando muestra una lista de las instantáneas que se eliminarán y una estimación del espacio que reclamaría sin realizar la operación de destrucción real.

23.4.6.5. Retenciones de Instantáneas

Una retención coloca una etiqueta definida por el usuario en una instantánea y evita su destrucción. Los intentos de destruir una instantánea retenida con zfs destroy fallan con EBUSY. Una instantánea puede llevar cualquier número de retenciones, cada una identificada por un nombre de etiqueta único. Las retenciones protegen instantáneas de las que otros procesos aún dependen, como la instantánea más reciente compartida por ambos lados de una cadena de replicación (ver Replicación). Destruir esa instantánea común por accidente obliga a la próxima replicación a comenzar de nuevo con un flujo completo.

Coloque una retención con zfs hold etiqueta instantánea. Agregar -r también retiene las instantáneas con el mismo nombre en todos los conjuntos de datos hijos.

# zfs hold keepme mypool/var/tmp@my_recursive_snapshot
# zfs destroy mypool/var/tmp@my_recursive_snapshot
cannot destroy snapshot mypool/var/tmp@my_recursive_snapshot: dataset is busy

zfs holds enumera las retenciones en una instantánea, mostrando el nombre de la etiqueta y la hora de colocar cada retención:

# zfs holds mypool/var/tmp@my_recursive_snapshot
NAME                                  TAG     TIMESTAMP
mypool/var/tmp@my_recursive_snapshot  keepme  Sat Jul 11 09:41 2026

Elimine una retención con zfs release. Destruir la instantánea se vuelve posible nuevamente una vez que se libera la última retención sobre ella:

# zfs release keepme mypool/var/tmp@my_recursive_snapshot
# zfs destroy mypool/var/tmp@my_recursive_snapshot

Consulte zfs-hold(8) para obtener más información.

23.4.7. Marcadores

Un marcador registra el punto en el tiempo en que se creó una instantánea, sin conservar ninguno de los datos de la instantánea. Los marcadores consumen casi ningún espacio, sin importar cuánto cambie el conjunto de datos después. Como una instantánea, un marcador puede servir como fuente de un zfs send incremental. A diferencia de una instantánea, no impide que ZFS libere los datos antiguos. Esta combinación hace que los marcadores sean útiles para la replicación incremental: después de enviar una instantánea a otro pool, marcarla y destruirla en el lado de envío, reclamando el espacio mientras el lado receptor mantiene su copia de la instantánea. Consulte Respaldos Incrementales para el flujo de trabajo de replicación en sí.

Cree un marcador a partir de una instantánea con zfs bookmark. Los nombres de marcadores usan # como separador entre el nombre del conjunto de datos y el nombre del marcador, de la misma manera que los nombres de instantáneas usan @.

# zfs snapshot mypool/data@snap1
# zfs send mypool/data@snap1 | zfs receive backup/data
# zfs bookmark mypool/data@snap1 mypool/data#snap1bm
# zfs destroy mypool/data@snap1

Enumere los marcadores con zfs list -t bookmark:

# zfs list -t bookmark mypool/data
NAME                 USED  AVAIL  REFER  MOUNTPOINT
mypool/data#snap1bm     -      -   184K  -

Cuando llega el momento para el próximo respaldo incremental, tome una nueva instantánea y use el marcador como fuente incremental:

# zfs snapshot mypool/data@snap2
# zfs send -i mypool/data#snap1bm mypool/data@snap2 | zfs receive backup/data

Esto funciona porque el pool receptor aún tiene la instantánea backup/data@snap1 que coincide con el marcador. Los marcadores sirven solo como fuentes incrementales. Montar un marcador, retroceder a él o restaurar archivos desde él es imposible, ya que no contiene datos. Consulte zfs-bookmark(8) para obtener más información.

23.4.8. Gestión de Clones

Un clon es una copia de una instantánea tratada más como un conjunto de datos regular. A diferencia de una instantánea, un clon es escribible y montable, y tiene sus propias propiedades. Después de crear un clon usando zfs clone, destruir la instantánea originadora es imposible. Para revertir la relación hijo/padre entre el clon y la instantánea use zfs promote. Promover un clon hace que la instantánea se convierta en un hijo del clon, en lugar del conjunto de datos padre original. Esto cambiará cómo ZFS contabiliza el espacio, pero no cambiará realmente la cantidad de espacio consumido. Es posible montar el clon en cualquier lugar dentro de la jerarquía del sistema de archivos ZFS, no solo debajo de la ubicación original de la instantánea.

Para mostrar la función de clon use este conjunto de datos de ejemplo:

# zfs list -rt all camino/home/joe
NAME                    USED  AVAIL  REFER  MOUNTPOINT
camino/home/joe         108K   1.3G    87K  /usr/home/joe
camino/home/joe@plans    21K      -  85.5K  -
camino/home/joe@backup    0K      -    87K  -

Un uso típico para los clones es experimentar con un conjunto de datos específico mientras se mantiene la instantánea disponible para retroceder en caso de que algo salga mal. Dado que las instantáneas no pueden cambiar, cree un clon de lectura/escritura de una instantánea. Después de lograr el resultado deseado en el clon, promueva el clon a un conjunto de datos y elimine el sistema de archivos antiguo. Eliminar el conjunto de datos padre no es estrictamente necesario, ya que el clon y el conjunto de datos pueden coexistir sin problemas.

# zfs clone camino/home/joe@backup camino/home/joenew
# ls /usr/home/joe*
/usr/home/joe:
backup.txz     plans.txt
/usr/home/joenew:
backup.txz     plans.txt
# df -h /usr/home
Filesystem          Size    Used   Avail Capacity  Mounted on
usr/home/joe        1.3G     31k    1.3G     0%    /usr/home/joe
usr/home/joenew     1.3G     31k    1.3G     0%    /usr/home/joenew

Crear un clon lo convierte en una copia exacta del estado en el que se encontraba el conjunto de datos al tomar la instantánea. Ahora es posible cambiar el clon de forma independiente de su conjunto de datos de origen. La conexión entre los dos es la instantánea. ZFS registra esta conexión en la propiedad origin. Promover el clon con zfs promote convierte al clon en un conjunto de datos independiente. Esto elimina el valor de la propiedad origin y desconecta el nuevo conjunto de datos independiente de la instantánea. Este ejemplo lo muestra:

# zfs get origin camino/home/joenew
NAME                  PROPERTY  VALUE                     SOURCE
camino/home/joenew    origin    camino/home/joe@backup    -
# zfs promote camino/home/joenew
# zfs get origin camino/home/joenew
NAME                  PROPERTY  VALUE   SOURCE
camino/home/joenew    origin    -       -

Después de realizar algunos cambios, como copiar loader.conf al clon promovido, por ejemplo, el directorio antiguo se vuelve obsoleto en este caso. En su lugar, el clon promovido puede reemplazarlo. Para hacer esto, primero zfs destroy el conjunto de datos antiguo y luego zfs rename el clon al nombre del conjunto de datos antiguo (o a un nombre completamente diferente).

# cp /boot/defaults/loader.conf /usr/home/joenew
# zfs destroy -f camino/home/joe
# zfs rename camino/home/joenew camino/home/joe
# ls /usr/home/joe
backup.txz     loader.conf     plans.txt
# df -h /usr/home
Filesystem          Size    Used   Avail Capacity  Mounted on
usr/home/joe        1.3G    128k    1.3G     0%    /usr/home/joe

La instantánea clonada es ahora un conjunto de datos ordinario. Contiene todos los datos de la instantánea original más los archivos añadidos a ella como loader.conf. Los clones proporcionan características útiles a los usuarios de ZFS en diferentes escenarios. Por ejemplo, proporcionar jaulas como instantáneas que contienen diferentes conjuntos de aplicaciones instaladas. Los usuarios pueden clonar estas instantáneas y añadir sus propias aplicaciones como consideren oportuno. Una vez satisfechos con los cambios, promueven los clones a conjuntos de datos completos y los proporcionan a los usuarios finales para que trabajen con ellos como lo harían con un conjunto de datos real. Esto ahorra tiempo y sobrecarga administrativa al proporcionar estas jaulas.

23.4.9. Clonación de Bloques

Clonación de bloques lleva la escritura en copia (copy-on-write) a copias de archivos individuales. Cuando está habilitada, copiar un archivo con cp(1) no duplica los datos del archivo. En su lugar, el nuevo archivo hace referencia a los mismos bloques que el original, y ZFS escribe nuevos bloques solo cuando cualquiera de los archivos cambia posteriormente. cp(1) realiza copias con copy_file_range(2), que ZFS convierte en operaciones de clonación de bloques, haciendo que las copias dentro de un grupo sean casi instantáneas y no consuman espacio adicional al principio.

A diferencia de deduplicación, la clonación de bloques no mantiene una tabla de comprobaciones que consuma memoria. El intercambio ocurre solo en el momento de la copia, y escribir datos idénticos en operaciones separadas aún los almacena dos veces. A diferencia de clones, la clonación de bloques no requiere una instantánea, funciona en archivos individuales en lugar de conjuntos de datos completos y no deja una relación de origin detrás.

La clonación de bloques requiere la característica de grupo block_cloning de OpenZFS 2.2, incluida por primera vez en FreeBSD 14.0 (ver zpool-features(7)). El sysctl(8) vfs.zfs.bclone_enabled controla si ZFS realmente crea clones de bloques. Por defecto es 0 en FreeBSD 14.x y 1 en FreeBSD 15.0. Mientras el sysctl sea 0, copy_file_range() recurre a una copia ordinaria. Para habilitar la clonación de bloques en FreeBSD 14.x:

# sysctl vfs.zfs.bclone_enabled=1
vfs.zfs.bclone_enabled: 0 -> 1

Para mantener la configuración tras reinicios, añada esta línea a /etc/sysctl.conf:

vfs.zfs.bclone_enabled=1

Las propiedades de grupo bcloneused, bclonesaved y bcloneratio muestran el espacio utilizado por bloques clonados, el espacio ahorrado por la clonación y la proporción de ahorro resultante:

# cp /var/tmp/database.dump /var/tmp/database.copy
# zpool list -o name,bcloneused,bclonesaved,bcloneratio mypool
NAME    BCLONE_USED  BCLONE_SAVED  BCLONE_RATIO
mypool         1.7G          1.7G         2.00x

23.4.10. Replicación

Mantener los datos en un solo grupo en una sola ubicación los expone a riesgos como robo y desastres naturales o humanos. Hacer copias de seguridad regulares de todo el grupo es vital. ZFS proporciona una función de serialización integrada que puede enviar una representación de flujo de los datos a la salida estándar. Usando esta función, es posible almacenar estos datos en otro grupo conectado al sistema local, así como enviarlos a través de una red a otro sistema. Las instantáneas son la base para esta replicación (ver la sección sobre Instantáneas de ZFS). Los comandos utilizados para replicar datos son zfs send y zfs receive.

Estos ejemplos muestran la replicación de ZFS con estos dos grupos:

# zpool list
NAME    SIZE  ALLOC   FREE   CKPOINT  EXPANDSZ   FRAG   CAP  DEDUP  HEALTH  ALTROOT
backup  960M    77K   896M         -         -     0%    0%  1.00x  ONLINE  -
mypool  984M  43.7M   940M         -         -     0%    4%  1.00x  ONLINE  -

El grupo llamado mypool es el grupo principal donde se escriben y leen datos de forma regular. Se utiliza un segundo grupo de reserva backup en caso de que el grupo principal no esté disponible. Tenga en cuenta que esta conmutación por error no la hace ZFS automáticamente, sino que debe ser realizada manualmente por un administrador del sistema cuando sea necesario. Use una instantánea para proporcionar una versión consistente del sistema de archivos para replicar. Después de crear una instantánea de mypool, cópiela al grupo backup replicando instantáneas. Esto no incluye los cambios realizados desde la instantánea más reciente.

# zfs snapshot mypool@backup1
# zfs list -t snapshot
NAME                    USED  AVAIL  REFER  MOUNTPOINT
mypool@backup1             0      -  43.6M  -

Ahora que existe una instantánea, use zfs send para crear un flujo que represente el contenido de la instantánea. Almacene este flujo como un archivo o recíbalo en otro grupo. Escribir el flujo a la salida estándar, pero redirigir a un archivo o tubería o aparecerá un error:

# zfs send mypool@backup1
Error: Stream can not be written to a terminal.
You must redirect standard output.

Para hacer una copia de seguridad de un conjunto de datos con zfs send, redirija a un archivo ubicado en el grupo de respaldo montado. Asegúrese de que el grupo tenga suficiente espacio libre para acomodar el tamaño de la instantánea enviada, lo que significa los datos contenidos en la instantánea, no los cambios desde la instantánea anterior.

# zfs send mypool@backup1 > /backup/backup1
# zpool list
NAME    SIZE  ALLOC   FREE   CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
backup  960M  63.7M   896M         -         -     0%     6%  1.00x  ONLINE  -
mypool  984M  43.7M   940M         -         -     0%     4%  1.00x  ONLINE  -

El zfs send transfirió todos los datos en la instantánea llamada backup1 al grupo llamado backup. Para crear y enviar estas instantáneas automáticamente, use un trabajo de cron(8).

En lugar de almacenar las copias de seguridad como archivos comprimidos, ZFS puede recibirlas como un sistema de archivos en vivo, permitiendo el acceso directo a los datos respaldados. Para llegar a los datos reales contenidos en esos flujos, use zfs receive para transformar los flujos de nuevo en archivos y directorios. El ejemplo siguiente combina zfs send y zfs receive usando una tubería para copiar los datos de un grupo a otro. Use los datos directamente en el grupo receptor una vez que la transferencia se complete. Solo es posible replicar un conjunto de datos a un conjunto de datos vacío.

# zfs snapshot mypool@replica1
# zfs send -v mypool@replica1 | zfs receive backup/mypool
full send of mypool@replica1 estimated size is 50.1M
total estimated size is 50.1M
TIME        SENT   SNAPSHOT mypool@replica1
10:22:01   9.75M   mypool@replica1
10:22:02   25.4M   mypool@replica1

# zpool list
NAME    SIZE  ALLOC   FREE   CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
backup  960M  63.7M   896M         -         -     0%     6%  1.00x  ONLINE  -
mypool  984M  43.7M   940M         -         -     0%     4%  极x  ONLINE  -

23.4.10.1. Copias de Seguridad Incrementales

zfs send también puede determinar la diferencia entre dos instantáneas y enviar diferencias individuales entre las dos. Esto ahorra espacio en disco y tiempo de transferencia. Por ejemplo:

# zfs snapshot mypool@replica2
# zfs list -t snapshot
NAME                    USED  AVAIL  REFER  MOUNTPOINT
mypool@replica1         5.72M      -  43.6M  -
mypool@replica2             0      -  44.1M  -
# zpool list
NAME    SIZE  ALLOC   FREE   CKPOINT  EXPANDSZ   FRAG   CAP  DEDUP  HEALTH  ALTROOT
backup  960M  61.7M   898M         -         -     0%    6%  1.00x  ONLINE  -
mypool  960M  50.2M   910M         -         -     0%    5%  1.00x  ONLINE  -

Cree una segunda instantánea llamada replica2. Esta segunda instantánea contiene cambios realizados en el sistema de archivos entre ahora y la instantánea anterior, replica1. Usando zfs send -i e indicando el par de instantáneas se genera un flujo de réplica incremental que contiene los datos cambiados. Esto tiene éxito si la instantánea inicial ya existe en el lado receptor.

# zfs send -v -i mypool@replica1 mypool@replica2 | zfs receive backup/mypool
send from @replica1 to mypool@replica2 estimated size is 5.02M
total estimated size is 5.02M
TIME        SENT   SNAPSHOT mypool@replica2

# zpool list
NAME    SIZE  ALLOC   FREE   CKPOINT  EXPANDSZ   FRAG  CAP  DEDUP  HEALTH  ALTROOT
backup  极M  80.8M   879M         -         -     0%   8%  1.00x  ONLINE  -
mypool  960M  50.2M   910M         -         -     0%   5%  1.00x  ONLINE  -

# zfs list
NAME                         USED  AVAIL  REFER  MOUNTPOINT
backup                      55.4M   240G   152K  /backup
backup/mypool               55.3M   240G  55.2M  /极/mypool
mypool                      55.6M  11.6G  55.0M  /mypool

# zfs list -t snapshot
NAME                                         USED  AVAIL  REFER  MOUNTPOINT
backup/mypool@replica1                       104K      -  50.2M  -
backup/mypool@replica2                          0      -  55.2M  -
mypool@replica1                             29.9K      -  50.0M  -
mypool@replica2                                 0      -  55.0M  -

El flujo incremental replicó los datos cambiados en lugar de la totalidad de replica1. Enviar solo las diferencias tomó mucho menos tiempo para transferir y ahorró espacio en disco al no copiar todo el grupo cada vez. Esto es útil cuando se replica a través de una red lenta o una que cobra por byte transferido.

Un nuevo sistema de archivos, backup/mypool, está disponible con los archivos y datos del grupo mypool. Especificar -p copia las propiedades del conjunto de datos incluyendo configuraciones de compresión, cuotas y puntos de montaje. Especificar -R copia todos los conjuntos de datos hijos del conjunto de datos junto con sus propiedades. Automatice el envío y recepción para crear copias de seguridad regulares en el segundo grupo. La sección Opciones de Flujo de Envío describe estas y otras opciones útiles con más detalle.

23.4.10.2. Opciones de Flujo de Envío

zfs send proporciona opciones que controlan lo que incluye un flujo y qué tan compacto es. Especificar -p incluye las propiedades del conjunto de datos, como configuraciones de compresión, cuotas y puntos de montaje, en el flujo. Especificar -R genera un paquete de flujo de replicación, que incluye el conjunto de datos, todos los conjuntos de datos hijos, instantáneas, clones y propiedades hasta la instantánea nombrada, e implica -p. El ejemplo en Enviando Copias de Seguridad Encriptadas sobre SSH usa -R para replicar un árbol completo de conjuntos de datos. Especificar -v imprime información sobre el flujo generado, incluyendo un informe de progreso por segundo.

Otras opciones cambian el formato de los bloques de datos en el flujo:

  • -L permite bloques más grandes de 128 KB en el flujo, preservando el tamaño de bloque en disco de conjuntos de datos con un recordsize superior a 128 KB en lugar de dividir esos bloques.

  • -e genera un flujo más compacto usando registros WRITE_EMBEDDED para bloques minúsculos que la característica de grupo embedded_data almacena directamente en el puntero de bloque.

  • -c envía bloques que están comprimidos en disco en su forma comprimida en lugar de descomprimirlos primero, ahorrando tiempo de CPU en ambos sistemas y reduciendo la cantidad de datos transferidos para conjuntos de datos comprimidos.

  • -w envía un conjunto de datos encriptado en forma cruda, exactamente como se almacena en disco y sin cargar su clave de encriptación, como se describe en Enviando Conjuntos de Datos Encriptados. Para conjuntos de datos no encriptados, -w es equivalente a -Lec.

Combinar estas opciones como zfs send -Lec es un buen valor predeterminado en grupos modernos. El grupo receptor debe admitir cada característica que el flujo use, y zfs receive rechaza un flujo que requiere una característica que al grupo le falta. Vea zfs-send(8) y zpool-features(7) para la lista completa de opciones y las características de grupo de las que dependen.

23.4.10.3. Transferencias Reanudables

Una conexión de red interrumpida o un reinicio durante una transferencia grande normalmente significa comenzar de nuevo desde el principio. Usar zfs receive -s mantiene el estado parcialmente recibido en el conjunto de datos receptor en lugar de eliminarlo cuando el flujo termina prematuramente.

# zfs send -v mypool@replica1 | zfs receive -极 backup/mypool
full send of mypool@replica1 estimated size is 50.1M
total estimated size is 50.1M
TIME        SENT   SNAPSHOT mypool@replica1
10:31:01   9.75M   mypool@replica1
^C

Después de la interrupción, el conjunto de datos receptor almacena un token de reanudación opaco en su propiedad receive_resume_token. El token registra qué instantánea contenía el flujo interrumpido y cuánto de él llegó. Pasar el token a zfs send -t genera un nuevo flujo que continúa donde se detuvo la transferencia:

# zfs get -H -o value receive_resume_token backup/mypool
1-1211c4f4a-f8-789c636064000310a501c49c50360710a715e5e7a69766a63040c1eabb735735ce8f8d5420c0e5c9e8d4d3d28a5388e4d3d200
# zfs send -t $(zfs get -H -o value receive_resume_token backup/mypool) | zfs receive -s backup/mypool

La transferencia reanudada se completa normalmente y elimina el estado parcial guardado. Hasta que se reanude o abandone, el estado parcial consume espacio en el grupo receptor y bloquea otras recepciones en el mismo conjunto de datos. Para abandonar una transferencia interrumpida en lugar de reanudarla, use zfs receive -A para eliminar el estado parcial guardado:

# zfs receive -A backup/mypool

23.4.10.4. Enviando Copias de Seguridad Encriptadas sobre SSH

Enviar flujos a través de la red es una buena manera de mantener una copia de seguridad remota, pero tiene un inconveniente. Los datos enviados a través del enlace de red no están encriptados, permitiendo que cualquiera intercepte y transforme los flujos de nuevo en datos sin el conocimiento del usuario que envía. Esto es indeseable cuando se envían los flujos a través de internet a un host remoto. Use SSH para encriptar de forma segura los datos enviados a través de una conexión de red. Dado que ZFS requiere redirigir el flujo desde la salida estándar, canalizarlo a través de SSH es fácil. Para mantener el contenido del sistema de archivos encriptado también en el sistema remoto, use encriptación nativa y envíe el conjunto de datos como un flujo crudo, como se describe en Enviando Conjuntos de Datos Encriptados.

Cambie algunas configuraciones y tome precauciones de seguridad primero. Esto describe los pasos necesarios requeridos para la operación zfs send; para más información sobre SSH, vea OpenSSH.

Cambie la configuración como sigue:

  • Acceso SSH sin contraseña entre el host de envío y recepción usando claves SSH

  • ZFS requiere los privilegios del usuario root para enviar y recibir flujos. Esto requiere iniciar sesión en el sistema receptor como root.

  • Razones de seguridad impiden que root inicie sesión por defecto.

  • Use el sistema de Delegación de ZFS para permitir que un usuario no root en cada sistema realice las respectivas operaciones de envío y recepción. En el sistema de envío:

# zfs allow -u someuser send,snapshot mypool
  • Para montar el grupo, el usuario no privilegiado debe ser el propietario del directorio, y los usuarios regulares necesitan permiso para montar sistemas de archivos.

En el sistema receptor:

# sysctl vfs.usermount=1
vfs.usermount: 0 -> 1
# echo vfs.usermount=1 >> /etc/sysctl.conf
# zfs create recvpool/backup
# zfs allow -u someuser create,mount,receive recvpool/backup
# chown someuser /recvpool/backup

El usuario no privilegiado puede recibir y montar conjuntos de datos ahora, y replica el conjunto de datos home al sistema remoto:

% zfs snapshot -r mypool/home@monday
% zfs send -R mypool/home@monday | ssh someuser@backuphost zfs recv -dvu recvpool/backup

Cree una instantánea recursiva llamada monday del conjunto de datos del sistema de archivos home en el grupo mypool. Luego zfs send -R incluye el conjunto de datos, todos los conjuntos de datos hijos, instantáneas, clones y configuraciones en el flujo. Canalice la salida a través de SSH al zfs receive esperando en el host remoto backuphost. Usar una dirección IP o un nombre de dominio completamente calificado es una buena práctica. La máquina receptora escribe los datos en el conjunto de datos backup en el grupo recvpool. Añadir -d a zfs recv descarta el primer elemento de la ruta de la instantánea enviada, normalmente el nombre del grupo, e injerta la ruta restante en el conjunto de datos receptor, creando cualquier sistema de archivos intermedio requerido. -u hace que los sistemas de archivos no se monten en el lado receptor. Usar -v muestra más detalles sobre la transferencia, incluyendo el tiempo transcurrido y la cantidad de datos transferidos.

23.4.10.5. Recepción Correctiva

Un scrub detecta datos corruptos, pero en un grupo sin suficiente redundancia no puede reparar el daño y en su lugar reporta errores permanentes. Cuando existe una copia intacta de la instantánea afectada en otro grupo, una recepción correctiva con zfs receive -c repara los bloques dañados en su lugar, usando el flujo de envío como una fuente de datos sanos. El conjunto de datos permanece donde está, sin ningún rollback o cambio de nombre.

La recepción correctiva requiere OpenZFS 2.2, incluida por primera vez en FreeBSD 14.0.

En este ejemplo, un scrub del grupo de un solo disco mypool encontró daño irrecuperable:

# zpool status -v mypool
  pool: mypool
 state: ONLINE
status: One or more devices has experienced an error resulting in data
        corruption.  Applications may be affected.
action: Restore the file in question if possible.  Otherwise restore the
        entire pool from backup.
   see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-8A
  scan: scrub repaired 0B in 00:01:22 with 1 errors on Sat Jul 11 09:14:37 2026
config:
NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          ada0      ONLINE       0     0     2

errors: Permanent errors have been detected in the following files:

        /mypool/reports/summary-2026.db

El snapshot replica2 todavía hace referencia a los bloques dañados, y el pool backup contiene una copia intacta de ese snapshot. Envíe el snapshot desde el pool de respaldo y recíbalo de forma correctiva en el snapshot correspondiente del pool dañado, luego ejecute un scrub para confirmar la reparación:

# zfs send backup/mypool@replica2 | zfs receive -c mypool@replica2
# zpool scrub -w mypool
# zpool status mypool | grep errors:
errors: No known data errors

El flujo debe contener el mismo snapshot que existe en el dataset dañado. La recepción correctiva solo repara los bloques de datos presentes en el flujo; no puede reparar los metadatos o los datos escritos después de que se tomara el snapshot. Ejecute siempre un scrub después para verificar que el pool ya no contiene datos dañados.

23.4.11. Cuotas de dataset, usuario y grupo

Utilice las cuotas de dataset para restringir la cantidad de espacio consumido por un dataset en particular. Las cuotas de referencia funcionan de manera muy similar, pero cuentan el espacio utilizado por el propio dataset, excluyendo los snapshots y los datasets hijos. De manera similar, utilice las cuotas de usuario y de grupo para evitar que los usuarios o grupos agoten todo el espacio en el pool o dataset. Las cuotas de proyecto, descritas a continuación, restringen en su lugar el espacio consumido por un árbol de directorios arbitrario.

Los siguientes ejemplos asumen que los usuarios ya existen en el sistema. Antes de añadir un usuario al sistema, asegúrese de crear primero su dataset de inicio y establecer el mountpoint en /home/bob. Luego, cree el usuario y haga que el directorio de inicio apunte a la ubicación del mountpoint del dataset. Esto establecerá correctamente los permisos de propietario y grupo sin ocultar ninguna ruta de directorio de inicio preexistente que pudiera existir.

Para aplicar una cuota de dataset de 10 GB para storage/home/bob:

# zfs set quota=10G storage/home/bob

Para aplicar una cuota de referencia de 10 GB para storage/home/bob:

# zfs set refquota=10G storage/home/bob

Para eliminar una cuota de 10 GB para storage/home/bob:

# zfs set quota=none storage/home/bob

El formato general es userquota@user=size, y el nombre del usuario debe estar en uno de estos formatos:

  • Nombre compatible con POSIX como joe.

  • ID numérico POSIX como 789.

  • Nombre SID como joe.bloggs@example.com.

  • ID numérico SID como S-1-123-456-789.

Por ejemplo, para aplicar una cuota de usuario de 50 GB para el usuario llamado joe:

# zfs set userquota@joe=50G storage/home/joe

Para eliminar cualquier cuota:

# zfs set userquota@joe=none storage/home/joe

Las propiedades de cuota de usuario no se muestran con zfs get all. Los usuarios que no son root no pueden ver las cuotas de otros a menos que se les conceda el privilegio userquota. Los usuarios con este privilegio pueden ver y establecer la cuota de todos.

El formato general para establecer una cuota de grupo es: groupquota@group=size.

Para establecer la cuota para el grupo firstgroup en 50 GB, utilice:

# zfs set groupquota@firstgroup=50G storage/home

Para eliminar la cuota del grupo firstgroup, o para asegurarse de que no haya ninguna establecida, utilice en su lugar:

# zfs set groupquota@firstgroup=none storage/home

Al igual que con la propiedad de cuota de usuario, los usuarios que no son root pueden ver las cuotas asociadas a los grupos a los que pertenecen. Un usuario con el privilegio groupquota o root puede ver y establecer todas las cuotas para todos los grupos.

Para mostrar la cantidad de espacio utilizado por cada usuario en un sistema de archivos o snapshot junto con cualquier cuota, utilice zfs userspace. Para obtener información de grupos, utilice zfs groupspace. Para obtener más información sobre las opciones soportadas o cómo mostrar opciones específicas de forma aislada, consulte zfs-userspace(8).

Los usuarios privilegiados y root pueden listar la cuota para storage/home/bob utilizando:

# zfs get quota storage/home/bob

23.4.11.1. Cuotas de proyecto

Las cuotas de dataset y de usuario no se adaptan a todas las distribuciones. Cuando varios árboles de directorios pertenecientes a diferentes proyectos comparten un único dataset, las cuotas de proyecto restringen en su lugar el espacio consumido por cada árbol. Un proyecto es un identificador numérico arbitrario etiquetado en archivos y directorios.

zfs project gestiona el ID de proyecto de archivos y directorios. Establecer la bandera de herencia de proyecto en un directorio hace que los nuevos archivos y subdirectorios creados en su interior hereden su ID de proyecto. Para asignar el ID de proyecto 42 a un árbol existente, establezca la bandera y el ID de forma recursiva:

# zfs project -s -p 42 -r /storage/proj

Aplique un límite de 100 GB a todos los archivos pertenecientes al proyecto 42 con la propiedad projectquota:

# zfs set projectquota@42=100G storage

zfs projectspace muestra el espacio consumido por cada proyecto en un dataset junto con cualquier cuota:

# zfs projectspace -o name,used,quota storage
NAME   USED  QUOTA
42    1.95G   100G

La propiedad projectobjquota limita el número de objetos que un proyecto puede poseer de la misma manera. Muestre o borre el ID de proyecto de un directorio con zfs project -d y zfs project -C. Consulte zfs-project(8) y zfsprops(7) para obtener más detalles.

23.4.12. Reservas

Las reservas garantizan una cantidad de espacio siempre disponible en un dataset. El espacio reservado no estará disponible para ningún otro dataset. Esta útil característica asegura que haya espacio libre disponible para un dataset importante o archivos de registro.

El formato general de la propiedad reservation es reservation=size, por lo que para establecer una reserva de 10 GB en storage/home/bob, utilice:

# zfs set reservation=10G storage/home/bob

Para borrar cualquier reserva:

# zfs set reservation=none storage/home/bob

El mismo principio se aplica a la propiedad refreservation para establecer una reserva de referencia, con el formato general refreservation=size.

Este comando muestra cualquier reserva o reserva de referencia que exista en storage/home/bob:

# zfs get reservation storage/home/bob
# zfs get refreservation storage/home/bob

23.4.13. Compresión

ZFS proporciona compresión transparente. Comprimir los datos escritos a nivel de bloque ahorra espacio y también aumenta el rendimiento del disco. Si los datos se comprimen en un 25%, los datos comprimidos se escriben en el disco a la misma velocidad que la versión sin comprimir, lo que resulta en una velocidad de escritura efectiva del 125%. La compresión también puede ser una gran alternativa a la deduplicación porque no requiere memoria adicional.

ZFS ofrece diferentes algoritmos de compresión, cada uno con diferentes compromisos. En OpenZFS 2.2 y versiones posteriores, los pools y datasets recién creados tienen por defecto compression=on, lo que selecciona LZ4. LZ4 comprime todo el pool sin el gran impacto en el rendimiento de otros algoritmos. La mayor ventaja de LZ4 es la característica de early abort. Si LZ4 no logra al menos un 12,5% de compresión en la parte de la cabecera de los datos, ZFS escribe el bloque sin comprimir para evitar desperdiciar ciclos de CPU intentando comprimir datos que ya están comprimidos o que son incompresibles. Cambiar la propiedad compression afecta solo a las nuevas escrituras; los datos existentes mantienen su antigua codificación hasta que se reescriben (consulte Reescritura de datos existentes). Para obtener detalles sobre los diferentes algoritmos de compresión disponibles en ZFS, consulte la entrada Compresión en la sección de terminología.

El administrador puede ver la efectividad de la compresión utilizando las propiedades del dataset.

# zfs get used,compressratio,compression,logicalused mypool/compressed_dataset
NAME                       PROPERTY       VALUE  SOURCE
mypool/compressed_dataset  used           449G   -
mypool/compressed_dataset  compressratio  1.11x  -
mypool/compressed_dataset  compression    lz4    local
mypool/compressed_dataset  logicalused    496G   -

El dataset está utilizando 449 GB de espacio (la propiedad used). Sin compresión, habría ocupado 496 GB de espacio (la propiedad logicalused). Esto da como resultado una tasa de compresión de 1.11:1.

La compresión puede tener un efecto secundario inesperado cuando se combina con las cuotas de usuario. Las cuotas de usuario restringen la cantidad de espacio real que un usuario consume en un dataset después de la compresión. Si un usuario tiene una cuota de 10 GB y escribe 10 GB de datos compresibles, todavía podrá almacenar más datos. Si más tarde actualiza un archivo, por ejemplo una base de datos, con datos más o menos compresibles, la cantidad de espacio disponible para él cambiará. Esto puede resultar en la extraña situación en la que un usuario no aumentó la cantidad real de datos (la propiedad logicalused), pero el cambio en la compresión hizo que alcanzara su límite de cuota.

La compresión puede tener una interacción inesperada similar con las copias de seguridad. Las cuotas se utilizan a menudo para limitar el almacenamiento de datos y asegurar que haya suficiente espacio de copia de seguridad disponible. Dado que las cuotas no consideran la compresión, ZFS puede escribir más datos de los que cabrían en copias de seguridad sin comprimir.

23.4.14. Compresión Zstandard

OpenZFS 2.0 añadió el algoritmo de compresión Zstandard (Zstd). Zstd ofrece tasas de compresión más altas que el LZ4 predeterminado, al tiempo que ofrece velocidades mucho mayores que la alternativa, gzip.

Zstd proporciona una gran selección de niveles de compresión, ofreciendo un control detallado sobre el rendimiento frente a la tasa de compresión. Una de las principales ventajas de Zstd es que la velocidad de descompresión es independiente del nivel de compresión. Para los datos que se escriben una vez pero se leen a menudo, Zstd permite el uso de los niveles de compresión más altos sin penalización en el rendimiento de lectura.

Incluso con actualizaciones frecuentes de datos, habilitar la compresión a menudo proporciona un mayor rendimiento. Una de las mayores ventajas proviene de la característica ARC comprimida. La Adaptive Replacement Cache (ARC) de ZFS almacena en caché la versión comprimida de los datos en la RAM, descomprimiéndola cada vez. Esto permite que la misma cantidad de RAM almacene más datos y metadatos, aumentando la tasa de aciertos de la caché.

ZFS ofrece 19 niveles de compresión Zstd, cada uno ofreciendo incrementalmente más ahorro de espacio a cambio de una compresión más lenta. El nivel predeterminado es zstd-3 y ofrece una mayor compresión que LZ4 sin ser mucho más lento. Los niveles superiores a 10 requieren grandes cantidades de memoria para comprimir cada bloque y los sistemas con menos de 16 GB de RAM no deberían utilizarlos. ZFS también utiliza una selección de los niveles fast de Zstd, que se vuelven correspondientemente más rápidos pero soportan tasas de compresión más bajas. ZFS soporta desde zstd-fast-1 hasta zstd-fast-10, desde zstd-fast-20 hasta zstd-fast-100 en incrementos de 10, y zstd-fast-500 y zstd-fast-1000 que proporcionan una compresión mínima, pero ofrecen un alto rendimiento.

Si ZFS no puede obtener la memoria requerida para comprimir un bloque con Zstd, recurrirá a almacenar el bloque sin comprimir. Es poco probable que esto suceda excepto en los niveles más altos de Zstd en sistemas con memoria limitada. ZFS cuenta con qué frecuencia ha ocurrido esto desde que se cargó el módulo ZFS con kstat.zfs.misc.zstd.compress_alloc_fail.

23.4.15. Reescritura de datos existentes

zfs rewrite requiere OpenZFS 2.4, incluido por primera vez en FreeBSD 15.0.

Propiedades como compression, checksum, dedup y copies afectan únicamente a los datos recién escritos. Cambiarlas deja los bloques existentes almacenados tal como estaban, y aplicar los nuevos valores tradicionalmente requería un ciclo de envío/recepción (send/receive) o copiar cada archivo de un lado a otro. En su lugar, zfs rewrite reescribe los bloques de los archivos existentes en su lugar, como si se leyeran y escribieran de nuevo atómicamente, de modo que los valores actuales de las propiedades surten efecto sin esas soluciones alternativas.

El comando opera sobre archivos y directorios en lugar de nombres de dataset. Para aplicar un algoritmo de compresión recién elegido a todo un dataset, hágalo de forma recursiva desde su punto de montaje:

# zfs set compression=zstd mypool/archive
# zfs rewrite -r /mypool/archive

Añadir -v imprime el nombre de cada archivo reescrito. -x evita que la recursión cruce los puntos de montaje hacia los datasets hijos, y -o y -l restringen la reescritura a un rango de bytes dentro de un archivo. Los cambios de propiedades que alterarían el tamaño del bloque lógico, como recordsize, no tienen efecto en los archivos reescritos.

Los bloques reescritos son bloques nuevos: los snapshots tomados antes de la reescritura siguen haciendo referencia a las copias antiguas, por lo que el uso del espacio puede crecer hasta que esos snapshots se destruyan. zfs rewrite no funciona a través de snapshots por la misma razón. Consulte zfs-rewrite(8) para obtener más detalles.

23.4.16. Deduplicación

Cuando está habilitada, la deduplicación utiliza el checksum de cada bloque para detectar bloques duplicados. Cuando un nuevo bloque es un duplicado de un bloque existente, ZFS escribe una nueva referencia a los datos existentes en lugar de todo el bloque duplicado. Son posibles enormes ahorros de espacio si los datos contienen muchos archivos duplicados o información repetida. Advertencia: la deduplicación requiere una gran cantidad de memoria, y habilitar la compresión en su lugar proporciona la mayor parte del ahorro de espacio sin el coste adicional.

dedup es una propiedad del dataset, no una propiedad del pool. Para activar la deduplicación, establézcala en un dataset:

# zfs set dedup=on pool

Este ejemplo establece la propiedad en el dataset raíz del pool pool, por lo que cada dataset en el pool la hereda. Limitar la deduplicación a los datasets que realmente almacenan datos con muchos duplicados mantiene la tabla de deduplicación más pequeña.

La deduplicación solo afecta a los nuevos datos escritos en el dataset. El mero hecho de activar esta opción no deduplicará los datos ya escritos. En FreeBSD 15.0, zfs rewrite puede reescribir los datos existentes para que pasen por la deduplicación. Un pool con una propiedad de deduplicación recién activada se verá como en este ejemplo:

# zpool list
NAME  SIZE ALLOC  FREE   CKPOINT  EXPANDSZ   FRAG   CAP   DEDUP   HEALTH   ALTROOT
pool 2.84G 2.19M 2.83G         -         -     0%    0%   1.00x   ONLINE   -

La columna DEDUP muestra la tasa real de deduplicación para el pool. Un valor de 1.00x muestra que los datos aún no se han deduplicado. El siguiente ejemplo copia algunos binarios del sistema tres veces en diferentes directorios en el pool deduplicado creado anteriormente.

# for d in dir1 dir2 dir3; do
> mkdir $d && cp -R /usr/bin $d &
> done

Para observar la deduplicación de datos redundantes, utilice:

# zpool list
NAME SIZE  ALLOC  FREE   CKPOINT  EXPANDSZ   FRAG  CAP   DEDUP   HEALTH   ALTROOT
pool 2.84G 20.9M 2.82G         -         -     0%   0%   3.00x   ONLINE   -

La columna DEDUP muestra un factor de 3.00x. Detectar y deduplicar copias de los datos utiliza un tercio del espacio. El potencial de ahorro de espacio puede ser enorme, pero tiene el coste de tener suficiente memoria para realizar un seguimiento de los bloques deduplicados. ZFS almacena una entrada para cada bloque deduplicado en la tabla de deduplicación (DDT). Una regla general es de 5 a 6 GB de RAM por cada 1 TB de datos deduplicados. Cuando la tabla ya no cabe en la memoria, cada escritura fuerza lecturas de las entradas de la tabla desde el disco, y el rendimiento se degrada drásticamente.

La deduplicación no siempre es beneficiosa cuando los datos en un pool no son redundantes. ZFS puede mostrar el ahorro de espacio potencial simulando la deduplicación en un pool existente:

# zdb -S pool
Simulated DDT histogram:
bucket              allocated                       referenced
______   ______________________________   ______________________________
refcnt   blocks   LSIZE   PSIZE   DSIZE   blocks   LSIZE   PSIZE   DSIZE
------   ------   -----   -----   -----   ------   -----   -----   -----
     1    2.58M    289G    264G    264G    2.58M    289G    264G    264G
     2     206K   12.6G   10.4G   10.4G     430K   26.4G   21.6G   21.6G
     4    37.6K    692M    276M    276M     170K   3.04G   1.26G   1.26G
     8    2.18K   45.2M   19.4M   19.4M    20.0K    425M    176M    176M
    16      174   2.83M   1.20M   1.20M    3.33K   48.4M   20.4M   20.4M
    32       40   2.17M    222K    222K    1.70K   97.2M   9.91M   9.91M
    64        9     56K   10.5K   10.5K      865   4.96M    948K    948K
   128        2   9.50K      2K      2K      419   2.11M    438K    438K
   256        5   61.5K     12K     12K    1.90K   23.0M   4.47M   4.47M
    1K        2      1K      1K      1K    2.98K   1.49M   1.49M   1.49M
 Total    2.82M    303G    275G    275G    3.20M    319G    287G    287G

dedup = 1.05, compress = 1.11, copies = 1.00, dedup * compress / copies = 1.16

Una vez que zdb -S termina de analizar el pool, muestra la tasa de reducción de espacio que se lograría al activar la deduplicación. En este caso, 1.16 es una tasa de ahorro de espacio deficiente proporcionada principalmente por la compresión. Activar la deduplicación en este pool no ahorraría ninguna cantidad de espacio, y no compensa la cantidad de memoria requerida para habilitar la deduplicación. Utilizando la fórmula ratio = dedup * compress / copies, los administradores de sistemas pueden planificar la asignación de almacenamiento, decidiendo si la carga de trabajo contendrá suficientes bloques duplicados para justificar los requisitos de memoria. Si los datos son razonablemente compresibles, el ahorro de espacio puede ser bueno.

Fast dedup, una implementación rediseñada que reduce estos costes, requiere OpenZFS 2.3 o posterior, disponible por primera vez en FreeBSD 15.0. Fast dedup agrupa las actualizaciones de la tabla de deduplicación en un registro en disco y las vuelca a la tabla en segundo plano, reduciendo la E/S aleatoria que hacía lenta a la deduplicación clásica. La propiedad del pool dedup_table_quota establece un límite en el tamaño en disco de la tabla; ZFS deja de añadir nuevas entradas una vez que el pool alcanza el límite, y con el valor predeterminado de auto el tamaño de un vdev de dedup dedicado sirve como cuota. La propiedad de solo lectura del pool dedup_table_size informa del tamaño actual de la tabla. zpool ddtprune -p 30 pool elimina el 30% más antiguo de las entradas de la tabla que no proporcionan ningún ahorro porque solo un único bloque hace referencia a ellas; -d days en su lugar poda las entradas de referencia única más antiguas que el número de días indicado. zpool status -DD pool muestra las estadísticas de la tabla de deduplicación, incluyendo un histograma de bloques por recuento de referencias. Almacenar la tabla en un dedup vdev dedicado compuesto por dispositivos rápidos mantiene las búsquedas rápidas incluso cuando la tabla supera la memoria RAM.

Una buena práctica es habilitar primero la compresión, ya que la compresión también proporciona un rendimiento mucho mayor. Habilite la deduplicación en los casos en que los ahorros sean considerables y con suficiente memoria disponible para la DDT.

23.4.17. ZFS y Jails

Utilice zfs jail y la propiedad jailed correspondiente para delegar un dataset de ZFS a una Jail. zfs jail jailid adjunta un dataset a la jail especificada, y zfs unjail lo desvincula. Para controlar el dataset desde dentro de una jail, establezca la propiedad jailed. ZFS prohíbe montar un dataset enjaulado en el host porque puede tener puntos de montaje que comprometerían la seguridad del host.

Un dataset delegado cede el control de todo un subárbol al administrador de la jail, quien puede montarlo, crear datasets hijos, tomar snapshots y cambiar propiedades, todo ello confinado a ese subárbol. Para que esto funcione, la jail necesita tener habilitados los parámetros allow.mount y allow.mount.zfs y el parámetro enforce_statfs establecido en un valor inferior a 2. Consulte jail(8) para obtener detalles sobre estos parámetros.

Este ejemplo crea un dataset, lo marca como enjaulado y lo adjunta a la jail en ejecución myjail:

# zfs create mypool/jaildata
# zfs set jailed=on mypool/jaildata
# zfs jail myjail mypool/jaildata

El dataset aparece entonces en zfs list dentro de la jail y es administrable allí. zfs unjail myjail mypool/jaildata devuelve el control al host. Consulte zfs-jail(8) para obtener más información.

A partir de FreeBSD 15.0, jail(8) automatiza la vinculación. Enumere los datasets a delegar en el parámetro de jail zfs.dataset, y jail(8) los adjuntará cuando se inicie la jail. Los datasets ya deben tener establecido jailed=on, y el parámetro requiere allow.mount.zfs. Una entrada en /etc/jail.conf que lo utilice se ve así:

myjail {
    path = "/usr/local/jails/myjail";
    host.hostname = "myjail.example.org";
    exec.start = "/bin/sh /etc/rc";
    exec.stop = "/bin/sh /etc/rc.shutdown";
    allow.mount;
    allow.mount.zfs;
    enforce_statfs = 1;
    zfs.dataset = "mypool/jaildata";
}

Establecer el parámetro de jail zfs.mount_snapshot en 1 permite adicionalmente a los usuarios dentro de la jail acceder al contenido de los snapshots de ZFS bajo el directorio .zfs de los sistemas de archivos delegados.

23.5. Administración delegada

Un sistema integral de delegación de permisos permite a los usuarios sin privilegios realizar funciones de administración de ZFS. Por ejemplo, si el directorio de inicio de cada usuario es un dataset, los usuarios necesitan permiso para crear y destruir snapshots de sus directorios de inicio. Un usuario que realiza copias de seguridad puede obtener permiso para utilizar las funciones de replicación. ZFS permite que un script de estadísticas de uso se ejecute con acceso únicamente a los datos de uso de espacio para todos los usuarios. También es posible delegar la capacidad de delegar permisos. La delegación de permisos es posible para cada subcomando y para la mayoría de las propiedades.

23.5.1. Delegación de la creación de datasets

zfs allow someuser create mydataset otorga al usuario especificado permiso para crear datasets hijos bajo el dataset padre seleccionado. Una advertencia: crear un nuevo dataset implica montarlo. Eso requiere establecer el sysctl(8) vfs.usermount de FreeBSD en 1 para permitir que los usuarios que no son root monten un sistema de archivos. Otra restricción destinada a prevenir abusos: los usuarios que no son root deben ser los propietarios del punto de montaje donde se montará el sistema de archivos.

23.5.2. Delegación de la delegación de permisos

zfs allow someuser allow mydataset otorga al usuario especificado la capacidad de asignar cualquier permiso que tenga sobre el dataset de destino, o sus hijos, a otros usuarios. Si un usuario tiene el permiso snapshot y el permiso allow, ese usuario puede entonces conceder el permiso snapshot a otros usuarios.

23.6. Cifrado nativo de ZFS

ZFS soporta el cifrado nativo de datasets y de los datos almacenados en ellos. Esto no siempre fue así, ya que las soluciones anteriores dependían del cifrado basado en GELI de FreeBSD. Aunque este enfoque es seguro, no era tan fácilmente portable a sistemas que no fueran FreeBSD y que carecieran de soporte para GELI. Con el cifrado nativo de ZFS, los datasets cifrados se pueden utilizar en otros sistemas que soporten esta característica del pool sin depender de componentes de terceros o del cifrado nativo del sistema operativo.

Otro beneficio del cifrado nativo de ZFS es que los datasets no necesitan ser descifrados para tareas administrativas como snapshots, replicación u operaciones de scrub. Las comprobaciones de integridad de datos de ZFS funcionan igual de bien con datasets cifrados de forma nativa, y la compresión también funciona en datasets cifrados.

Diferentes datasets en el mismo pool pueden utilizar claves separadas de forma independiente. Considere un servidor de archivos central donde diferentes usuarios almacenan sus datos en datasets de inicio cifrados. El Usuario A tiene una clave diferente a la del Usuario B. Ambos usuarios pueden trabajar codo con codo y elegir descifrar sus datasets según sea necesario sin conocer las claves de descifrado del otro. El método de descifrado también puede diferir completamente entre usuarios sin afectarse mutuamente. Esto permite que los datos sensibles de diferentes usuarios se almacenen en el mismo pool mientras permanecen protegidos por claves separadas.

Antes de utilizar el cifrado nativo de ZFS, tenga en cuenta lo siguiente:

  • El cifrado se aplica a nivel de dataset, no a nivel de pool.

  • El boot desde datasets de ZFS cifrados aún no está soportado en el cargador de FreeBSD.

  • El cifrado solo se puede habilitar cuando se crea un dataset, no después.

  • El cifrado de bloques, la longitud de la clave y el modo de cifrado no se pueden cambiar una vez que se han establecido.

  • ZFS no cifra los metadatos.

El último punto puede parecer un inconveniente en comparación con el cifrado de disco completo. Sin embargo, proporciona una mayor flexibilidad al permitir que diferentes claves protejan los datasets dentro del mismo pool en lugar de requerir una única clave o frase de contraseña para desbloquear todo el pool. Específicamente, ZFS cifra lo siguiente:

  • datos de archivos y zvol,

  • atributos de archivos,

  • ACLs,

  • bits de permisos,

  • listados de directorios,

  • mapeos FUID,

  • datos userused/groupused, y

  • datos deduplicados

Algunos metadatos e información de ZFS permanecen sin cifrar, incluyendo lo siguiente:

  • estructura y nombre del pool,

  • nombres de datasets y snapshots,

  • jerarquía de datasets,

  • propiedades,

  • tamaño de archivo,

  • huecos de archivo, y

  • tablas de deduplicación

Estos metadatos sin cifrar permiten a ZFS realizar operaciones de mantenimiento rutinarias, como zpool scrub, sin descifrar primero los datos. Como resultado, ZFS puede detectar y reparar datos cifrados corruptos sin acceder al contenido de los archivos sin cifrar.

Para cifrar datos existentes sin cifrar, cópielos a un dataset con el cifrado habilitado. Esto permite que los datos se migren a una ubicación segura dentro del pool, siempre que se proporcione la frase de contraseña para autorizar el acceso. Normalmente, esto se hace cargando la clave de cifrado en la memoria después de confirmar el conocimiento de un secreto, como una frase de contraseña. Una vez que la clave se ha cargado, el contenido del dataset se vuelve accesible para lectura y escritura. Para volver a asegurar el dataset, descargue la clave de la memoria. ZFS entonces hace que el dataset sea inaccesible hasta que la clave se cargue de nuevo.

Cuando el cifrado está habilitado, algunas operaciones de ZFS se comportan de manera diferente. ZFS aplica la compresión antes del cifrado para preservar las tasas de compresión. Mientras que ZFS normalmente utiliza sumas de comprobación de 256 bits, el cifrado las reemplaza con una suma de comprobación de 128 bits y un Código de Autenticación de Mensajes (MAC) de 128 bits proporcionado por la suite de cifrado. Esto proporciona protección adicional contra la modificación maliciosa de datos.

Cuando la deduplicación se utiliza junto con el cifrado, ZFS realiza la deduplicación solo dentro del dataset cifrado, sus snapshots y sus clones. Esto evita que se filtre información entre datasets cifrados. La contrapartida es una menor eficiencia de deduplicación porque ZFS no puede comparar sumas de comprobación en todo el pool. Aun así, la deduplicación combinada con el cifrado sigue revelando qué bloques son idénticos e incurre en una sobrecarga de CPU adicional por cada bloque escrito.

Se aplican otras limitaciones al utilizar el cifrado de ZFS. La característica embedded_data no se puede utilizar con el cifrado. Los datasets con el cifrado habilitado tampoco pueden tener la propiedad copies establecida en 3, porque la implementación almacena metadatos cifrados en la ubicación donde normalmente residiría la tercera copia.

23.6.1. Creación de un dataset cifrado

El cifrado de ZFS se habilita estableciendo la propiedad encryption=on al crear un dataset. Establecer esta propiedad fuera de un comando zfs create no habilita el cifrado de forma retroactiva, ya que solo tiene efecto durante la creación del dataset. En el siguiente ejemplo, se utiliza una frase de contraseña al montar el dataset cifrado después de haber sido creado.

# zfs create -o encryption=on -o keyformat=passphrase -o keylocation=prompt zroot/secretdata
Enter passphrase:
Re-enter passphrase:

Si la frase de contraseña tiene menos de ocho caracteres, ZFS la rechaza y no crea el dataset. Después de que la frase de contraseña se haya introducido correctamente dos veces, ZFS crea y monta el dataset en el pool.

Cualquier dato almacenado en el dataset cifrado permanece cifrado mientras resida allí. Copiar datos de un dataset cifrado a una ubicación sin cifrar descifra los datos durante la operación de copia. El dataset recién creado se puede montar entonces en una ubicación diferente si es necesario.

# zfs set mountpoint=/secretdata zroot/secretdata
# echo "Hello FreeBSD!" > /secretdata/message
# cat /secretdata/message
Hello FreeBSD!

Como era de esperar, los datos están actualmente disponibles para lectura y escritura por cualquiera que tenga acceso al dataset.

23.6.2. Propiedades de los datasets cifrados

Listar las propiedades de cifrado nativo de ZFS para un dataset se realiza con el siguiente comando:

# zfs get encryption,keylocation,keyformat zroot/secretdata
NAME              PROPERTY     VALUE        SOURCE
zroot/secretdata  encryption   aes-256-gcm  -
zroot/secretdata  keylocation  prompt       local
zroot/secretdata  keyformat    passphrase   -

La propiedad encryption muestra aes-256-gcm, que es actualmente el método de cifrado predeterminado utilizado por ZFS. Como indica la columna SOURCE, ni esta propiedad ni la propiedad keyformat se pueden cambiar utilizando zfs set después de que se haya creado el dataset. Consulte la sección changing the encryption key para obtener información sobre cómo modificar algunas de estas propiedades. La siguiente tabla enumera las propiedades relacionadas con el cifrado utilizadas por ZFS:

encryptionroot

El dataset del cual el dataset actual hereda su clave de cifrado. Los clones de datasets comparten la clave de cifrado de su dataset de origen.

keyformat

El formato de la clave de cifrado. Los valores posibles son: raw, hex y passphrase. Tanto las claves raw como hex deben tener 32 bytes de longitud y contener valores aleatorios.

encryption

El cifrador utilizado para el cifrado, que consiste en el cifrado de bloques, la longitud de la clave y el modo de cifrado. Tanto la propiedad encryption como keyformat deben especificarse cuando se crea el dataset. Los valores posibles para la propiedad encryption son:

  • off (predeterminado),

  • on,

  • aes-128-ccm,

  • aes-192-ccm,

  • aes-256-ccm,

  • aes-128-gcm,

  • aes-192-gcm, y

  • aes-256-gcm (estándar actual cuando se establece on).

Esta propiedad no se puede cambiar una vez que se ha establecido.

keystatus

Indica si una clave de cifrado se ha cargado correctamente. Los valores posibles son none, available y unavailable.

keylocation

Especifica la ubicación desde la cual cargar la clave de cifrado. Los valores posibles son:

pbkdf2iters

El número de iteraciones utilizadas al derivar una clave de cifrado a partir de una frase de contraseña. Esto obliga a un atacante a realizar un gran número de operaciones hash computacionalmente costosas. A medida que aumenta la potencia de cálculo, este valor también debería aumentarse desde su valor predeterminado actual de 350000.

23.6.3. Descarga de la clave de cifrado

Proteger los datos almacenados en un dataset cifrado requiere dos pasos: primero desmontar el dataset, luego descargar la clave de cifrado de la memoria. Esta distinción es importante. Un dataset desmontado no está protegido si su clave de cifrado permanece cargada en la memoria. Ejecute siempre zfs unload-key para proteger los datos. Para acceder al dataset de nuevo, cargue la clave y proporcione la frase de contraseña como se describe en la sección loading the encryption key. ZFS impide que zfs unload-key se ejecute mientras el dataset todavía está montado.

# zfs unmount zroot/secretdata
# zfs unload-key zroot/secretdata

Ejecutar zfs unload-key varias veces da como resultado un error que indica que la clave ya ha sido descargada.

23.6.4. Carga de la clave de cifrado

Antes de que un dataset cifrado pueda ser utilizado como cualquier otro dataset, su clave de cifrado debe ser cargada y se debe proporcionar la frase de contraseña. En este punto, la propiedad keystatus todavía está establecida en unavailable, y el montaje del dataset falla porque la clave aún no se ha cargado:

# zfs get keystatus zroot/secretdata
NAME              PROPERTY   VALUE        SOURCE
zroot/secretdata  keystatus  unavailable  -
# zfs mount zroot/secretdata
cannot mount 'zroot/secretdata': encryption key not loaded

Esto indica que el dataset está cifrado y requiere una clave de cifrado. Para montar el dataset, ejecute zfs load-key y proporcione la frase de contraseña cuando se le solicite:

# zfs load-key zroot/secretdata
Enter passphrase for 'zroot/secretdata':
# zfs get keystatus zroot/secretdata
NAME              PROPERTY   VALUE      SOURCE
zroot/secretdata  keystatus  available  -

A continuación, monte el dataset para hacerlo accesible a través de la jerarquía del sistema de archivos:

# zfs mount zroot/secretdata
# mount|grep secretdata
zroot/secretdata on /secretdata (zfs, local, noatime, nfsv4acls)

Para cargar múltiples claves de cifrado de forma recursiva, especifique la opción -r con zfs load-key. Si una clave ya ha sido cargada, ZFS lo informa con un mensaje de error.

# zfs load-key zroot/secretdata
Key load error: Key already loaded for 'zroot/secretdata'.

La propiedad keystatus también confirma que la clave ha sido cargada al informar el valor available. Para verificar si una frase de contraseña es correcta sin cargar la clave, utilice la opción -n para realizar una prueba en seco (dry run).

23.6.5. Cambio de la clave de cifrado

ZFS también soporta el cambio de claves de cifrado, como reemplazar una frase de contraseña. Esta operación no requiere volver a cifrar el dataset. Ejecute el siguiente comando para cambiar la frase de contraseña de cifrado:

# zfs change-key zroot/secretdata
Enter new passphrase for 'zroot/secretdata':
Re-enter new passphrase for 'zroot/secretdata':

Ejecutar zfs change-key requiere que la clave actual esté cargada. Si no lo está, ZFS sigue solicitando la nueva clave pero luego muestra una advertencia de que la clave actual no ha sido cargada.

El comando zfs change-key también puede modificar las propiedades keylocation, keyformat y pbkdf2iters especificándolas con la opción -o. Ejecutar zfs change-key en un dataset hijo cifrado lo convierte en una raíz de cifrado (encryption root) si aún no lo es. Para evitar este comportamiento y continuar heredando la clave del padre, especifique la opción -i.

Tenga en cuenta que cambiar la clave de cifrado de un dataset padre también cambia la clave para los datasets hijos que la heredan. En consecuencia, esos datasets hijos continúan utilizando la clave de cifrado del padre. Si un dataset hijo debe utilizar una clave diferente, especifique un keyformat diferente al crearlo o ejecute zfs change-key en el dataset hijo. Hacerlo crea una nueva raíz de cifrado para el hijo y rompe su herencia de cifrado del padre.

Los clones de ZFS de un dataset cifrado siempre utilizan la clave de cifrado de su dataset de origen. Como resultado, las propiedades keystatus, keyformat, keylocation y pbkdf2iters no se heredan como otras propiedades del dataset. En su lugar, utilizan los valores definidos por la raíz de cifrado. Para determinar la raíz de cifrado, utilice la propiedad de solo lectura encryptionroot.

Si un atacante compromete una clave de cifrado, cambiar la frase de contraseña con zfs change-key no protege necesariamente los datos existentes o recién escritos. Los nuevos datos continúan siendo cifrados con la misma clave maestra que los datos existentes. Si un atacante obtiene tanto una clave de usuario como su correspondiente clave maestra envuelta, ejecutar zfs change-key no sobrescribe la clave maestra anterior en el disco. Como resultado, la antigua clave maestra puede permanecer disponible para análisis forense durante un período indeterminado.

Si una clave maestra ha sido comprometida, la solución preferida es borrar de forma segura los dispositivos de almacenamiento subyacentes y crear un nuevo pool. Posteriormente, restaure los datos desde una copia de seguridad al nuevo pool. Alternativamente, cree un nuevo dataset cifrado, migre los datos utilizando zfs send y zfs receive, y luego ejecute zpool trim --secure para borrar el espacio liberado. Si el hardware subyacente no soporta TRIM seguro, utilice zpool initialize en su lugar.

23.6.6. Envío de datasets cifrados

La replicación de ZFS se basa en el envío de snapshots de datasets, que también se pueden crear a partir de datasets cifrados. Las instantáneas resultantes permanecen cifradas.

# zfs snapshot zroot/secretdata@snap1

Además de enviar copias de seguridad cifradas a través de SSH, el uso de la opción -w (raw) con zfs send transfiere los bloques de datos cifrados al pool de destino. Un envío en bruto (raw) proporciona varias ventajas:

  • el sistema receptor nunca ve los datos en texto plano.

  • el sistema receptor no requiere la frase de contraseña ya que no se realiza ningún descifrado.

  • Las copias de seguridad se pueden enviar sin cargar primero la clave de cifrado.

  • un sistema no confiable puede recibir los datos cifrados pero no puede descifrarlos ni modificarlos sin la clave de cifrado.

Para enviar la instantánea creada anteriormente como un flujo en bruto (raw) al dataset secret en el pool backup, introduzca el siguiente comando:

# zfs send -w zroot/secretdata@snap1 | zfs recv backup/secret

Sin la opción -w, zfs send transmite los datos de forma no cifrada. El sistema receptor puede entonces volver a cifrar los datos utilizando una clave diferente. Sin embargo, hacer esto impide futuros envíos incrementales en bruto a ese destino.

23.6.7. Cargar claves de cifrado en el arranque

El script zfskeys de rc(8) carga las claves de cifrado en el arranque para los datasets cifrados cuya propiedad keylocation apunta a un archivo de clave con una URL file://. El script se ejecuta después de la importación del pool y antes de montar los sistemas de archivos, por lo que los datasets manejados de esta manera se montan automáticamente durante el inicio normal de ZFS. El script no maneja datasets con keylocation=prompt; cargue sus claves manualmente con zfs load-key después de que el sistema haya arrancado.

Para cambiar el dataset creado anteriormente de una frase de contraseña a un archivo de clave, genere 32 bytes de datos aleatorios como la nueva clave, restrinja el acceso al archivo de clave y cambie la clave de cifrado del dataset:

# dd if=/dev/random of=/root/secretdata.key bs=32 count=1
# chmod 600 /root/secretdata.key
# zfs change-key -o keyformat=raw -o keylocation=file:///root/secretdata.key zroot/secretdata

Habilite el script en /etc/rc.conf:

# sysrc zfskeys_enable="YES"

Por defecto, el script carga las claves de todos los datasets cifrados con una ubicación de clave file://. Para restringir la carga de claves a datasets específicos, enumérelos en zfskeys_datasets, separados por espacios:

# sysrc zfskeys_datasets="zroot/secretdata"

Cualquiera que pueda leer el archivo de clave puede descifrar el dataset. Mantenga el archivo de clave como propiedad de root con el modo 600, y guárdelo en un almacenamiento que esté protegido por sí mismo, como un sistema de archivos raíz cifrado o un medio extraíble que solo se conecte durante el arranque.

23.7. Entornos de arranque

Un entorno de arranque es un clon arrancable del árbol de datasets que contiene el sistema operativo. En los sistemas instalados con la disposición Root-on-ZFS, estos datasets residen bajo zroot/ROOT, con el sistema en ejecución en zroot/ROOT/default. La creación de un entorno de arranque toma instantáneas y clona los datasets raíz, lo cual se completa en segundos y casi no consume espacio hasta que los entornos comienzan a divergir.

Gestione los entornos de arranque con bectl(8). Cree un nuevo entorno antes de un cambio importante, como una actualización del sistema operativo o de un paquete grande:

# bectl create beforeupgrade
# bectl list
BE            Active Mountpoint Space Created
default       NR     /          2.43G 2026-07-11 11:26
beforeupgrade -      -          328K  2026-07-11 11:31

En la columna Active, N marca el entorno en uso actualmente, y R marca el que se activará en el reinicio.

Realice la actualización con freebsd-update(8) o pkg(8) como de costumbre. La actualización modifica el entorno activo, mientras que beforeupgrade preserva el sistema tal como estaba. Si el sistema actualizado no arranca o se comporta de forma incorrecta, reinicie y seleccione beforeupgrade en el menú Boot Environments del cargador de FreeBSD. Seleccionar un entorno en el menú del cargador afecta únicamente al arranque actual. Para hacer que la reversión sea permanente, active el entorno:

# bectl activate beforeupgrade

Ejecutar bectl activate -t beName en su lugar activa un entorno solo para el siguiente arranque, lo cual es útil al probar cambios en un sistema remoto.

Para inspeccionar o reparar el contenido de un entorno inactivo sin arrancarlo, móntelo en una ubicación temporal:

# bectl mount beforeupgrade
/tmp/be_mount.c1Xk
# bectl umount beforeupgrade

Destruya un entorno que ya no sea necesario para recuperar el espacio que utiliza:

# bectl destroy beforeupgrade

Crear un entorno de arranque antes de cada actualización con freebsd-update(8) o de una operación grande con pkg(8) proporciona una forma instantánea de volver a un sistema en buen estado conocido sin tener que restaurar desde copias de seguridad.

23.7.1. Entornos de arranque y aplicaciones

Un entorno de arranque contiene únicamente los datasets bajo zroot/ROOT. En la disposición predeterminada Root-on-ZFS, esto incluye todo el sistema de archivos raíz con /usr/local y /var/db, por lo que los paquetes instalados y sus metadatos se revierten junto con el sistema operativo. Los datasets fuera de zroot/ROOT, como zroot/home, zroot/var/log y zroot/var/mail, son compartidos: cada entorno ve los mismos archivos, y activar un entorno más antiguo no los devuelve a un estado anterior.

Planifique la disposición de los datasets en torno a esta división antes de depender de los entornos de arranque. Los datos que deben sobrevivir a una reversión, como las bases de datos de una aplicación instalada desde paquetes, pertenecen a su propio dataset fuera de zroot/ROOT:

# zfs create -o mountpoint=/var/db/postgres zroot/pgdata

Con esta disposición, revertir a un entorno más antiguo devuelve los binarios del servidor de base de datos a su versión anterior, mientras que el contenido de la base de datos permanece intacto. Lo inverso también se cumple: los archivos escritos en datasets compartidos mientras se prueba un nuevo entorno persisten después de volver atrás, por lo que los entornos de arranque no reemplazan a las instantáneas de esos datasets.

23.8. Temas avanzados

23.8.1. Ajuste de rendimiento

Ajuste los parámetros configurables para que ZFS ofrezca el mejor rendimiento en diferentes cargas de trabajo. FreeBSD expone los parámetros configurables del kernel de ZFS como variables de sysctl(8) bajo vfs.zfs; zfs(4) documenta cada parámetro configurable y su valor predeterminado. Establezca los valores que deben aplicarse desde el arranque en /boot/loader.conf; ajuste los valores modificables en tiempo de ejecución con sysctl(8) y hágalos permanentes en /etc/sysctl.conf.

  • vfs.zfs.arc.max - Tamaño máximo del ARC. El valor predeterminado de 0 permite a ZFS dimensionar el ARC automáticamente en función de la cantidad de memoria instalada. Utilice un valor más bajo si el sistema ejecuta otros demonios o procesos que puedan requerir memoria; consulte Dimensionamiento y monitorización de ARC para obtener orientación. Ajuste este valor en tiempo de ejecución con sysctl(8) y establézcalo en /boot/loader.conf o /etc/sysctl.conf.

  • vfs.zfs.arc.min - Tamaño mínimo del ARC. El valor predeterminado de 0 permite a ZFS elegir un mínimo pequeño automáticamente. Aumente este valor para evitar que otras aplicaciones desplacen todo el ARC. Ajuste este valor en tiempo de ejecución con sysctl(8) y establézcalo en /boot/loader.conf o /etc/sysctl.conf.

  • vfs.zfs.arc.meta_balance - Equilibrio entre el almacenamiento en caché de metadatos y datos de archivos en el ARC; los valores superiores a 100 favorecen cada vez más a los metadatos, y el valor predeterminado es 500. Aumente este valor si la carga de trabajo implica operaciones en un gran número de archivos y directorios, u operaciones frecuentes de metadatos, a costa de que quepan menos datos de archivos en el ARC. Este parámetro configurable reemplaza a vfs.zfs.arc.meta_limit, el cual fue eliminado en OpenZFS 2.2. Ajuste este valor en cualquier momento con sysctl(8).

  • vfs.zfs.vdev.min_auto_ashift - El ashift (tamaño de sector) mínimo utilizado automáticamente en el momento de la creación del pool. El valor es una potencia de dos. El valor predeterminado de 9 representa 2^9 = 512, un tamaño de sector de 512 bytes. Para evitar la amplificación de escritura y obtener el mejor rendimiento, establezca este valor en el tamaño de sector más grande utilizado por un dispositivo en el pool.

    Consulte Creación y destrucción de pools de almacenamiento para saber por qué los pools en unidades con sectores de 4 KB deben usar un ashift de 12.

  • vfs.zfs.prefetch.disable - Deshabilita la captación previa (prefetch). Un valor de 0 la habilita y 1 la deshabilita. El valor predeterminado es 0. La captación previa funciona leyendo bloques más grandes de lo solicitado en el ARC con la esperanza de necesitar pronto los datos. Si la carga de trabajo tiene un gran número de lecturas aleatorias, deshabilitar la captación previa puede en realidad mejorar el rendimiento al reducir las lecturas innecesarias. Ajuste este valor en cualquier momento con sysctl(8).

  • vfs.zfs.txg.timeout - Número máximo de segundos entre grupos de transacciones. El grupo de transacciones actual escribe en el pool y se inicia un nuevo grupo de transacciones si transcurre esta cantidad de tiempo desde el grupo de transacciones anterior. Un grupo de transacciones puede desencadenarse antes si se escriben suficientes datos. El valor predeterminado es de 5 segundos. Un valor mayor puede mejorar el rendimiento de lectura al retrasar las escrituras asíncronas, pero esto puede causar un rendimiento irregular al escribir el grupo de transacciones. Ajuste este valor en cualquier momento con sysctl(8).

  • vfs.zfs.l2arc.write_max - Limita la cantidad de datos escritos en el L2ARC por segundo. Este parámetro configurable prolonga la longevidad de los SSD al limitar la cantidad de datos que se escriben en el dispositivo. Ajuste este valor en cualquier momento con sysctl(8).

  • vfs.zfs.l2arc.write_boost - Añade el valor de este parámetro configurable a vfs.zfs.l2arc.write_max y aumenta la velocidad de escritura en el SSD hasta expulsar el primer bloque del L2ARC. Esta "Fase de calentamiento turbo" reduce la pérdida de rendimiento de un L2ARC vacío después de un reinicio. Ajuste este valor en cualquier momento con sysctl(8).

  • vfs.zfs.l2arc.rebuild_enabled - Hace que el contenido del L2ARC persista a través de los reinicios. Con el valor predeterminado de 1, ZFS reconstruye el L2ARC a partir de los bloques de registro almacenados en el dispositivo de caché al importar un pool, evitando el largo período de calentamiento que de otro modo necesitaría una caché vacía. Establezca este valor en 0 para comenzar siempre con un L2ARC vacío.

  • vfs.zfs.vdev.max_active - Número máximo de solicitudes de E/S activas en cada dispositivo del pool. Un valor más alto mantiene llenas las colas de comandos del dispositivo y puede proporcionar un mayor rendimiento. Un valor más bajo reduce la latencia. Ajuste este valor en cualquier momento con sysctl(8).

  • vfs.zfs.vdev.*_min_active y vfs.zfs.vdev.*_max_active - Número mínimo y máximo de solicitudes de E/S concurrentes que el planificador emite a cada dispositivo para cada clase de E/S: sync_read, sync_write, async_read, async_write, scrub y otras. Estos límites por clase reemplazan la limitación basada en retrasos del scrub y el resilver que se encontraba en versiones anteriores de ZFS. Por ejemplo, aumentar vfs.zfs.vdev.scrub_max_active permite que un scrub utilice una mayor parte de la cola de cada dispositivo, terminando antes a costa de la latencia de E/S en primer plano.

  • vfs.zfs.resilver_min_time_ms - Cantidad mínima de tiempo, en milisegundos, que un resilver pasa trabajando entre los vaciados del grupo de transacciones; el valor predeterminado es 3000 (3 segundos). Aumente este valor para completar un resilver antes cuando un pool degradado corre el riesgo de perder otro dispositivo, a costa de ralentizar el funcionamiento normal del pool. Ajuste este valor en cualquier momento con sysctl(8).

    === Dimensionamiento y monitorización del ARC

ZFS mantiene los datos y metadatos usados reciente y frecuentemente en la RAM en el ARC. El ARC crece bajo demanda hasta vfs.zfs.arc.max y se reduce de nuevo cuando otros programas necesitan memoria, por lo que en un servidor de almacenamiento dedicado es normal que la mayor parte de la RAM esté en uso. El ARC almacena los bloques en su forma comprimida en disco y los descomprime al acceder a ellos. Este ARC comprimido permite que la misma cantidad de RAM almacene en caché más datos, aumentando la tasa efectiva de aciertos.

top(1) muestra el tamaño actual del ARC en su línea de resumen de memoria. El árbol sysctl(8) kstat.zfs.misc.arcstats expone estadísticas detalladas, incluyendo el tamaño actual, el máximo objetivo y los contadores de aciertos y fallos:

% sysctl kstat.zfs.misc.arcstats.size kstat.zfs.misc.arcstats.c_max kstat.zfs.misc.arcstats.hits kstat.zfs.misc.arcstats.misses
kstat.zfs.misc.arcstats.size: 8963041280
kstat.zfs.misc.arcstats.c_max: 15843122176
kstat.zfs.misc.arcstats.hits: 954912441
kstat.zfs.misc.arcstats.misses: 21356847

filesystems/zfs-stats resume estas estadísticas en un informe legible por humanos.

El ARC cede memoria bajo presión, pero en sistemas que comparten RAM entre ZFS y otros grandes consumidores como bases de datos, máquinas virtuales o jails, la competencia puede causar un rendimiento desigual en ambos lados. Limitar el ARC deja una cantidad predecible de memoria para las otras cargas de trabajo. Por ejemplo, para limitar el ARC a 8 GB, añada esta línea a /boot/loader.conf:

vfs.zfs.arc.max="8G"

Cambiar vfs.zfs.arc.max con sysctl(8) tiene efecto inmediatamente, aunque reducir un ARC caliente libera memoria gradualmente.

23.8.2. Escrituras síncronas, el ZIL y SLOG

Cada pool tiene un ZIL. Las aplicaciones que solicitan semántica síncrona con fsync(2) o el indicador O_SYNC no obtienen una confirmación hasta que ZFS confirma el registro de intenciones correspondiente en el almacenamiento estable. Por defecto, el ZIL reside en los vdevs regulares del pool, por lo que cada escritura síncrona compite con la E/S normal del pool. Las escrituras asíncronas omiten el ZIL y se escriben con el siguiente transaction group.

Un vdev de log dedicado, a menudo llamado SLOG (registro separado), mueve el ZIL a un dispositivo rápido:

# zpool add mypool log mirror nda0 nda1

Un SLOG solo ayuda a las cargas de trabajo que generan muchas escrituras síncronas, como los servidores NFS y las bases de datos. No supone ninguna diferencia para las cargas de trabajo puramente asíncronas.

Unos pocos gigabytes de capacidad de SLOG son suficientes: el ZIL contiene como máximo unos pocos segundos de escrituras entrantes, aproximadamente el valor de un grupo de transacciones, antes de que ZFS escriba los datos en su ubicación final en el pool. Elija SSDs con protección contra pérdida de energía y baja latencia de escritura sostenida, y refleje los dispositivos de registro. ZFS lee el ZIL solo después de un fallo, por lo que perder un SLOG sin reflejar junto con un fallo del sistema hace que se pierdan las escrituras que fueron reconocidas pero aún no confirmadas en el pool.

La propiedad sync del dataset controla el comportamiento de la escritura síncrona:

  • sync=standard (el valor por defecto) confirma las escrituras síncronas en el ZIL y las escrituras asíncronas con el siguiente grupo de transacciones.

  • sync=always trata cada escritura como síncrona, intercambiando rendimiento por seguridad, lo que solo ayuda a las aplicaciones que no solicitan escrituras síncronas cuando deberían hacerlo.

  • sync=disabled trata cada escritura como asíncrona.

Con sync=disabled, ZFS reconoce las escrituras síncronas antes de que alcancen el almacenamiento estable. El pool en sí se mantiene consistente, pero después de un fallo o pérdida de energía, las aplicaciones y los clientes NFS pierden silenciosamente hasta unos pocos segundos de datos que creían que se habían escrito de forma segura. No utilice sync=disabled para bases de datos, exportaciones NFS o cualquier otro dato que importe.

La propiedad logbias ajusta cómo ZFS utiliza el registro: logbias=latency (el valor por defecto) favorece el SLOG para minimizar la latencia de confirmación, mientras que logbias=throughput escribe los datos síncronos directamente en el pool principal, reservando la capacidad del SLOG para los datasets sensibles a la latencia. Consulte zfsprops(7) para obtener más detalles.

23.8.3. E/S directa

La E/S directa requiere OpenZFS 2.3 o posterior, disponible por primera vez en FreeBSD 15.0.

La propiedad direct del dataset controla cómo ZFS maneja las peticiones realizadas con el indicador O_DIRECT:

  • direct=standard (el valor por defecto) respeta O_DIRECT: las lecturas y escrituras correctamente alineadas omiten el ARC.

  • direct=always trata cada lectura o escritura correctamente alineada como una petición directa.

  • direct=disabled ignora silenciosamente O_DIRECT y maneja cada petición a través del ARC.

La E/S directa evita las copias de memoria y la sobrecarga de almacenamiento en caché del ARC. En pools de dispositivos NVMe muy rápidos, esta sobrecarga puede dominar el coste de la propia E/S, y las aplicaciones que mantienen sus propias cachés, como las bases de datos, desperdician RAM al almacenar en caché los mismos datos dos veces. Para tales cargas de trabajo, la E/S directa puede aumentar el rendimiento y reducir el uso de memoria.

ZFS sigue verificando las sumas de comprobación para las lecturas y escrituras directas, por lo que la protección de la integridad de los datos no cambia. Las escrituras directas deben estar alineadas con el recordsize del dataset; ZFS redirige silenciosamente la porción no alineada de una petición a través del ARC. Consulte zfsprops(7) para conocer las reglas de alineación y restricciones completas.

23.8.4. recordsize y volblocksize

La propiedad recordsize establece el bloque más grande que ZFS utiliza para almacenar un archivo en un dataset, 128 KB por defecto. Hacer coincidir el tamaño del bloque con el patrón de E/S de la carga de trabajo evita leer y escribir más datos de los que solicitó la aplicación.

Para las bases de datos que realizan pequeñas lecturas y escrituras aleatorias, establezca recordsize en el tamaño de página de la base de datos, típicamente 8 KB o 16 KB, antes de crear los archivos de la base de datos. Para los datasets que almacenan archivos multimedia grandes o flujos de copia de seguridad que se leen y escriben secuencialmente, recordsize=1M reduce la sobrecarga de metadatos y mejora la compresión. Los volúmenes utilizan en su lugar la propiedad volblocksize, que por defecto es de 16 KB y no puede cambiar después de crear el volumen.

Cambiar recordsize afecta solo a los archivos recién escritos; los archivos existentes mantienen su tamaño de bloque original. Ni siquiera zfs rewrite aplica un nuevo recordsize a los archivos existentes, ya que los cambios de propiedades que afectan al tamaño del bloque lógico no tienen efecto sobre los bloques reescritos; copie los archivos de nuevo para almacenarlos con el nuevo valor.

  • Documentación de OpenZFS, incluyendo las guías de Rendimiento y Ajuste

  • OpenZFS

  • zfs(4) describe cada parámetro ajustable del kernel, zpoolconcepts(7) describe los tipos de vdev y la disposición del pool, y zfsprops(7) describe cada propiedad del dataset

  • Herramientas de automatización de instantáneas y replicación de la Colección de Ports:

    • filesystems/zrepl - un demonio de replicación que soporta configuraciones push y pull, gestión automática de instantáneas y transferencias reanudables

    • sysutils/sanoid - gestión de instantáneas basada en políticas, con el syncoid incluido manejando la replicación a través de SSH

    • filesystems/zfstools - rotación automática de instantáneas al estilo del servicio auto-snapshot de OpenSolaris, ejecutado desde cron(8)

    • filesystems/zap - mantenimiento sencillo de instantáneas y replicación remota, configurado a través de propiedades de ZFS en lugar de un archivo de configuración

23.10. Características y terminología de ZFS

ZFS es fundamentalmente diferente de los sistemas de archivos tradicionales. ZFS combina los roles de sistema de archivos y gestor de volúmenes, permitiendo la adición de nuevos dispositivos de almacenamiento a un sistema en vivo y haciendo que el nuevo espacio esté disponible en los sistemas de archivos existentes en ese pool de inmediato. Al combinar los roles tradicionalmente separados, ZFS supera las limitaciones anteriores que impedían que los grupos RAID crecieran. Un vdev es un dispositivo de nivel superior en un pool y puede ser un disco simple o una transformación RAID como un espejo o un array RAID-Z. Los sistemas de archivos ZFS (llamados datasets) tienen cada uno acceso al espacio libre combinado de todo el pool. Los bloques usados del pool disminuyen el espacio disponible para cada sistema de archivos. Este enfoque evita el error común con el particionamiento extensivo donde el espacio libre se fragmenta a través de las particiones.

pool

Un pool de almacenamiento es el bloque de construcción más básico de ZFS. Un pool consta de uno o más vdevs, los dispositivos subyacentes que almacenan los datos. Un pool se utiliza luego para crear uno o más sistemas de archivos (datasets) o dispositivos de bloques (volúmenes). Estos datasets y volúmenes comparten el pool de espacio libre restante. Cada pool se identifica de forma única por un nombre y un GUID. Los pools creados por el OpenZFS moderno están en la versión de pool 5000; a partir de esa versión, las capacidades individuales se gestionan mediante feature flags en lugar del número de versión. Consulte zpool-features(7) y Upgrading a Storage Pool para obtener más detalles.

Tipos de vdev

Un pool consta de uno o más vdevs, que a su vez son un solo disco o un grupo de discos, transformados en un RAID. Cuando se utilizan muchos vdevs, ZFS distribuye los datos a través de los vdevs para aumentar el rendimiento y maximizar el espacio utilizable. Todos los vdevs deben tener al menos 64 MB de tamaño.

  • Disk (Disco) - El tipo de vdev más básico es un dispositivo de bloques estándar. Este puede ser un disco entero (como /dev/ada0) o una partición (/dev/ada0p3). En FreeBSD, no hay penalización de rendimiento por usar una partición en lugar del disco entero. Esto difiere de las recomendaciones hechas por la documentación de Solaris.

    Se desaconseja encarecidamente el uso de un disco entero como parte de un pool arrancable, ya que esto puede hacer que el pool no pueda arrancar. Del mismo modo, no debe utilizar un disco entero como parte de un vdev espejo o RAID-Z. Determinar de forma fiable el tamaño de un disco sin particionar en el momento del arranque es imposible y no hay lugar para poner el código de arranque.

  • File (Archivo) - Los archivos regulares pueden conformar pools de ZFS, lo cual es útil para pruebas y experimentación. Utilice la ruta completa al archivo como la ruta del dispositivo en zpool create.

  • Mirror (Espejo) - Al crear un espejo, especifique la palabra clave mirror seguida de la lista de dispositivos miembros para el espejo. Un espejo consta de dos o más dispositivos, escribiendo todos los datos en todos los dispositivos miembros. Un vdev espejo contendrá tantos datos como su miembro más pequeño. Un vdev espejo puede soportar el fallo de todos sus miembros excepto uno sin perder ningún dato.

    Para actualizar un vdev regular de un solo disco a un vdev espejo en cualquier momento, utilice zpool attach.

  • RAID-Z - ZFS utiliza RAID-Z, una variación del RAID-5 estándar que ofrece una mejor distribución de la paridad y elimina el "agujero de escritura de RAID-5" en el que la información de datos y paridad se vuelve inconsistente después de un reinicio inesperado. ZFS soporta tres niveles de RAID-Z que proporcionan niveles variables de redundancia a cambio de niveles decrecientes de almacenamiento utilizable. ZFS utiliza desde RAID-Z1 hasta RAID-Z3 basándose en el número de dispositivos de paridad en el array y el número de discos que pueden fallar antes de que el pool deje de estar operativo.

    En una configuración RAID-Z1 con cuatro discos, cada uno de 1 TB, el almacenamiento utilizable es de 3 TB y el pool aún podrá operar en modo degradado con un disco fallido. Si otro disco se desconecta antes de reemplazar y resincronizar el disco fallido, resultaría en la pérdida de todos los datos del pool.

    En una configuración RAID-Z3 con ocho discos de 1 TB, el volumen proporcionará 5 TB de espacio utilizable y aún podrá operar con tres discos fallidos. La recomendación tradicional es no más de nueve discos en un solo vdev. Si más discos conforman la configuración, la recomendación es dividirlos en vdevs separados y distribuir los datos del pool a través de ellos.

    Una configuración de dos vdevs RAID-Z2 que constan de 8 discos cada uno crearía algo parecido a un array RAID-60. La capacidad de almacenamiento de un grupo RAID-Z es aproximadamente el tamaño del disco más pequeño multiplicado por el número de discos sin paridad. Cuatro discos de 1 TB en RAID-Z1 tienen un tamaño efectivo de aproximadamente 3 TB, y un array de ocho discos de 1 TB en RAID-Z3 producirá 5 TB de espacio utilizable.

    Hacer crecer un vdev raidz un disco a la vez es posible con la RAID-Z expansion, que requiere OpenZFS 2.3 o posterior, disponible por primera vez en FreeBSD 15.0.

  • dRAID - Una variante de RAID-Z que distribuye datos, paridad y capacidad de repuesto a través de todos los discos miembros utilizando bandas de ancho fijo. En lugar de discos de repuesto en caliente dedicados, dRAID proporciona repuestos distribuidos: capacidad de repuesto distribuida sobre cada disco miembro, permitiendo que un disco fallido se reconstruya secuencialmente en todos los discos restantes a la vez y restaurando la redundancia mucho más rápido que una resincronización tradicional en un solo repuesto. Especifique un vdev dRAID como draid[parity][:datad][:childrenc][:sparess], como se describe en zpoolconcepts(7). Consulte dRAID Pools para obtener más detalles.

  • dRAID - Una variante de RAID-Z que distribuye datos, paridad y capacidad de repuesto entre todos los discos miembros usando franjas de ancho fijo. En lugar de discos de repuesto en caliente dedicados, dRAID ofrece repuestos distribuidos: capacidad de repuesto repartida por cada disco miembro, lo que permite que un disco fallido se reconstruya secuencialmente sobre todos los discos restantes a la vez, restaurando la redundancia mucho más rápido que un resilver tradicional sobre un único repuesto. Especifique un vdev dRAID como draid[parity][:datad][:childrenc][:sparess], como se describe en zpoolconcepts(7). Consulte dRAID Pools para obtener más detalles.

  • Spare (Repuesto) - ZFS tiene un tipo especial de pseudo-vdev para realizar un seguimiento de los repuestos en caliente disponibles. Cuando zfsd(8) está habilitado, ZFS despliega los repuestos en caliente instalados automáticamente para reemplazar los dispositivos fallidos; de lo contrario, configúrelos manualmente para reemplazar el dispositivo fallido utilizando zpool replace. Consulte Hot Spares and Automatic Replacement with zfsd para obtener más detalles.

  • Log (Registro) - Cada pool tiene un Registro de Intenciones de ZFS (ZIL), almacenado en los dispositivos regulares del pool por defecto. Un vdev de registro dedicado, a menudo llamado SLOG, mueve el registro de intenciones a un dispositivo separado, típicamente un SSD. Tener un dispositivo de registro dedicado mejora el rendimiento de las aplicaciones con un alto volumen de escrituras síncronas como las bases de datos. El reflejo de los dispositivos de registro es posible, pero RAID-Z no está soportado. Si se utilizan muchos dispositivos de registro, las escrituras se equilibrarán en carga a través de ellos. Consulte Synchronous Writes, the ZIL, and SLOG para obtener más detalles.

  • Cache (Caché) - Añadir un vdev de caché a un pool añadirá el almacenamiento de la caché al L2ARC. Reflejar dispositivos de caché es imposible. Dado que un dispositivo de caché almacena solo nuevas copias de datos existentes, no hay riesgo de pérdida de datos.

  • Special/Dedup (Especial/Deduplicación) - Vdevs de clase de asignación que almacenan metadatos del pool, opcionalmente bloques de archivos pequeños (controlados por la propiedad del dataset special_small_blocks), y tablas de deduplicación en dispositivos rápidos como SSDs, acelerando un pool de discos más lentos. Estos vdevs son críticos para el pool: perder un vdev especial o de deduplicación hace que se pierda el pool, así que deles el mismo nivel de redundancia que a los vdevs de datos. Consulte Special Allocation Classes para obtener más detalles.

Grupo de transacciones (TXG)

Los grupos de transacciones son la forma en que ZFS agrupa los cambios de bloques y los escribe en el pool. Los grupos de transacciones son la unidad atómica que ZFS utiliza para garantizar la consistencia. ZFS asigna a cada grupo de transacciones un identificador consecutivo único de 64 bits. Puede haber hasta tres grupos de transacciones activos a la vez, uno en cada uno de estos tres estados:

* Open - Un nuevo grupo de transacciones comienza en el estado abierto y acepta nuevas escrituras. Siempre hay un grupo de transacciones en el estado abierto, pero el grupo de transacciones puede rechazar nuevas escrituras si ha alcanzado un límite. Una vez que el grupo de transacciones abierto ha alcanzado un límite, o al alcanzar el vfs.zfs.txg.timeout, el grupo de transacciones avanza al siguiente estado. * Quiescing - Un estado corto que permite que cualquier operación pendiente finalice sin bloquear la creación de un nuevo grupo de transacciones abierto. Una vez que todas las transacciones del grupo se han completado, el grupo de transacciones avanza al estado final. * Syncing - Escribe todos los datos del grupo de transacciones en el almacenamiento estable. Este proceso, a su vez, cambiará otros datos, como los metadatos y los mapas de espacio, que ZFS también escribirá en el almacenamiento estable. El proceso de sincronización implica varias pasadas. En la primera y más grande, todos los bloques de datos modificados; a continuación vienen los metadatos, que pueden requerir varias pasadas para completarse. Dado que la asignación de espacio para los bloques de datos genera nuevos metadatos, el estado de sincronización no puede terminar hasta que se complete una pasada que no utilice ningún espacio nuevo. El estado de sincronización es también donde se completan las synctasks. Las synctasks son operaciones administrativas como la creación o destrucción de snapshots y datasets que completan el cambio del uberblock. Una vez que el estado de sincronización se completa, el grupo de transacciones en el estado de inactividad avanza al estado de sincronización. Todas las funciones administrativas, como snapshot se escriben como parte del grupo de transacciones. ZFS añade una synctask creada al grupo de transacciones abierto, y ese grupo avanza lo más rápido posible al estado de sincronización para reducir la latencia de los comandos administrativos.

Caché de Reemplazo Adaptativo (ARC)

ZFS utiliza una Caché de Reemplazo Adaptativo (ARC), en lugar de una caché tradicional de Menos Usado Recientemente (LRU). Una caché LRU es una lista simple de elementos en la caché, ordenados por la fecha de uso reciente del objeto, añadiendo nuevos elementos a la cabeza de la lista. Cuando la caché está llena, la expulsión de elementos de la cola de la lista hace espacio para objetos más activos. Una ARC consta de cuatro listas; los objetos Más Usados Recientemente (MRU) y Más Frecuentemente Usados (MFU), además de una lista fantasma para cada uno. Estas listas fantasma rastrean los objetos expulsados para evitar añadirlos de nuevo a la caché. Esto aumenta la tasa de aciertos de la caché al evitar objetos que tienen un historial de uso ocasional. Otra ventaja de usar tanto un MRU como un MFU es que escanear un sistema de archivos completo expulsaría todos los datos de una caché MRU o LRU a favor de este contenido recién accedido. Con ZFS, también hay un MFU que rastrea los objetos más frecuentemente usados, y la caché de los bloques accedidos más comúnmente permanece.

L2ARC

L2ARC es el segundo nivel del sistema de caché de ZFS. La RAM almacena la ARC primaria. Dado que la cantidad de RAM disponible a menudo es limitada, ZFS también puede usar cache vdevs. Los Discos de Estado Sólido (SSDs) se usan a menudo como estos dispositivos de caché debido a su mayor velocidad y menor latencia en comparación con los discos giratorios tradicionales. L2ARC es completamente opcional, pero tener uno aumentará las velocidades de lectura para los archivos en caché en el SSD en lugar de tener que leer de los discos regulares. L2ARC también puede acelerar la deduplication porque una tabla de deduplicación (DDT) que no cabe en la RAM pero sí cabe en la L2ARC será mucho más rápida que una DDT que deba leer del disco. Desde OpenZFS 2.0, la L2ARC es persistente: después de un reinicio, ZFS reconstruye el contenido de la caché a partir de las cabeceras almacenadas en el dispositivo de caché en lugar de comenzar con una caché vacía. Los límites en la tasa de datos añadidos a los dispositivos de caché evitan el desgaste prematuro de los SSDs con escrituras adicionales. Hasta que la caché esté llena (el primer bloque expulsado para hacer espacio), las escrituras en la L2ARC se limitan a la suma del límite de escritura y el límite de impulso (boost), y posteriormente se limitan al límite de escritura. Un par de valores de sysctl(8) controlan estos límites de tasa: vfs.zfs.l2arc.write_max controla el número de bytes escritos en la caché por segundo, mientras que vfs.zfs.l2arc.write_boost se añade a este límite hasta la primera expulsión de la caché. Consulte Tuning para obtener más detalles.

ZIL

El Registro de Intenciones de ZFS (ZIL) es el registro en disco que ZFS utiliza para reproducir escrituras síncronas después de un fallo. Cada pool tiene un ZIL; por defecto ocupa una pequeña cantidad de espacio en los dispositivos regulares del pool. Cuando una aplicación solicita una escritura síncrona (una garantía de que los datos se almacenan en el disco en lugar de simplemente almacenarse en caché para escrituras posteriores), ZFS confirma los datos en el ZIL primero y los vuelca al almacenamiento regular con el siguiente grupo de transacciones. Mover el ZIL a un log vdev (SLOG) dedicado en un dispositivo más rápido que el almacenamiento principal, como un SSD, reduce en gran medida la latencia y mejora el rendimiento. Las cargas de trabajo síncronas como las bases de datos se beneficiarán únicamente de un ZIL rápido. Las escrituras asíncronas regulares, como la copia de archivos, no utilizarán el ZIL en absoluto. Consulte Synchronous Writes, the ZIL, and SLOG para obtener más detalles.

Copy-On-Write

A diferencia de un sistema de archivos tradicional, ZFS escribe un bloque diferente en lugar de sobrescribir los datos antiguos en el mismo lugar. Al completar esta escritura, los metadatos se actualizan para apuntar a la nueva ubicación. Cuando ocurre una escritura interrumpida (un fallo del sistema o pérdida de energía en medio de la escritura de un archivo), todo el contenido original del archivo sigue estando disponible y ZFS descarta la escritura incompleta. Esto también significa que ZFS no requiere un fsck(8) después de un apagado inesperado.

Dataset

Dataset es el término genérico para un sistema de archivos, volumen, snapshot o clon de ZFS. Cada dataset tiene un nombre único en el formato poolname/path@snapshot. La raíz del pool también es un dataset. Los datasets hijos tienen nombres jerárquicos como los directorios. Por ejemplo, mypool/home, el dataset de inicio, es un hijo de mypool y hereda propiedades de él. Expanda esto aún más creando mypool/home/user. Este dataset nieto heredará las propiedades del padre y del abuelo. Establezca propiedades en un hijo para anular los valores predeterminados heredados del padre y del abuelo. La administración de los datasets y sus hijos puede ser delegated.

Sistema de archivos

Un dataset de ZFS se utiliza con mayor frecuencia como un sistema de archivos. Al igual que la mayoría de los demás sistemas de archivos, un sistema de archivos ZFS se monta en algún lugar de la jerarquía de directorios del sistema y contiene archivos y directorios propios con permisos, indicadores (flags) y otros metadatos.

Volumen

ZFS también puede crear volúmenes, que aparecen como dispositivos de disco. Los volúmenes tienen muchas de las mismas características que los datasets, incluyendo copy-on-write, snapshots, clones y sumas de comprobación (checksumming). Los volúmenes pueden ser útiles para ejecutar otros formatos de sistemas de archivos sobre ZFS, como la virtualización de UFS, o para exportar extensiones iSCSI.

Snapshot

El diseño copy-on-write (COW) de ZFS permite snapshots consistentes y casi instantáneos con nombres arbitrarios. Después de tomar un snapshot de un dataset, o un snapshot recursivo de un dataset padre que incluirá todos los datasets hijos, los nuevos datos van a nuevos bloques, pero sin reclamar los bloques antiguos como espacio libre. El snapshot contiene la versión original del sistema de archivos y el sistema de archivos en vivo contiene cualquier cambio realizado desde que se tomó el snapshot sin usar ningún otro espacio. Los nuevos datos escritos en el sistema de archivos en vivo usan nuevos bloques para almacenar estos datos. El snapshot crecerá a medida que los bloques ya no se utilicen en el sistema de archivos en vivo, sino únicamente en el snapshot. Montar estos snapshots como de solo lectura permite recuperar versiones anteriores de archivos. Un rollback de un sistema de archivos en vivo a un snapshot específico es posible, deshaciendo cualquier cambio que haya tenido lugar después de tomar el snapshot. Cada bloque en el pool tiene un contador de referencias que realiza un seguimiento de los snapshots, clones, datasets o volúmenes que usan ese bloque. A medida que los archivos y snapshots se eliminan, el recuento de referencias disminuye, reclamando el espacio libre cuando ya no se hace referencia a un bloque. Marcar los snapshots con un hold significa que cualquier intento de destruirlo devuelve un error EBUSY. Cada snapshot puede tener retenciones (holds) con un nombre único cada una. El comando release elimina la retención para que el snapshot pueda ser eliminado. Los snapshots, la clonación y el rollback funcionan en volúmenes, pero el montaje independiente no.

Clon

Clonar un snapshot también es posible. Un clon es una versión escribible de un snapshot, lo que permite que el sistema de archivos se bifurque como un nuevo dataset. Al igual que con un snapshot, un clon inicialmente no consume espacio nuevo. A medida que los nuevos datos escritos en un clon utilizan nuevos bloques, el tamaño del clon crece. Cuando los bloques se sobrescriben en el sistema de archivos o volumen clonado, el recuento de referencias en el bloque anterior disminuye. Eliminar el snapshot en el que se basa un clon es imposible porque el clon depende de él. El snapshot es el padre y el clon es el hijo. Los clones pueden ser promovidos (promoted), revirtiendo esta dependencia y convirtiendo al clon en el padre y al padre anterior en el hijo. Esta operación no requiere espacio nuevo. Dado que la cantidad de espacio utilizado por el padre y el hijo se invierte, puede afectar a las cuotas y reservas existentes.

Bookmark

Un bookmark registra el punto en el tiempo en el que se tomó un snapshot, sin conservar ninguno de los datos del snapshot. Los bookmarks sirven como origen de los flujos incrementales de zfs send, lo que hace posible destruir el snapshot en el lado de envío mientras se conserva la capacidad de enviar incrementos adicionales. Cree un bookmark a partir de un snapshot existente con zfs bookmark. Consulte Bookmarks para obtener más detalles.

Hold

Un hold (retención) es una etiqueta con nombre colocada en un snapshot que evita su destrucción. Los intentos de destruir un snapshot retenido fallan con un error EBUSY hasta que se libere cada hold con zfs release. Los holds protegen los snapshots de los que aún dependen las herramientas de copia de seguridad y replicación. Consulte Snapshot Holds para obtener más detalles.

Suma de comprobación

Cada bloque también tiene una suma de comprobación. El algoritmo de suma de comprobación utilizado es una propiedad por dataset, consulte set. La suma de comprobación de cada bloque se valida de forma transparente al leerse, lo que permite a ZFS detectar la corrupción silenciosa. Si los datos leídos no coinciden con la suma de comprobación esperada, ZFS intentará recuperar los datos de cualquier redundancia disponible, como espejos (mirrors) o RAID-Z. Desencadene una validación de todas las sumas de comprobación con scrub. Los algoritmos de suma de comprobación incluyen:

* fletcher2 * fletcher4 * sha256 * sha512 * skein * edonr * blake3 (desde FreeBSD 14.0)

Los algoritmos fletcher son más rápidos, pero los hashes criptográficos (sha256, sha512, skein, edonr y blake3) tienen una probabilidad mucho menor de colisiones a costa de algo de rendimiento. El valor predeterminado de on selecciona actualmente fletcher4; la deduplication requiere un hash criptográfico como sha256. Desactivar las sumas de comprobación es posible, pero se desaconseja encarecidamente.

Compresión

Cada dataset tiene una propiedad de compresión. Desde OpenZFS 2.2, los nuevos datasets tienen la compresión habilitada por defecto (compression=on, que selecciona LZ4). Esto provoca la compresión de todos los datos nuevos escritos en el dataset. Más allá de una reducción en el espacio utilizado, el rendimiento de lectura y escritura a menudo aumenta porque se necesitan leer o escribir menos bloques.

* LZ4 - Añadido en la versión 5000 del pool de ZFS (feature flags), LZ4 es el algoritmo que selecciona compression=on y la opción recomendada de propósito general. LZ4 funciona aproximadamente un 50% más rápido que LZJB cuando opera con datos comprimibles, y es más de tres veces más rápido cuando opera con datos incomprimibles. LZ4 también descomprime aproximadamente un 80% más rápido que LZJB. En las CPUs modernas, LZ4 a menudo puede comprimir a más de 500 MB/s y descomprimir a más de 1.5 GB/s (por cada núcleo de CPU individual).

* ZSTD - Zstandard ofrece tasas de compresión más altas que LZ4 con un equilibrio configurable entre velocidad y compresión, que va desde las variantes rápidas zstd-fast hasta zstd-19 para un ahorro de espacio máximo. Consulte Zstandard Compression para obtener más detalles.

* LZJB - Un algoritmo de compresión heredado, creado por Jeff Bonwick (uno de los creadores originales de ZFS). LZJB ofrece una buena compresión con menos sobrecarga de CPU en comparación con GZIP. LZ4 lo ha reemplazado como el algoritmo predeterminado; prefiera LZ4 o ZSTD para los nuevos datasets.

* GZIP - Un popular algoritmo de compresión de flujo disponible en ZFS. Una de las principales ventajas de usar GZIP es su nivel configurable de compresión. Al establecer la propiedad compress, el administrador puede elegir el nivel de compresión, que va desde gzip1, el nivel más bajo de compresión, hasta gzip9, el nivel más alto de compresión. Esto le da al administrador control sobre cuánto tiempo de CPU intercambiar por espacio en disco ahorrado.

* ZLE - Zero Length Encoding (Codificación de Longitud Cero) es un algoritmo de compresión especial que comprime únicamente secuencias continuas de ceros. Este algoritmo de compresión es útil cuando el dataset contiene grandes bloques de ceros.

Copias

Cuando se establece en un valor mayor que 1, la propiedad copies indica a ZFS que mantenga copias de cada bloque en el crossref:zfs[zfs-term-filesystem,file system] o volume. Establecer esta propiedad en datasets importantes proporciona redundancia adicional desde la cual recuperar un bloque que no coincide con su suma de comprobación. En pools sin redundancia, la característica de copias es la única forma de redundancia. La característica de copias puede recuperarse de un solo sector defectuoso u otras formas de corrupción menor, pero no protege al pool de la pérdida de un disco entero.

Deduplicación

Las sumas de comprobación hacen posible detectar bloques duplicados al escribir datos. Con la deduplicación, el recuento de referencias de un bloque existente e idéntico aumenta, ahorrando espacio de almacenamiento. ZFS mantiene una tabla de deduplicación (DDT) en memoria para detectar bloques duplicados. La tabla contiene una lista de sumas de comprobación únicas, la ubicación de esos bloques y un recuento de referencias. Al escribir nuevos datos, ZFS calcula las sumas de comprobación y las compara con la lista. Al encontrar una coincidencia, utiliza el bloque existente. El uso del algoritmo de suma de comprobación SHA256 con deduplicación proporciona un hash criptográfico seguro. La deduplicación es ajustable. Si dedup está en on, entonces una suma de comprobación coincidente significa que los datos son idénticos. Al establecer dedup en verify, ZFS realiza una comprobación byte por byte en los datos asegurando que sean realmente idénticos. Si los datos no son idénticos, ZFS notará la colisión de hash y almacenará los dos bloques por separado. Como la DDT debe almacenar el hash de cada bloque único, consume una gran cantidad de memoria. Una regla general es de 5-6 GB de RAM por cada 1 TB de datos deduplicados. En situaciones en las que no es práctico tener suficiente RAM para mantener toda la DDT en memoria, el rendimiento sufrirá enormemente ya que la DDT debe leerse del disco antes de escribir cada nuevo bloque. La deduplicación puede usar L2ARC para almacenar la DDT, proporcionando un punto intermedio entre la memoria rápida del sistema y los discos más lentos. Considere usar la compresión en su lugar, que a menudo proporciona casi el mismo ahorro de espacio sin el aumento de memoria. Fast dedup (deduplicación rápida) agrupa las actualizaciones de la DDT en un registro, permite podar las entradas obsoletas con zpool ddtprune y limita el tamaño de la tabla con la propiedad del pool dedup_table_quota; requiere OpenZFS 2.3 o posterior, disponible por primera vez en FreeBSD 15.0. Consulte Deduplication para obtener más detalles.

Clonación de Bloques

La clonación de bloques permite que una copia de archivo haga referencia a los bloques existentes en el disco del archivo de origen en lugar de duplicarlos, por lo que la copia se completa casi instantáneamente y no consume espacio adicional hasta que cualquiera de los archivos cambie. En FreeBSD, cp(1) utiliza copy_file_range(2), por lo que las copias de archivos ordinarias se convierten en clones de bloques cuando la característica está habilitada (el valor predeterminado en FreeBSD 15.0). Las propiedades del pool bcloneused, bclonesaved y bcloneratio informan sobre el ahorro de espacio resultante. Consulte Block Cloning para obtener más detalles.

Scrub

En lugar de una comprobación de consistencia como fsck(8), ZFS tiene scrub. scrub lee todos los bloques de datos almacenados en el pool y verifica sus sumas de comprobación frente a las sumas de comprobación buenas conocidas almacenadas en los metadatos. Una comprobación periódica de todos los datos almacenados en el pool asegura la recuperación de cualquier bloque corrupto antes de necesitarlo. No se requiere un scrub después de un apagado incorrecto, pero una buena práctica es al menos una vez al mes. ZFS verifica la suma de comprobación de cada bloque durante el uso normal, pero un scrub se asegura de comprobar incluso los bloques de uso poco frecuente en busca de corrupción silenciosa. ZFS mejora la seguridad de los datos en situaciones de almacenamiento de archivo. Pause un scrub en ejecución con zpool scrub -p y reanúdelo más tarde ejecutando zpool scrub de nuevo. Consulte Scrubbing a Pool para obtener más detalles.

Checkpoint

Un checkpoint preserva todo el estado de un pool en un único punto en el tiempo, incluyendo los cambios de configuración a nivel de pool que los snapshots no pueden capturar. Rebobinar a un checkpoint con zpool import --rewind-to-checkpoint deshace todo lo que sucedió después de tomarlo, como habilitar características del pool, añadir o eliminar vdevs, o destruir datasets. Un pool tiene como máximo un checkpoint a la vez. Consulte Pool Checkpoints para obtener más detalles.

TRIM

TRIM notifica a los SSD y a otros almacenamientos basados en flash qué bloques ya no utiliza el pool, permitiendo al dispositivo borrarlos por adelantado y mantener el rendimiento de escritura. Ejecute zpool trim manualmente, o establezca la propiedad del pool autotrim en on para hacer trim al espacio liberado de forma continua. Consulte TRIM e Inicialización para obtener más detalles.

Cuota de Dataset

ZFS proporciona una contabilidad rápida y precisa del espacio de datasets, usuarios y grupos, así como cuotas y reservas de espacio. Esto otorga al administrador un control detallado sobre la asignación de espacio y permite reservar espacio para sistemas de archivos críticos.

ZFS soporta diferentes tipos de cuotas: la cuota de dataset, la cuota de referencia (refquota), la cuota de usuario, y la cuota de grupo.

Las cuotas limitan el tamaño total de un dataset y sus descendientes, incluyendo los snapshots del dataset, los datasets hijos y los snapshots de esos datasets.

Los volúmenes no soportan cuotas, ya que la propiedad volsize actúa como una cuota implícita.

Cuota de Referencia

Una cuota de referencia limita la cantidad de espacio que un dataset puede consumir al imponer un límite estricto. Este límite estricto incluye el espacio referenciado únicamente por el dataset y no incluye el espacio utilizado por los descendientes, como sistemas de archivos o snapshots.

Cuota de Usuario

Las cuotas de usuario son útiles para limitar la cantidad de espacio utilizado por el usuario especificado.

Cuota de Grupo

La cuota de grupo limita la cantidad de espacio que un grupo especificado puede consumir.

Reserva de Dataset

La propiedad reservation hace posible garantizar una cantidad de espacio para un dataset específico y sus descendientes. Esto significa que establecer una reserva de 10 GB en storage/home/bob evita que otros datasets utilicen todo el espacio libre, reservando al menos 10 GB de espacio para este dataset. A diferencia de una refreservation normal, el espacio utilizado por los snapshots y los datasets descendientes sí cuenta para la reserva.

Las reservas de cualquier tipo son útiles en situaciones como la planificación y prueba de la idoneidad de la asignación de espacio en disco en un sistema nuevo, o para asegurar que haya suficiente espacio disponible en los sistemas de archivos para registros de audio o procedimientos y archivos de recuperación del sistema.

Reserva de Referencia

La propiedad refreservation hace posible garantizar una cantidad de espacio para el uso de un dataset específico excluyendo a sus descendientes. Esto significa que al establecer una reserva de 10 GB en storage/home/bob, y otro dataset intenta utilizar el espacio libre, se reservan al menos 10 GB de espacio para este dataset. En contraste con una reserva normal, el espacio utilizado por los snapshots y los datasets descendientes no se cuenta para la reserva. Por ejemplo, si se toma un snapshot de storage/home/bob, debe existir suficiente espacio en disco aparte de la cantidad de refreservation para que la operación tenga éxito. Los descendientes del dataset principal no se cuentan en la cantidad de refreservation y, por lo tanto, no invaden el espacio establecido.

Entorno de Arranque

Un entorno de arranque es un clon arrancable de los datasets que contienen el sistema FreeBSD, gestionado con bectl(8). Crear un entorno de arranque antes de una actualización del sistema hace posible arrancar el sistema anterior y funcional desde el menú del cargador si la actualización causa problemas. Consulte Entornos de Arranque para obtener más detalles.

Resilver

Al reemplazar un disco fallido, ZFS debe llenar el nuevo disco con los datos perdidos. El resilvering es el proceso de escribir esos datos en el dispositivo de reemplazo: los espejos hacen resilver copiando los datos de los miembros supervivientes, mientras que RAID-Z los reconstruye a partir de la información de paridad distribuida en las unidades restantes. A diferencia de una reconstrucción RAID tradicional, el resilvering copia únicamente los datos asignados en lugar de cada sector del dispositivo. Un resilver secuencial (zpool attach -s o zpool replace -s) reconstruye los vdevs de espejo y dRAID aún más rápido copiando los bloques en el orden del disco, omitiendo la verificación de la suma de comprobación y posponiéndola para un scrub programado automáticamente. Consulte Manejo de Dispositivos Fallidos para obtener más detalles.

Online

Un pool o vdev en el estado Online tiene sus dispositivos miembros conectados y completamente operativos. Los dispositivos individuales en el estado Online están funcionando.

Offline

El administrador pone los dispositivos individuales en un estado Offline si existe suficiente redundancia para evitar poner el pool o vdev en un estado Faulted. Un administrador puede elegir poner un disco en offline como preparación para reemplazarlo, o para que sea más fácil de identificar.

Degraded

Un pool o vdev en el estado Degraded tiene uno o más discos que desaparecieron o fallaron. El pool sigue siendo utilizable, pero si otros dispositivos fallan, el pool puede volverse irrecuperable. Reconectar los dispositivos faltantes o reemplazar los discos fallidos devolverá el pool a un estado Online después de que el dispositivo reconectado o nuevo haya completado el proceso de Resilver.

Faulted

Un pool o vdev en el estado Faulted ya no está operativo. Acceder a los datos ya no es posible. Un pool o vdev entra en el estado Faulted cuando el número de dispositivos faltantes o fallidos excede el nivel de redundancia en el vdev. Si se reconectan los dispositivos faltantes, el pool regresará a un estado Online. Una redundancia insuficiente para compensar el número de discos fallidos provoca la pérdida del contenido del pool y requiere la restauración desde copias de seguridad.

Unavail

Un dispositivo en el estado Unavail no se puede abrir, porque falta o es inaccesible. El pool continúa operando si existe suficiente redundancia para compensar, ejecutándose en un estado Degraded. Si un vdev de nivel superior está en Unavail, acceder al contenido del pool es imposible.

Removed

Un dispositivo en el estado Removed fue desconectado físicamente mientras el sistema estaba en ejecución. La detección de extracción de dispositivos depende del hardware y no está soportada en algunas plataformas. Cuando el dispositivo se reconecta, zfsd(8) lo vuelve a poner en línea; si el dispositivo no regresa, zfsd activa un hot spare disponible en su lugar.