Funcionalidad de btrfs o «b-tree fs»

Btrfs o «b-tree fs« se trata de un sistema de ficheros de GNU/Linux que intenta ser el relevo de ZFS en servidores. Se ha hecho estable hace ya algún tiempo estando integrado en el núcleo desde la versión 2.6.29.

Podemos decir que es una alternativa a ZFS, ya que hace uso del copy-on-write, permite snapshots, sistemas de archivo multidispositivo, subvolúmenes, además tiene comprobación mediante checksums, compresión al vuelo y optimización para SSD, entre otras cosas.

El objetivo del proyecto de btrfs dejar de lado herramientas como mdadm, lvm, sistemas de integridad de ficheros, etc y tenerlo todo integrado de forma nativa en el sistema de ficheros.

Para ver las funcionalidades que nos otorga, vamos a crear 3 volúmenes en nuestra máquina virtual y los formatearemos con btrfs.

El paquete donde están las funcionalidades del sistema de ficheros es:

# apt install btrfs-tools -y

Y formateamos:

# mkfs.btrfs /dev/vdb /dev/vdc /dev/vdd

RAID:

A la hora de crear el sistema de fichero podemos declarar sistemas RAID: raid0, raid1, raid10, raid5 y raid6.

Para crear el RAID:

# mkfs.btrfs -d raid0 -m raid0 /dev/vdb /dev/vdc

A los RAID podemos añadirles dispositivos de bloques o quitárselos, pero teniendo siempre en cuenta la integridad, es decir, si para que se mantenga una información necesitamos tres discos, antes de quitar alguno de estos tendremos que añadir otro, para que la información se mantenga consistente.

Algunos comandos para la operatoria de dispositivos:

Añadir disco:

btrfs device add /one/device /mnt/btrfs

Eliminar disco:

btrfs device delete /one/device /mnt/btrfs

Actividad del disco:

btrfs device stats /one/device

Vamos a comprobar la capacidad de mantener la integridad de los ficheros en un raid1, vamos a tener un fichero, vamos a llenar un disco de 0 y después vamos a reconstruir el RAID.

mkfs.btrfs -d raid1 -m raid1 /dev/vdb /dev/vdc -f && \
mount /dev/vdb /mnt && cp /etc/passwd /mnt

Ahora vamos llenar el disco vdb y provocar un error para restaurarlo:

root@mickey:~# dd if=/dev/zero of=/dev/vdb
dd: writing to '/dev/vdb': No space left on device
4194305+0 records in
4194304+0 records out
2147483648 bytes (2.1 GB, 2.0 GiB) copied, 472.355 s, 4.5 MB/s

Lo hemos llenado de ceros el disco y si entramos en /mnt:

root@mickey:~# ls /mnt/
passwd

Seguimos teniendo el fichero, pero, ¿habrá cambiado?

root@mickey:~# sha256sum /etc/passwd
d0b05fb5b9e7adf756f02d0778a64866b0099ed29f56b2cd229d604413121e5e /etc/passwd
root@mickey:~# sha256sum /mnt/passwd 
d0b05fb5b9e7adf756f02d0778a64866b0099ed29f56b2cd229d604413121e5e /mnt/passwd

Comprobamos el estado del RAID:

root@mickey:~# btrfs filesystem show
Label: none  uuid: cf078854-7266-40ec-a990-5de7a4ca2b6b
	Total devices 2 FS bytes used 260.00KiB
	devid    1 size 2.00GiB used 417.50MiB path /dev/vdb
	devid    2 size 2.00GiB used 417.50MiB path /dev/vdc

warning, device 1 is missing
Label: none  uuid: 5df72d59-3d5e-474e-aa37-3a95e9ad17e9
	Total devices 2 FS bytes used 112.00KiB
	devid    2 size 2.00GiB used 417.50MiB path /dev/vdd
	*** Some devices missing

Nos dice que el dispositivo /dev/vdb esta en estado «missing», pues bien, vamos a repararlo, para ello solo tenemos que añadir un nuevo disco y eliminar el anterior:

btrfs device add /dev/vdd /mnt -f && \
btrfs device delete /dev/vdb /mnt

Y ahora si comprobamos el estado:

