Snapshots con Btrfs

Enviado por Jordi Reñé en Jue, 31/03/2016 - 12:47
Btrfs file system

Introducción

A partir de la versión OpenSUSE 13.2 el sistema de ficheros por defecto es el nuevo Btrfs. Este sistema es el sustituto del ext4. Btrfs, b-tree fs, basado en la funcionalidad copy-on-write y entendido como un “better FS”, aporta rapidez, robustez y muchas posibilidades. Entre ellas la que hoy nos ocupa, los “snapshots”.

El término “snapshot” se utiliza en distintos entornos, y hace mucho tiempo que ha estado disponible. Sin embargo, en estos momentos, el soporte que ofrece Opensuse 13.2 y superiores (ya ha salido la OpenSUSE Leap 34.1) permite aplicarlos para casos de uso muy cotidianos y útiles.

Para probar las bondades de los snapshots, montamos un servidor de pruebas, y creamos una partición de tipo Btrfs.

Tutorial

Formateamos la partición:

miserver /root# cfdisk /dev/sdb
Disk: /dev/sdb
Size: 15 GiB, 16106127360 bytes, 31457280 sectors
Label: dos, identifier: 0x0a20e307

Device       Boot     Start     Sectors      Size      Id Type        
>> /dev/sdb1 2048     31457279  31455232     15G       83 Linux       

Creamos el file system, de tipo Btrfs:

miserver /root# mkfs.btrfs  /dev/sdb1 
btrfs-progs v4.1.2+20151002
See http://btrfs.wiki.kernel.org for more information.

Label:              (null)
UUID:               ffce50d9-ab70-4712-a4d1-8b87b638d655
Node size:          16384
Sector size:        4096
Filesystem size:    15.00GiB
Block group profiles:
 Data:             single            8.00MiB
 Metadata:         DUP               1.01GiB
 System:           DUP              12.00MiB
SSD detected:       no
Incompat features:  extref, skinny-metadata
Number of devices:  1
Devices:
  ID        SIZE  PATH
   1    15.00GiB  /dev/sdb1
miserver /root# 

Montamos el file system y comprobamos que es 'btrfs':

miserver /root# mkdir /mibtrfs
miserver /root# mount /dev/sdb1  /mibtrfs
miserver /root# mount | grep mibt
/dev/sdb1 on /mibtrfs type btrfs (rw,relatime,space_cache,subvolid=5,subvol=/)
miserver /root#

Cada partición de la que queramos mantener snapshots, debe tener una configuración propia. Al iniciar el sistema, no hay ninguna configuración disponible. El sistema nos obliga a tener una configuración por cada partición sobre la que queramos tomar “snapshots”, porque pueden tener parámetros de configuración distintos.

miserver /root# snapper list-configs
Config | Subvolume
-------+----------

Vamos a crear una configuración para mantener los snapshots de nuestra partición /mibtrfs:

miserver /root# snapper -c mibtrfs  create-config /mibtrfs/
miserver /root# snapper list-configs
Config  | Subvolume
--------+----------
mibtrfs | /mibtrfs 
miserver /root#

Dada esta configuración, listamos los snapshots disponibles:

miserver /root# snapper -c mibtrfs list
Type   | # | Pre # | Date | User | Cleanup | Description | Userdata
-------+---+-------+------+------+---------+-------------+---------
single | 0 |       |      | root |         | current     |         

Ahora creamos el primer snapshot:

miserver /root# snapper -c mibtrfs create  --description "snapshot despues de crear el filesystem" 

Volvemos a listar los snapshots disponibles:

miserver /root# snapper -c mibtrfs list
Type   | # | Pre # | Date                     | User | Cleanup | Description                             | Userdata
-------+---+-------+--------------------------+------+---------+-----------------------------------------+---------
single | 0 |       |                          | root |         | current                                 |         
single | 1 |       | Tue Mar 29 17:05:27 2016 | root |         | snapshot despues de crear el filesystem |         
miserver /root# 

Comprobamos si hay diferencias entre el snapshot 1 y el estado actual, y no hay diferencias, porque no ha habido actividad en el file system.

miserver /root# snapper -c mibtrfs  status 1..0
miserver /root# 

