Snapshot sur LVM2


LVM (Linux Volume Manager) est un système de gestion des disques physiques et des périphériques de stockage de masse intégré au noyau Linux. Les outils permettant son utilisation sont packagés sous la majeur partie des distributions.

Une fois le système en place Linux Volume Manager permet depuis la version 2 de l’outil de créer des « snapshots » de partition accessibles en lecture écriture. Cette technique permet de conserver des instantanés de l’état d’une partition LVM à un moment « t ».

Pré-requis

Pour utiliser la fonctionnalité de snapshot, il est nécessaire de disposer des outils lvm (paquagés sur la plupart des distributions), du support de lvm dans votre kernel ainsi que du support des snapshot lvm fournit par le module « DM_SNAPSHOT » activé sous le nom « Snapshot target » dans la configuration du kernel :

Device Drivers  --->
   [*] Multiple devices driver support (RAID and LVM)  --->
      ...
      <*>   Device mapper support
      ...
      <*>     Snapshot target
      ...

Le banc de test

Pour les tests, partons d’un système LVM composé de trois périphériques de loop (voir Utiliser les périphériques de loop) d’environs 100M appartenant au groupe de volumes « vgtest » et contenant un volume logique « part-test » de « 120M » formaté en « xfs » et contenant une cinquantaire de fichiers.

Création des périphériques de blocs :

fhh@mafalda ~/tests/lvm $ sudo losetup -a
/dev/loop/0: [0803]:6177 (/usr/portage.container)
fhh@mafalda ~/tests/lvm $ for i in {1..3} ; do \
> dd if=/dev/zero of=hd.$i bs=1024 count=102400
> sudo losetup /dev/loop$i ./hd.$i ;
> done
102400+0 records in
102400+0 records out
104857600 bytes (105 MB) copied, 0,478475 s, 219 MB/s
102400+0 records in
102400+0 records out
104857600 bytes (105 MB) copied, 0,616529 s, 170 MB/s
102400+0 records in
102400+0 records out
104857600 bytes (105 MB) copied, 0,561478 s, 187 MB/s
fhh@mafalda ~/tests/lvm $ sudo losetup -a
/dev/loop/0: [0803]:6177 (/usr/portage.container)
/dev/loop/1: [fd00]:8077588 (/home/fhh/tests/lvm/hd.1)
/dev/loop/2: [fd00]:8077589 (/home/fhh/tests/lvm/hd.2)
/dev/loop/3: [fd00]:8077579 (/home/fhh/tests/lvm/hd.3)
fhh@mafalda ~/tests/lvm $ ls -lh
total 301M
-rw-r--r-- 1 fhh users 100M 2009-10-18 21:14 hd.1
-rw-r--r-- 1 fhh users 100M 2009-10-18 21:14 hd.2
-rw-r--r-- 1 fhh users 100M 2009-10-18 21:14 hd.3
fhh@mafalda ~/tests/lvm $

Préparation des disques à l’utilisation dans LVM :

fhh@mafalda ~/tests/lvm $ sudo pvcreate /dev/loop{1..3} 
  Physical volume "/dev/loop1" successfully created
  Physical volume "/dev/loop2" successfully created
  Physical volume "/dev/loop3" successfully created

Création du groupe de volume :

fhh@mafalda ~/tests/lvm $ sudo vgcreate vgtest /dev/loop{1,2}
  Volume group "vgtest" successfully created
fhh@mafalda ~/tests/lvm $ sudo vgextend vgtest /dev/loop3
  Volume group "vgtest" successfully extended

Création du volume logique « part-test », formatage et création des fichiers :

fhh@mafalda ~/tests/lvm $ sudo lvcreate -L 110M -n part-test vgtest
  Rounding up size to full physical extent 112,00 MB
  Logical volume "part-test" created
fhh@mafalda ~/tests/lvm $ sudo mkfs.xfs /dev/vgtest/part-test
meta-data=/dev/vgtest/part-test  isize=256    agcount=4, agsize=7168 blks
         =                       sectsz=512   attr=2
data     =                       bsize=4096   blocks=28672, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0
log      =internal log           bsize=4096   blocks=1200, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=0
realtime =none                   extsz=4096   blocks=0, rtextents=0
fhh@mafalda ~/tests/lvm $ mkdir mount
fhh@mafalda ~/tests/lvm $ sudo mount /dev/vgtest/part-test mount/
fhh@mafalda ~/tests/lvm $ df -h
Filesystem            Size  Used Avail Use% Mounted on
...
/dev/mapper/vgtest-part--test
                      108M  4,2M  104M   4% /home/fhh/tests/lvm/mount
