Sistemas de ficheros Btrfs
Introducción
Btrfs es un sistema de archivos copy-on-write anunciado por Oracle Corporation para GNU/Linux.
Su objetivo es sustituir al actual sistema de archivos ext4, eliminando el mayor número de sus limitaciones, en especial con el tamaño máximo de los ficheros; además de la adopción de nuevas tecnologías no soportadas por ext3. Se afirma también que se “centrará en la tolerancia a fallos, reparación y fácil administración”.
En este post crearemos un escenario vagrant con una maquina que incluya varios discos y a traves de varias pruebas comprobaremos el funcionamiento y rendimiento de btrfs.
Escenario
El escenario con el que contamos para esta practica es el de una maquina virtual con sistema operativo debían 10 creada con vagrant con 4 discos adicionales en el que se instalara un Raid5 usando los 3 primeros discos, y el ultimo disco se dejara para posteriormente comprobar sustituciones de discos simulando fallos.
vagrant@Btrfs:~$ lsblk -f
NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
sda
├─sda1 ext4 983742b1-65a8-49d1-a148-a3865ea09e24 16.1G 7% /
├─sda2
└─sda5 swap 04559374-06db-46f1-aa31-e7a4e6ec3286 [SWAP]
sdb
sdc
sdd
sde
- Instalamos Btrfs.
sudo apt install btrfs-tools
Pruebas con Btrfs
- Gestión de un solo disco btrfs:
Creamos un sistema de ficheros btrfs sobre un solo disco (también se puede hacer sobre una partición):
mffs.btrfs /dev/sdb
vagrant@Btrfs:~$ sudo mkfs.btrfs /dev/sdb
btrfs-progs v4.20.1
See http://btrfs.wiki.kernel.org for more information.
Label: (null)
UUID: 5bf5fcf2-e41a-44f7-891e-afd10e40b898
Node size: 16384
Sector size: 4096
Filesystem size: 1.00GiB
Block group profiles:
Data: single 8.00MiB
Metadata: DUP 51.19MiB
System: DUP 8.00MiB
SSD detected: no
Incompat features: extref, skinny-metadata
Number of devices: 1
Devices:
ID SIZE PATH
1 1.00GiB /dev/sdb
Comprobación:
vagrant@Btrfs:~$ lsblk -f
NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
sda
├─sda1 ext4 983742b1-65a8-49d1-a148-a3865ea09e24 16.1G 7% /
├─sda2
└─sda5 swap 04559374-06db-46f1-aa31-e7a4e6ec3286 [SWAP]
sdb btrfs 0113a314-9022-4668-886d-3f4fc4f7700d
sdc
sdd
sde
- Gestión de múltiples discos (pool de almacenamiento)
mkfs.btrfs /dev/sdb /dev/sdc
vagrant@Btrfs:~$ sudo mkfs.btrfs -f /dev/sdb /dev/sdc
btrfs-progs v4.20.1
See http://btrfs.wiki.kernel.org for more information.
Label: (null)
UUID: 717e0d5d-3322-4f91-a528-d1540d9fc52d
Node size: 16384
Sector size: 4096
Filesystem size: 3.00GiB
Block group profiles:
Data: RAID0 307.12MiB
Metadata: RAID1 153.56MiB
System: RAID1 8.00MiB
SSD detected: no
Incompat features: extref, skinny-metadata
Number of devices: 2
Devices:
ID SIZE PATH
1 1.00GiB /dev/sdb
2 2.00GiB /dev/sdc
Comprobación:
vagrant@Btrfs:~$ lsblk -f
NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
sda
├─sda1 ext4 983742b1-65a8-49d1-a148-a3865ea09e24 16.1G 7% /
├─sda2
└─sda5 swap 04559374-06db-46f1-aa31-e7a4e6ec3286 [SWAP]
sdb btrfs 717e0d5d-3322-4f91-a528-d1540d9fc52d
sdc btrfs 717e0d5d-3322-4f91-a528-d1540d9fc52d
sdd
sde
vagrant@Btrfs:~$ sudo mount /dev/sdb /mnt/
vagrant@Btrfs:~$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 227M 0 227M 0% /dev
tmpfs 49M 976K 48M 2% /run
/dev/sda1 19G 1.4G 17G 8% /
tmpfs 242M 0 242M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 242M 0 242M 0% /sys/fs/cgroup
tmpfs 49M 0 49M 0% /run/user/1000
/dev/sdb 3.0G 17M 1.7G 1% /mnt
Cuando gestionamos varios discos, las capacidades de estos se agregan formando un pool de almacenamiento, es decir que si contamos con un disco de 2 GB y uno de 4 GB, obtendremos un pool de 6 GB.
- Configuramos los discos en RAID, haciendo pruebas de fallo de algún disco y haciendo sustitución y restauración del RAID comparando las ventajas e inconvenientes respecto al uso de RAID software con mdadm.
Una de las ventajas que tiene el uso de un raid con btrfs respecto a mdadm, es que btrfs gestiona el uso de almacenamiento lo que permite que no se desperdicie espacio en disco, al contrario que con mdadm que en el caso de tener distintos discos con distintas capacidades, limita la capacidad de almacenaje a la del disco mas pequeño, es decir si tenemos un disco de 1GB y dos de 2GB con mdadm solo seremos capaces de almacenar un máximo de 1GB por lo que en los otros discos estamos desaprovechando espacio.
Btrfs por otro lado gestiona los discos de forma que la información que se almacena se va repartiendo entre los distintos discos por lo que permite utilizar la máxima capacidad de cada disco que tengamos.
Btrfs soporta actualmente raid 0, raid 1, raid 10, raid 5, raid 6 y single, sin embargo, raid 5 y 6 al ser los mas recientes contienen algunos bugs que impiden el correscto funcionamiento de alguna de sus funciones.
Creación de raid5 con btrfs:
vagrant@Btrfs:~$ sudo mkfs.btrfs -d raid5 -m raid5 -f /dev/sdb /dev/sdc /dev/sdd
btrfs-progs v4.20.1
See http://btrfs.wiki.kernel.org for more information.
Label: (null)
UUID: 0ad6fabb-6a4b-4f2b-ba33-54086764dba1
Node size: 16384
Sector size: 4096
Filesystem size: 7.00GiB
Block group profiles:
Data: RAID5 477.75MiB
Metadata: RAID5 477.75MiB
System: RAID5 16.00MiB
SSD detected: no
Incompat features: extref, raid56, skinny-metadata
Number of devices: 3
Devices:
ID SIZE PATH
1 1.00GiB /dev/sdb
2 2.00GiB /dev/sdc
3 4.00GiB /dev/sdd
vagrant@Btrfs:~$ sudo btrfs filesystem show
Label: none uuid: 0ad6fabb-6a4b-4f2b-ba33-54086764dba1
Total devices 3 FS bytes used 128.00KiB
devid 1 size 1.00GiB used 485.75MiB path /dev/sdb
devid 2 size 2.00GiB used 485.75MiB path /dev/sdc
devid 3 size 4.00GiB used 485.75MiB path /dev/sdd
Montamos uno de los discos del raid y comprobamos su capacidad actual:
vagrant@Btrfs:~$ sudo mount /dev/sdb /mnt/
vagrant@Btrfs:~$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 227M 0 227M 0% /dev
tmpfs 49M 1.6M 47M 4% /run
/dev/sda1 19G 1.4G 17G 8% /
tmpfs 242M 0 242M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 242M 0 242M 0% /sys/fs/cgroup
tmpfs 49M 0 49M 0% /run/user/1000
/dev/sdb 7.0G 17M 6.1G 1% /mnt
Haciendo uso de las opciones -d y -m lo que conseguimos es indicar que tanto los datos como los metadatos, se almacenen de forma redundante en varios discos de forma que el raid sea tolerante a fallos.
En este caso practico, comprobamos que el disco de nuestro raid montado, tiene como capacidad máxima de almacenamiento, la suma del almacenamiento de los discos usados, es decir 7GB, aunque solo estan libres 6,1 dado que los 900M restantes pasan a convertirse en grupos de bloques para datos y metadatos, 477MB en los dos primeros discos.
Para comprobar el estado de los discos, btrfs raid cuenta con la función scrub (función no habilitada en sistemas ubuntu):
iniciar scrub → btrfs scrub start ‘punto de montaje’ ver estado → btrfs scrub status ‘punto de montaje’ desactivar scrub → btrfs scrub cancel ‘punto de montaje’
Ejemplo:
vagrant@Btrfs:~$ sudo btrfs scrub start /dev/sdb
scrub started on /dev/sdb, fsid 0ad6fabb-6a4b-4f2b-ba33-54086764dba1 (pid=1223)
vagrant@Btrfs:~$ sudo btrfs scrub status /dev/sdb
scrub status for 0ad6fabb-6a4b-4f2b-ba33-54086764dba1
scrub started at Sat Jan 16 11:02:40 2021 and finished after 00:00:00
total bytes scrubbed: 0.00B with 0 errors
Como vemos, nuestro disco recién montado no cuenta con errores.
En caso de que algun disco falle, se podrá intentar recuperar ejecutando el siguiente comando, para ello el disco debe estar montado:
mount -o recovery /dev/sdb /mnt/
En caso de ser necesario sustituir alguno de los discos se hará ejecutando los siguientes pasos:
1- Agregar disco nuevo (para ello el sistema de ficheros debe estar montado)
vagrant@Btrfs:~$ sudo btrfs device add /dev/sde /mnt/
vagrant@Btrfs:~$ lsblk -f
NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
sda
├─sda1 ext4 983742b1-65a8-49d1-a148-a3865ea09e24 16.1G 7% /
├─sda2
└─sda5 swap 04559374-06db-46f1-aa31-e7a4e6ec3286 [SWAP]
sdb btrfs 0ad6fabb-6a4b-4f2b-ba33-54086764dba1 6.6G 0% /mnt
sdc btrfs 0ad6fabb-6a4b-4f2b-ba33-54086764dba1
sdd btrfs fcb1c3b8-5929-49a7-9439-e69b8ad306be
sde
vagrant@Btrfs:~$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 227M 0 227M 0% /dev
tmpfs 49M 1.6M 47M 4% /run
/dev/sda1 19G 1.4G 17G 8% /
tmpfs 242M 0 242M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 242M 0 242M 0% /sys/fs/cgroup
tmpfs 49M 0 49M 0% /run/user/1000
/dev/sdb 8.0G 17M 6.6G 1% /mnt
2- Comprobar el uso del disco a sustituir, en este caso vamos a sustituir como ejemplo el disco /dev/sdd:
vagrant@Btrfs:~$ sudo btrfs filesystem show
Label: none uuid: 0ad6fabb-6a4b-4f2b-ba33-54086764dba1
Total devices 4 FS bytes used 256.00KiB
devid 1 size 1.00GiB used 637.75MiB path /dev/sdb
devid 2 size 2.00GiB used 637.75MiB path /dev/sdc
devid 3 size 4.00GiB used 637.75MiB path /dev/sdd
devid 4 size 1.00GiB used 0.00B path /dev/sde
Comprobamos de esta forma que el disco sde se agrego correctamente.
3- Eliminar disco:
vagrant@Btrfs:~$ sudo btrfs device delete /dev/sdd /mnt/
vagrant@Btrfs:~$ sudo btrfs filesystem show
Label: none uuid: 0ad6fabb-6a4b-4f2b-ba33-54086764dba1
Total devices 3 FS bytes used 320.00KiB
devid 1 size 1.00GiB used 368.00MiB path /dev/sdb
devid 2 size 2.00GiB used 368.00MiB path /dev/sdc
devid 4 size 1.00GiB used 368.00MiB path /dev/sde
vagrant@Btrfs:~$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 227M 0 227M 0% /dev
tmpfs 49M 1.6M 47M 4% /run
/dev/sda1 19G 1.4G 17G 8% /
tmpfs 242M 0 242M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 242M 0 242M 0% /sys/fs/cgroup
tmpfs 49M 0 49M 0% /run/user/1000
/dev/sdb 4.0G 17M 3.4G 1% /mnt
4- Balanceo de datos → Para cuando agregamos un disco nuevo y queremos distribuir la información existente entre todos los discos.
vagrant@Btrfs:~$ sudo btrfs balance start --full-balance /mnt/
Done, had to relocate 3 out of 3 chunks
vagrant@Btrfs:~$ sudo btrfs filesystem show
Label: none uuid: 0ad6fabb-6a4b-4f2b-ba33-54086764dba1
Total devices 3 FS bytes used 256.00KiB
devid 1 size 1.00GiB used 368.00MiB path /dev/sdb
devid 2 size 2.00GiB used 368.00MiB path /dev/sdc
devid 4 size 1.00GiB used 368.00MiB path /dev/sde
Como podemos comprobar, el disco sde ya no tiene 0B, sino 368MB.
Funcionamiento de las principales funcionalidades btrfs
- Compresión al vuelo:
Con la compresión activa o al vuelo, los bloques se comprimen antes de escribirse y se descomprimen de manera automática en las lecturas, de este modo las aplicaciones simplemente se dedican a escribir/leer en el sistema de archivos pero se ahorra espacio en disco. La desventaja que tiene esta funcionalidad es que ahorramos espacio, pero sin embargo aumentamos el uso de CPU.
vagrant@Btrfs:~$ sudo mount -o compress=zlib /dev/sde /mnt/
vagrant@Btrfs:~$ sudo dd if=/dev/zero of=/mnt/fichero_pruebas
dd: writing to '/mnt/fichero_pruebas': No space left on device
3534154+0 records in
3534153+0 records out
1809486336 bytes (1.8 GB, 1.7 GiB) copied, 11.3729 s, 159 MB/s
Podemos comprobar que al comprimir podemos almacenar mas datos de lo normal, excediendo la capacidad del disco que en este caso es de 1 GB.
vagrant@Btrfs:~$ ls -lh /mnt/
total 1.7G
-rw-r--r-- 1 root root 1.7G Jan 16 11:36 fichero_pruebas
vagrant@Btrfs:~$ sudo btrfs filesystem show /mnt/
Label: none uuid: 0ad6fabb-6a4b-4f2b-ba33-54086764dba1
Total devices 3 FS bytes used 1.69GiB
devid 1 size 1.00GiB used 1023.00MiB path /dev/sdb
devid 2 size 2.00GiB used 1023.00MiB path /dev/sdc
devid 4 size 1.00GiB used 1023.00MiB path /dev/sde
- CoW (copy on write):
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 con el comando cp debemos indicarle el parámetro –reflink=always.
vagrant@Btrfs:/mnt$ sudo cp --reflink=always fichero_pruebas copia_fichero_prueba
vagrant@Btrfs:/mnt$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 227M 0 227M 0% /dev
tmpfs 49M 1.6M 47M 4% /run
/dev/sda1 19G 1.4G 17G 8% /
tmpfs 242M 0 242M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 242M 0 242M 0% /sys/fs/cgroup
tmpfs 49M 0 49M 0% /run/user/1000
/dev/sdb 4.0G 1.8G 1.1G 64% /mnt
- Snapshots de subvolumenes:
Para usar las snapshots, previamente hemos tenido que crear subvolumenes, en este caso como ejemplo, se han creado 4:
vagrant@Btrfs:~$ sudo btrfs subvolume create /mnt/subv1
Create subvolume '/mnt/subv1'
vagrant@Btrfs:~$ sudo btrfs subvolume create /mnt/subv2
Create subvolume '/mnt/subv2'
vagrant@Btrfs:~$ sudo btrfs subvolume create /mnt/subv3
Create subvolume '/mnt/subv3'
vagrant@Btrfs:~$ sudo btrfs subvolume create /mnt/subv4
Create subvolume '/mnt/subv4'
Listamos los volúmenes creados:
vagrant@Btrfs:~$ sudo btrfs subvolume list /mnt/
ID 266 gen 68 top level 5 path subv1
ID 267 gen 69 top level 5 path subv2
ID 268 gen 70 top level 5 path subv3
ID 269 gen 71 top level 5 path subv4
Para trabajar con estos subvolumenes, necesitaremos conocer su ID, para ello ejecutamos el siguiente comando:
vagrant@Btrfs:~$ sudo btrfs subvolume show /mnt/subv1
subv1
Name: subv1
UUID: c7a28a90-eb88-054b-bb41-0276b7791311
Parent UUID: -
Received UUID: -
Creation time: 2021-01-16 12:06:54 +0000
Subvolume ID: 266
Generation: 68
Gen at creation: 68
Parent ID: 5
Top level ID: 5
Flags: -
Snapshot(s):
De esta forma vemos algunos datos del subvolumen creado como la ID, fecha de creación o incluso si ese subvolumen cuenta con laguna snapshot.
Montamos el subvolumen creado, en este caso por ejemplo el subvolumen1:
vagrant@Btrfs:~$ sudo mount -o subvolid=266 /dev/sdb /home/
vagrant@Btrfs:~$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 227M 0 227M 0% /dev
tmpfs 49M 1.6M 47M 4% /run
/dev/sda1 19G 1.4G 17G 8% /
tmpfs 242M 0 242M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 242M 0 242M 0% /sys/fs/cgroup
tmpfs 49M 0 49M 0% /run/user/1000
/dev/sdb 4.0G 1.8G 1.1G 64% /mnt
/dev/sdb 4.0G 1.8G 1.1G 64% /home
Creamos varios ficheros dentro del subvolumen1 y creamos una snapshot:
vagrant@Btrfs:~$ sudo btrfs subvolume snapshot /mnt/subv1/ /mnt/snapshot_subv1
Create a snapshot of '/mnt/subv1/' in '/mnt/snapshot_subv1'
vagrant@Btrfs:/mnt/subv1$ ls -l /mnt/
total 3534160
-rw-r--r-- 1 root root 1809486336 Jan 16 11:47 copia_fichero_prueba
-rw-r--r-- 1 root root 1809486336 Jan 16 11:36 fichero_pruebas
drwxr-xr-x 1 root root 10 Jan 16 13:18 snapshot_subv1
drwxr-xr-x 1 root root 1582 Jan 16 13:17 subv1
drwxr-xr-x 1 root root 0 Jan 16 12:06 subv2
drwxr-xr-x 1 root root 0 Jan 16 12:06 subv3
drwxr-xr-x 1 root root 0 Jan 16 12:07 subv4
-
Cifrado (no incorporado actualmente).
-
Checksum:
Cada bloque, de datos o metadatos, está protegido mediante una suma de verificación CRC32C (en el futuro está planeado añadir otros algoritmos). En cada lectura se comprueba la integridad del bloque y si se detecta un error automáticamente se busca una copia alternativa. Este mecanismo protege la corrupción de bloques particulares.
- Fragmentación:
Uno de los problemas con los que cuenta btrfs es la fragmentacion, por ello es necesario desfragmentar, esto lo hacemos ejecutando el siguiente comando:
vagrant@Btrfs:~$ sudo btrfs filesystem defrag /mnt/subv1/
- Redimensionar discos:
Btrfs permite redimensionar los discos en caliente, de forma que podemos tanto aumentar como reducir el tamaño de un disco:
vagrant@Btrfs:~$ sudo btrfs filesystem show /mnt/
Label: none uuid: 203319dd-9732-49e7-920f-f8019bc30d4a
Total devices 3 FS bytes used 256.00KiB
devid 1 size 1.00GiB used 485.75MiB path /dev/sdb
devid 2 size 2.00GiB used 485.75MiB path /dev/sdc
devid 3 size 4.00GiB used 485.75MiB path /dev/sdd
* Reducir:
vagrant@Btrfs:~$ sudo btrfs filesystem resize -500m /mnt/
Resize '/mnt/' of '-500m'
vagrant@Btrfs:~$ sudo btrfs filesystem show /mnt/
Label: none uuid: 203319dd-9732-49e7-920f-f8019bc30d4a
Total devices 3 FS bytes used 256.00KiB
devid 1 size 524.00MiB used 485.75MiB path /dev/sdb
devid 2 size 2.00GiB used 485.75MiB path /dev/sdc
devid 3 size 4.00GiB used 485.75MiB path /dev/sdd
* Aumentar:
vagrant@Btrfs:~$ sudo btrfs filesystem resize +350m /mnt/
Resize '/mnt/' of '+350m'
vagrant@Btrfs:~$ sudo btrfs filesystem show /mnt/
Label: none uuid: 203319dd-9732-49e7-920f-f8019bc30d4a
Total devices 3 FS bytes used 256.00KiB
devid 1 size 874.00MiB used 485.75MiB path /dev/sdb
devid 2 size 2.00GiB used 485.75MiB path /dev/sdc
devid 3 size 4.00GiB used 485.75MiB path /dev/sdd
Comments