Creamos un fichero y comprobaremos otra vez las diferencias. Ahora, nos aparece el fichero nuevo que hemos creado.

miserver /root# touch /mibtrfs/PROVA

miserver /root# snapper -c mibtrfs status 1..0
+..... /mibtrfs/PROVA
miserver /root# 
miserver /root# 

Volvemos a copiar algunos ficheros más y volvemos a comprobar:

cp -a  /usr/lib64/yui/ /mibtrfs/

miserver /root# snapper -c mibtrfs status 1..0
+..... /mibtrfs/PROVA
+..... /mibtrfs/yui
+..... /mibtrfs/yui/libyui-ncurses-pkg.so.7
+..... /mibtrfs/yui/libyui-ncurses-pkg.so.7.0.0
+..... /mibtrfs/yui/libyui-ncurses.so.7
+..... /mibtrfs/yui/libyui-ncurses.so.7.0.0
miserver /root#

Ahora creamos un snapshot:

miserver /root# snapper -c mibtrfs create --description  "PROVA y  libyui creados" 
miserver /root# snapper -c mibtrfs list
Type   | # | Pre # | Date                     | User | Cleanup | Description                             | Userdata
-------+---+-------+--------------------------+------+---------+-----------------------------------------+---------
single | 0 |       |                          | root |         | current                                 |         
single | 1 |       | Tue Mar 29 17:05:27 2016 | root |      | snapshot despues de crear el filesystem |         
single | 2 |       | Wed Mar 30 10:54:18 2016 | root | PROVA y  libyui creados                          |         

Veamos las diferencias entre los 2 snapshots disponibles, y vemos los cambios, que corresponden a los ficheros nuevos. Lo mismo, si hubiéramos hecho borrados y/o modificaciones.

miserver /root# snapper -c mibtrfs status 1..0
+..... /mibtrfs/PROVA
+..... /mibtrfs/yui
+..... /mibtrfs/yui/libyui-ncurses-pkg.so.7
+..... /mibtrfs/yui/libyui-ncurses-pkg.so.7.0.0
+..... /mibtrfs/yui/libyui-ncurses.so.7
+..... /mibtrfs/yui/libyui-ncurses.so.7.0.0

Si los cambios no nos interesan, podríamos volver atrás en el tiempo y restaurar el estado existente en el snapshot número 1:

miserver /root# snapper -c mibtrfs -v undochange 1..2
create:0 modify:0 delete:6
deleting /mibtrfs/yui/libyui-ncurses.so.7.0.0
deleting /mibtrfs/yui/libyui-ncurses.so.7
deleting /mibtrfs/yui/libyui-ncurses-pkg.so.7.0.0
deleting /mibtrfs/yui/libyui-ncurses-pkg.so.7
deleting /mibtrfs/yui
deleting /mibtrfs/PROVA
miserver /root# 

Aparte de los snapshots que se hacen bajo demanda, el sistema, a través del cron y usando la utilidad snapper, va haciendo cada hora, un snapshot de seguridad, a no ser que lo desactivemos explícitamente. Veamos los snapshots disponibles después de varias horas de actividad:

miserver /etc/cron.daily# snapper -c mibtrfs list
Type   | # | Pre # | Date                     | User | Cleanup  | Description                             | Userdata
-------+---+-------+--------------------------+------+----------+-----------------------------------------+---------
single | 0 |       |                          | root |          | current                                 |         
single | 1 |       | Tue Mar 29 17:05:27 2016 | root |          | snapshot despues de crear el filesystem |         
single | 2 |       | Wed Mar 30 10:54:18 2016 | root |          | PROVA y  libyui creados |         
single | 3 |       | Wed Mar 30 11:30:01 2016 | root | timeline | timeline                                |         
single | 4 |       | Wed Mar 30 12:30:01 2016 | root | timeline | timeline                                |         
single | 5 |       | Wed Mar 30 13:30:01 2016 | root | timeline | timeline                                |         
miserver  /etc/cron.daily#

Hemos aplicado los snapshots en una partición de usuario o de datos. OpenSUSE permite el file system Btrfs en la partición root y /usr permitiendo aplicar los beneficios de los snapshots a esta partición. Esto permite que cada vez que hagamos un update de sistema, o cuando hacemos un mantenimiento con resultados desconocidos, podamos hacer un snapshot antes del cambio, para luego poder volver a ese punto de recuperación.

Aplicaciones de los snapshots

  • Deshacer cambios

    En el tutorial que hemos comentado al principio, vemos como deshacer cambios. Con el comando snapper y la opción undochange conseguiremos “retornar” al estado anterior.

  • Recuperar ficheros de snapshots almacenados

    De la misma forma que hemos deshecho completamente los cambios de todo un snapshot, podemos recuperar sólo un fichero contenido en ese snapshot.

    snapper -c   diff SNAPSHOT_ID..0 NOMBRE_FICHERO
  • System rollback

    Una vez comprendemos como se utilizan los snapshots, la idea es no utilizarlos manualmente, si no que sean las aplicaciones las que lo utilizan.

    Por ejemplo, instalando snapper-zypp-plugin, conseguiremos que zypper, cuando instale algún paquete, nos haga un snapshot antes de la instalación, para poder hacer una vuelta atrás en caso de que se haya desconfigurado algo.

    Los snapshots en la partición root prevendrán problemas de arranque. Imaginemos que borramos el fichero /bin/bash, en cuyo caso el sistema no botará. Si hemos tenido la precaución de hacer un snapshot antes de ese borrado, podremos botar usando ese snapshot.
    La secuencia sería:

    snapper create --description "estado correcto” --print-number
    35
    rm /bin/bash
        

    El sistema ahora ya no bota.

    Al botar, añadiremos el siguiente parámetro al kernel:

    rootflags=subvol=.snapshots/35/snapshot

    El sistema botará correctamente.

    Una vez en marcha, ejecutaremos snapper rollback, para hacer efectivo el cambio, y ya podremos rebotar normalmente.

  • Crear snapshots manualmente

    La utilidad principal de los snapshots, es cuando se hacen en la partición root (/) , para tener historia en los directorios /etc, y también cuando los conectamos a la utilidad de instalación de paquetes, zypper.

    Es decir, usados como punto de recuperación a un estado conocido, cuando nos disponemos a realizar cambios.

    Por otro lado, podemos usarlos para tener un backup de ficheros en las particiones de usuario. Esta afirmación hay que matizarla. No es realmente un backup, que nos protege de si se corrompe el file system o el medio. Nos protege ante pérdidas de fichero por parte del usuario.
    Por tanto, un snapshot diario de la partición de usuarios, nos permite poder recuperar rápidamente, un fichero a fecha de ayer. Si guardamos los 2 últimos snapshots, tendremos una memoria de 2 días.

    Hay que tener en cuenta que el snapshot, una vez realizado no consume espacio de disco, solo se trabaja con punteros. El snapshot irá creciendo en base al número de ficheros que cambien.

    Un ciclo útil de snapshots, sería guardar 7 snapshots, uno por día, y reciclarlos a la semana siguiente. Esto, reforzado con un backup semanal total. Pero, recordemos, que el snapshot se almacena en la propia partición, de tal forma, que si se corrompe la partición, el snapshot ya no sería accesible, y no podremos recuperar.

Conclusión

Las nuevas versiones de las distribuciones, entre ellas, openSUSE 13.2, openSUSE Leap 42.1, Ubuntu 14 entre otras, nos ofrecen la posibilidad de trabajar de forma nativa con el file system Btrfs. Este sistema, que usa la funcionalidad “copy_on_write”, permite realizar snapshots, de una forma muy eficiente y robusta. Un snapshot nos ofrece un punto de recuperación al que volver cuando el sistema ha llegado a un punto erróneo.

En el futuro inmediato, habrá que tener en cuenta este sistema, para saber aprovecharlo al máximo. También el file system, Btrfs, dispone de otras funcionalidades que se deberán aprovechar, como son los subvolumes. Por otro lado, tiene que quedar claro que el snapshot no sustituye a la herramienta de backup, solamente la complementa.

 

Síguenos en

Els nostres articles del bloc d'inLab FIB

         
         

inLab FIB incorpora esCert

Icona ESCERT

inLab es miembro de