fhh@mafalda ~/tests/lvm $ sudo su
mafalda lvm # for i in {0..50} ; do touch mount/fic.$i ; done
mafalda lvm # ls mount/
fic.0   fic.14  fic.2   fic.25  fic.30  fic.36  fic.41  fic.47  fic.7
fic.1   fic.15  fic.20  fic.26  fic.31  fic.37  fic.42  fic.48  fic.8
fic.10  fic.16  fic.21  fic.27  fic.32  fic.38  fic.43  fic.49  fic.9
fic.11  fic.17  fic.22  fic.28  fic.33  fic.39  fic.44  fic.5
fic.12  fic.18  fic.23  fic.29  fic.34  fic.4   fic.45  fic.50
fic.13  fic.19  fic.24  fic.3   fic.35  fic.40  fic.46  fic.6
mafalda lvm # exit

Ah mince… j’avais dis « 120M en xfs » … :

fhh@mafalda ~/tests/lvm $ sudo lvextend -L+8M /dev/vgtest/part-test
  Extending logical volume part-test to 120,00 MB
  Logical volume part-test successfully resized
fhh@mafalda ~/tests/lvm $ sudo xfs_growfs mount/
meta-data=/dev/mapper/vgtest-part--test isize=256    agcount=4, agsize=7168
blks
         =                       sectsz=512   attr=2
data     =                       bsize=4096   blocks=28672, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0
log      =internal               bsize=4096   blocks=1200, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=0
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 28672 to 30720
fhh@mafalda ~/tests/lvm $ df -h
Filesystem            Size  Used Avail Use% Mounted on
...
/dev/mapper/vgtest-part--test
                      116M  4,2M  112M   4% /home/fhh/tests/lvm/mount

Mise en place

Afin de créer un snapshot de partition nous devons spécifier la dimension de cette « sauvegarde ». C’est là que réside toute la difficulté de l’exercice.

Cette taille correspond a la taille maximale des changements (fichiers modifiés, créé, etc…) entre l’état actuel et l’état sauvegardé.

Pour des machines en production sauvegardées par rsnapshot par exemple (voir Sauvegardes incrémentales avec “rsnapshot”), nous pouvons nous baser sur la différence de taille entre deux sauvegardes incrémentale que nous multiplions par deux par mesure de sécurité.

En bref, si la taille maximale d’une sauvegarde incrémentale quotidienne par rsnapshot est de 10G, nous utiliserons une taille de 20G pour le snapshot LVM.

Une fois cette dimension déterminée, le snapshot est effectué à l’aide d' »lvcreate » :

fhh@mafalda ~/tests/lvm $ sudo lvcreate -s -L 100M -n snap-20091019 /dev/vgtest/part-test
  Logical volume "snap-20091019" created
fhh@mafalda ~/tests/lvm $ sudo lvs
  LV            VG     Attr   LSize   Origin    Snap%  Move Log Copy%  Convert
  part-test     vgtest owi-ao 120,00M                                         
  snap-20091019 vgtest swi-ao 100,00M part-test   2,05

Dans cet exemple, un snapshot de 100M vient d’être créé. Ceci signifie qu’au maximum, 100M de changement peut être effectué sur la partition « /dev/vgtest/part-test ». Au dela, le snapshot ne sera plus valide.

L’instantané du système peut maintenant être monté :

fhh@mafalda ~/tests/lvm $ mkdir yesteday
fhh@mafalda ~/tests/lvm $ sudo mount /dev/vgtest/snap-20091019 yesteday
mount: wrong fs type, bad option, bad superblock on /dev/mapper/vgtest-snap--20091019,
       missing codepage or helper program, or other error
       In some cases useful info is found in syslog - try
       dmesg | tail  or so
fhh@mafalda ~/tests/lvm $ sudo dmesg | tail
Filesystem "dm-2": Disabling barriers, trial barrier write failed
XFS: Filesystem dm-2 has duplicate UUID - can't mount

eh non. Le snapshot est tellement fidèle à l’original qu’il dispose du même UUID (voir Utilisation des UUID des sytèmes de fichiers) … heureusement l’option « nouuid » de mount solutionne ce problème :