root@mickey:~# btrfs filesystem show
Label: none  uuid: cf078854-7266-40ec-a990-5de7a4ca2b6b
	Total devices 2 FS bytes used 260.00KiB
	devid    2 size 2.00GiB used 704.00MiB path /dev/vdc
	devid    3 size 2.00GiB used 704.00MiB path /dev/vdd

Integridad de datos:

Otra de las funcionalidad que tiene btrfs es la integridad de los datos en su interior, para ello podemos programar un scrub cuando haya poca carga en el servidor.

Esta operación lleva a cabo la comprobación de todos los bloques de los ficheros de un disco y en caso de algún fallo recurre a la copia de ese fichero para subsanarlo.

btrfs scrub start /lugar/montaje

Y podemos comprobar como va el proceso:

btrfs scrub status /lugar/montaje

Compresión al vuelo:

Una de las características más interesantes que nos proporciona este sistema de ficheros es la compresión al vuelo, es decir, que al guardar un fichero, este se guarda comprimido, pero en la lectura se descomprime. Esta opción se activa al montar el disco.

mount /dev/vdc /mnt -o compress=lzo

En mi caso tengo un raid1 de dos discos de 2GB y mirad el resultado que me ha dado introduciendo ficheros:

root@mickey:/mnt# lsblk -fm
NAME FSTYPE LABEL UUID MOUNTPOINT NAME SIZE OWNER GROUP MODE
vda vda 10G root disk brw-rw----
└─vda1 ext4 4c114b65-2954-4955-a666-b5b8766a5848 / └─vda1 10G root disk brw-rw----
vdb vdb 2G root disk brw-rw----
vdc btrfs cf078854-7266-40ec-a990-5de7a4ca2b6b /mnt vdc 2G root disk brw-rw----
vdd btrfs cf078854-7266-40ec-a990-5de7a4ca2b6b vdd 2G root disk brw-rw----
root@mickey:/mnt# ls
archivo1.txt archivo3.txt archivo5.txt archivo7.txt
archivo2.txt archivo4.txt archivo6.txt passwd
root@mickey:/mnt# du -h
5.4G .
root@mickey:/mnt#

El poder de compresión que tiene nos permite almacenar más información que a priori nos permitiría, según el sistema tenemos 5,4 GiB pero según btrfs:

root@mickey:/mnt# btrfs filesystem show
Label: none uuid: cf078854-7266-40ec-a990-5de7a4ca2b6b
 Total devices 2 FS bytes used 179.23MiB
 devid 2 size 2.00GiB used 704.00MiB path /dev/vdc
 devid 3 size 2.00GiB used 704.00MiB path /dev/vdd

Solo hemos ocupado 704 MiB del valor real.

Multidispositivo o single

En cuanto al sistema de archivos multidispositivo, es lo que hemos visto al principio al formatear varios disco con b-tree pero con la opción -d single esto nos permitirá utilizar ambos disco como si fuera uno, independientemente de la capacidad de almacenamiento:

Si tenemos discos sin asignar sistema de ficheros:

mkfs.btrfs -d single /dev/vdb /dev/vdc

Si tenemos ya discos en producción y queremos ponerlo en single:

btrfs balance start -dconvert=single /punto/montaje

Subvolúmenes y Snapshots

Los subvolúmenes en btrfs se trata de directorios internos del pool que podemos montar en nuestro sistema, dándonos la oportunidad de tener un mismo dispositivo de bloques montado en varias localizaciones. Por ejemplo, podemos tener dos subvolúmenes (sv1 y sv2) y tenerlos montados en /home y en /etc y gracias a la funcionalidad de snapshots que nos proporciona b-tree nos permite tener copias de estos directorios.

Lo primero debemos de tener nuestro dispositivo de bloques b-tree montado en el directorio:

root@mickey:/mnt# lsblk -fm
NAME FSTYPE LABEL UUID MOUNTPOINT NAME SIZE OWNER GROUP MODE
vda vda 10G root disk brw-rw----
└─vda1 ext4 4c114b65-2954-4955-a666-b5b8766a5848 / └─vda1 10G root disk brw-rw----
vdb btrfs b6539178-c6e4-4838-b6f0-bf4017aa2f60 /mnt vdb 2G root disk brw-rw----
vdc btrfs b6539178-c6e4-4838-b6f0-bf4017aa2f60 vdc 2G root disk brw-rw----
vdd ext4 6231683c-1342-4f65-9ced-7af0cdc5b380 vdd 2G root disk brw-rw----

Una vez lo tengamos montado creamos el subvolumen:

btrfs subvolume create /mnt/sv1

Y vemos que se nos crea un directorio, este directorio es nuestro dispositivo y lo vamos a montar sobre /media, para ello necesitamos el ID:

btrfs subvolume list /mnt

Y lo montamos:

mount -o subvolid=268 /dev/vdb /media

Creamos un fichero en /media:

cd /media && touch fichero.txt

Si comprobamos en /mnt/sv1 tenemos también el fichero que hemos creado. Otros comandos útiles con subvolúmenes es saber cual está montado:

btrfs subvolume show /media

Y para eliminarlo:

btrfs subvolume delete /mnt/sv1

A estos subvolúmenes podemos hacerles snapshots por si tuviéramos cualquier error en ellos y quisiéramos recuperarlos, con esto podríamos crear una tarea en programada para tener siempre un snapshot actualizado:

btrfs subvolume snapshot /mnt/sv1 /mnt/sv1.snap

Esto nos generará una copia exacta y para restaurarla:

mv /mnt/sv1.snap /mnt/sv1

Redimensión

Además de todo esto b-tree es redimensionable en caliente tanto aumentar como decrecer:

Decrecer:

btrfs filesystem resize -2g /mnt

Aumentar:

btrfs filesystem resize +1g /mnt

O para coger todo el espacio disponible en disco:

btrfs filesystem resize max /mnt

Recuperación del FS:

Podemos reparar el sistema de ficheros, para ello:

mount -o recovery /dev/vdb /mnt

Copy on Write:

El sistema de copy on write o COW, nos permite tener varios ficheros iguales pero solo ocupando el espacio de uno, esto se produce porque al ser ficheros exactamente iguales las copias del original están referenciadas al original, pero si se produce un cambio, la copia ocupa el tamaño del original más el cambio.

Para utilizar esto en el comando cp debemos indicarle el parámetro –reflink=always. Para ponerlo a prueba en un dispositivo de bloques de 2GB voy a crear un ficheros de 1GB y copiarlo varias veces:

root@mickey:~# cd /mnt && dd if=/dev/zero of=archivo1.txt bs=1024 count=1024000
1024000+0 records in
1024000+0 records out
1048576000 bytes (1.0 GB, 1000 MiB) copied, 14.919 s, 70.3 MB/s
root@mickey:/mnt# ls
archivo1.txt
root@mickey:/mnt# cp --reflink=always archivo1.txt archivo2.txt 
root@mickey:/mnt# cp --reflink=always archivo1.txt archivo3.txt 
root@mickey:/mnt# cp --reflink=always archivo1.txt archivo4.txt 
root@mickey:/mnt# cp --reflink=always archivo1.txt archivo5.txt 
root@mickey:/mnt# cp --reflink=always archivo1.txt archivo6.txt 
root@mickey:/mnt# ls
archivo1.txt archivo3.txt archivo5.txt
archivo2.txt archivo4.txt archivo6.txt
root@mickey:/mnt# ls -lah
total 5.9G
drwxr-xr-x 1 root root 144 Jan 27 17:53 .
drwxr-xr-x 22 root root 4.0K Jan 15 09:22 ..
-rw-r--r-- 1 root root 1000M Jan 27 17:53 archivo1.txt
-rw-r--r-- 1 root root 1000M Jan 27 17:53 archivo2.txt
-rw-r--r-- 1 root root 1000M Jan 27 17:53 archivo3.txt
-rw-r--r-- 1 root root 1000M Jan 27 17:53 archivo4.txt
-rw-r--r-- 1 root root 1000M Jan 27 17:53 archivo5.txt
-rw-r--r-- 1 root root 1000M Jan 27 17:53 archivo6.txt

Fragmentación:

No todo va a ser bueno en btrfs, aquí tenemos el problema de la fragmentación por ello tenemos que desfragmentar:

btrfs filesystem defrag /mnt

Y esto es todo lo más significativo que tiene btrfs un sistema de ficheros versátil que compite con ZFS y que puede que algún día podamos ver dándole el relevo.


Un comentario sobre “Funcionalidad de btrfs o «b-tree fs»

Deja un comentario