fhh@mafalda ~/tests/lvm $ sudo mount -onouuid /dev/vgtest/snap-20091019 yesteday/
fhh@mafalda ~/tests/lvm $ sudo rm mount/fic.{10..30}
fhh@mafalda ~/tests/lvm $ ls mount
fic.0  fic.3   fic.33  fic.36  fic.39  fic.41  fic.44  fic.47  fic.5   fic.7
fic.1  fic.31  fic.34  fic.37  fic.4   fic.42  fic.45  fic.48  fic.50  fic.8
fic.2  fic.32  fic.35  fic.38  fic.40  fic.43  fic.46  fic.49  fic.6   fic.9
fhh@mafalda ~/tests/lvm $ ls yesteday/
fic.0   fic.14  fic.2   fic.25  fic.30  fic.36  fic.41  fic.47  fic.7
fic.1   fic.15  fic.20  fic.26  fic.31  fic.37  fic.42  fic.48  fic.8
fic.10  fic.16  fic.21  fic.27  fic.32  fic.38  fic.43  fic.49  fic.9
fic.11  fic.17  fic.22  fic.28  fic.33  fic.39  fic.44  fic.5
fic.12  fic.18  fic.23  fic.29  fic.34  fic.4   fic.45  fic.50
fic.13  fic.19  fic.24  fic.3   fic.35  fic.40  fic.46  fic.6
fhh@mafalda ~/tests/lvm $  df -h
Filesystem            Size  Used Avail Use% Mounted on
...
/dev/mapper/vgtest-part--test
                      116M  4,2M  112M   4% /home/fhh/tests/lvm/mount
/dev/mapper/vgtest-snap--20091019
                      116M  4,2M  112M   4% /home/fhh/tests/lvm/yesteday

La restauration des fichiers perdu accidentellement revient alors à effectuer une simple copie des fichiers de la veille sur la partition courante.

Il est possible de suivre l’encombrement du snapshot par la commande « lvs » :

fhh@mafalda ~/tests/lvm $ sudo lvs
  LV            VG     Attr   LSize   Origin    Snap%  Move Log Copy%  Convert
  part-test     vgtest owi-ao 120,00M
  snap-20091019 vgtest swi-ao 100,00M part-test   2,05
fhh@mafalda ~/tests/lvm $ sudo dd if=/dev/zero of=mount/grosfichier bs=1024 count=51200
51200+0 records in
51200+0 records out
52428800 bytes (52 MB) copied, 0,139865 s, 375 MB/s
fhh@mafalda ~/tests/lvm $ sudo lvs
  LV            VG     Attr   LSize   Origin    Snap%  Move Log Copy%  Convert
  part-test     vgtest owi-ao 120,00M                                         
  snap-20091019 vgtest swi-ao 100,00M part-test  52,26

Note complémentaire

Dans le cas de snapshot de partition en constante modification, il est préférable de geler les modifications du système de fichier avant de lancer le (très rapide) snapshot. Sur une partition « xfs » lvm2 effectue cette action automatiquement, si nous devions le faire manuellement, nous aurrions :

mafalda lvm # xfs_freeze -f mount/
mafalda lvm # lvcreate -s -L 100M -n snap-20091019 /dev/vgtest/part-test
  Logical volume "snap-20091019" created
mafalda lvm # xfs_freeze -u mount/

Nettoyage des tests

Pour nettoyer les essais réalisés :

  • démonter les systèmes de fichiers,
  • supprimer les volumes lvm,
  • supprimer le groupe de volume,
  • supprimer les associations de loop,
  • enfin supprimer le répertoire de test.
mafalda lvm # umount {mount,yesteday}
mafalda lvm # lvremove /dev/vgtest/snap-20091019 
  Do you really want to remove active logical volume "snap-20091019"? [y/n]: y
  Logical volume "snap-20091019" successfully removed
mafalda lvm # lvremove /dev/vgtest/part-test 
  Do you really want to remove active logical volume "part-test"? [y/n]: y
  Logical volume "part-test" successfully removed
mafalda lvm # vgremove vgtest
  Volume group "vgtest" successfully removed
mafalda lvm # losetup -d /dev/loop1
mafalda lvm # losetup -d /dev/loop2
mafalda lvm # losetup -d /dev/loop3
mafalda lvm # cd ..
mafalda tests # rm -rf lvm

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *