Simple LVM Logical volume management Howto
id : i9w95sdkc3
category : computer
blog : unixlinux
created : 02/27/10 - 19:40:33

Terms / Anatomy
  • PV : Physical Volume (A disk, or a partition, a software raid device, ...).
  • VG : Volume groupe (There is one or more PV in a VG, there is one or more LV in a VG).
  • LV : Logical Volume (An LV belongs to a VG, it's the equivalent of a disk partition in a non LVM-System).
  • PE : Physical extend (A PV is divided into chunks of data).
  • LE : Logical extend (A LV is divided into chunks of data : PE sizes are identical in an LV).

Setup a VG

  • First of all be sure you have unsed devices (disk or partitions for example).
  • We have used disk parition in this tutorial, but you can sure use a whole disc on your lvm setup.

  • List devices :
root@lvm# ls /dev/hd*
/dev/hdb  /dev/hdb1  /dev/hdb10  /dev/hdb11  /dev/hdb12  /dev/hdb13  /dev/hdb14  /dev/hdb15  /dev/hdb5	/dev/hdb6  /dev/hdb7  /dev/hdb8  /dev/hdb9


  • Before creating your first lv, pv must be created.

Initialize PVs

  • Create your pv with pvcreate command :
root@lvm# for DISK in `seq 5 15`; do pvcreate /dev/hdb${DISK} ; done
  Physical volume "/dev/hdb5" successfully created
  Physical volume "/dev/hdb6" successfully created
  Physical volume "/dev/hdb7" successfully created
  Physical volume "/dev/hdb8" successfully created
  Physical volume "/dev/hdb9" successfully created
  Physical volume "/dev/hdb10" successfully created
  Physical volume "/dev/hdb11" successfully created
  Physical volume "/dev/hdb12" successfully created
  Physical volume "/dev/hdb13" successfully created
  Physical volume "/dev/hdb14" successfully created
  Physical volume "/dev/hdb15" successfully created


  • You can use pvscan command to see actual pv in use :
root@lvm# pvscan
  PV /dev/hdb5                       lvm2 [49,65 MB]
  PV /dev/hdb6                       lvm2 [49,68 MB]
  PV /dev/hdb7                       lvm2 [49,68 MB]
  PV /dev/hdb8                       lvm2 [49,68 MB]
  PV /dev/hdb9                       lvm2 [49,68 MB]
  PV /dev/hdb10                      lvm2 [49,68 MB]
  PV /dev/hdb11                      lvm2 [49,68 MB]
  PV /dev/hdb12                      lvm2 [49,68 MB]
  PV /dev/hdb13                      lvm2 [49,68 MB]
  PV /dev/hdb14                      lvm2 [49,68 MB]
  PV /dev/hdb15                      lvm2 [49,68 MB]
  Total: 11 [546,45 MB] / in use: 0 [0   ] / in no VG: 11 [546,45 MB]


  • At this point, we have 11PV, 0 in use, and no VG created.

Initialize VGs

We will now create three differents VG :
    • One called logs (/dev/hdb5, /dev/hdb6) (PE : 2M)
    • One called crons (/dev/hdb7, /dev/hdb8) (PE : 4M)
    • One called data (/dev/hdb9, /dev/hdb10, /dev/hdb11, /dev/hdb12) (PE : 8M)

  • Use the vgcreate command to create your VGs :
root@lvm# vgcreate -s 2M logs /dev/hdb5 /dev/hdb6 
  Volume group "logs" successfully created
root@lvm# vgcreate -s 4M crons /dev/hdb7 /dev/hdb8
  Volume group "crons" successfully created
root@lvm# vgcreate -s 8M data /dev/hdb9 /dev/hdb10 /dev/hdb11 
  Volume group "data" successfully created


  • Let's see what we've done at this point, use vgdisplay command :
root@lvm# for VG in 'data logs cron'; do vgdisplay -c ${VG} | awk -F':' '{print "VGNAME:"$1"\t VGSIZE:"$12"\nPESIZE:"$13"\tTOTALPE:"$14"\tUSEDPE:"$15"\tFREEPE:"$16"\nUID:"$17"\nCURPV:"$11"\tACTPV:"$10}'; done

VGNAME:  data	 VGSIZE:147456
PESIZE:8192	TOTALPE:18	USEDPE:0	FREEPE:18
UID:Psn2fr-UiHk-3YEC-UeD4-Dg2G-F2Cs-EMw7uL
CURPV:3	ACTPV:3

VGNAME:  logs	 VGSIZE:98304
PESIZE:2048	TOTALPE:48	USEDPE:0	FREEPE:48
UID:vbMY48-fzbP-c1Mf-jIW4-aQ4j-dTVl-nG85cv
CURPV:2	ACTPV:2

VGNAME:  crons	 VGSIZE:98304
PESIZE:4096	TOTALPE:24	USEDPE:0	FREEPE:24
UID:pDlr6N-MTUE-RO1g-yS3Z-aTpG-Ggn5-pfzgk8
CURPV:2	ACTPV:2


Adding a PV to a VG
  • Oops we forget to add a disk to logs VG !

  • Extend your VGs with vgextend command :
root@lvm# vgextend logs /dev/hdb12
  Volume group "logs" successfully extended


  • Let's see what we've done with the command vgdisplay :
root@lvm# vgdisplay -c logs | awk -F':' '{print "VGNAME:"$1"\t VGSIZE:"$12"\nPESIZE:"$13"\tTOTALPE:"$14"\tUSEDPE:"$15"\tFREEPE:"$16"\nUID:"$17"\nCURPV:"$11"\tACTPV:"$10}' 

VGNAME:  logs	 VGSIZE:147456
PESIZE:2048	TOTALPE:72	USEDPE:0	FREEPE:72
UID:vbMY48-fzbP-c1Mf-jIW4-aQ4j-dTVl-nG85cv
CURPV:3	ACTPV:3


  • We have now three active PVs on logs VG.

  • We can confirm with pvscan command :
root@lvm# pvscan | grep logs
pvscan | grep logs
  PV /dev/hdb5    VG logs            lvm2 [48,00 MB / 48,00 MB free]
  PV /dev/hdb6    VG logs            lvm2 [48,00 MB / 48,00 MB free]
  PV /dev/hdb12   VG logs            lvm2 [48,00 MB / 48,00 MB free]


Removing a PV from an VG
  • First of all we need to be sure our PV is unused.

  • Use pvdisplay to find an PV with no pe allocated :
for $dev in /dev/hdb5 /dev/hdb6 /dev/hdb12; do pvdisplay ${dev} | grep Allocted; done
  Allocated PE          16
  Allocated PE          24
  Allocated PE          0


  • We can now remove /dev/hdb12 from Logs VG with vgreduce command :
root@lvm# vgreduce logs /dev/hdb12
  Removed "/dev/hdb12" from volume group "logs"


  • That's all for PVs

Creating LV
We'll now create three different LV :
  • One called : 80M_Logs (80M) on logs VG.
  • One called : 10PE_Crons (10PE) on crons VG with 2 stripes and stripe size 4 KB.
  • One called : 96M_Data (96M) on data VG using /dev/hdb9 and /dev/hdb11.

  • Use lvcreate to create LVs ;
root@lvm# lvcreate -L80 -n80M_Logs logs
  Logical volume "80M_Logs" created
root@lvm# lvcreate -l10 -i2 -I4 -n10PE_Crons crons
  Logical volume "10PE_Crons" created
root@lvm# lvcreate -L96 -n96M_Data data /dev/hdb9 /dev/hdb11
  Logical volume "96M_Data" created


Removing LV
  • First of all we need to umount our LV.

  • Use umount command to umount your LV.
root@lvm# umount /dev/logs/80M_Logs 


  • And remove it with lvremove command :
root@lvm#  lvremove /dev/logs/80M_Logs
Do you really want to remove active logical volume 80M_Logs? [y/n]: y
  Logical volume "80M_Logs" successfully removed


Extending LV
  • LV must be umounted to be extended.

  • Umount the LV :
root@lvm# umount /dev/crons/10PE_Crons


  • YOU DON'T NEED TO UMOUNT LV TO EXTEND IT JUST RUN LVEXTEND AND RESIZE2FS. Nevertheless kernel with ext2online patch is required

  • Just use the lvextend command to extend your VG, be sure to have free space on VG to extend your VG

  • Extend the lv with lvextend command :
root@lvm# lvextend -L+20M /dev/crons/10PE_Crons
  Using stripesize of last segment 4,00 KB
  Rounding size (15 extents) down to stripe boundary size for segment (14 extents)
  Extending logical volume 10PE_Crons to 56,00 MB
  Logical volume 10PE_Crons successfully resized


  • We're on an ext3 lv, use resize2fs to extend the partition.

  • First of all run an fsck on the partition :
root@lvm# e2fsck -f /dev/crons/10PE_Crons
e2fsck 1.39 (29-May-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/crons/10PE_Crons: 11/10240 files (9.1% non-contiguous), 5902/40960 blocks


  • And use resize2fs command :
[root@localhost mnt]# resize2fs /dev/crons/10PE_Crons 
resize2fs 1.39 (29-May-2006)
Resizing the filesystem on /dev/crons/10PE_Crons to 57344 (1k) blocks.
Le système de fichiers /dev/crons/10PE_Crons a maintenant une taille de 57344 blocs.


  • If you're on an old server for example on a Red Hat 4 and have problems with resize2fs use ext2online command :
[root@localhost mnt]# ext2online /dev/crons/10PE_Crons 
ext2online v1.1.18 - 2001/03/18 for EXT2FS 0.5b


Here's a list of command to resize partition :
  • ext2/ext3 -> resize2fs
  • reiserfs -> resize_reseirfr
  • xfs -> xfs_growfs
  • jfs -> mount -o remount,resize /partition

Reducing LV
  • LV must be unmounted to be reduced.

  • Umount the partition with the umount command :
root@lvm# umount /mnt/crons


  • Resize the partition before reduce your LV. You must EVER resize the filesystem before reducing your LV, whatever is residing on disk :
root@lvm# resize2fs /dev/mapper/crons-10PE_Crons 40960
resize2fs 1.39 (29-May-2006)
Resizing the filesystem on /dev/mapper/crons-10PE_Crons to 40960 (1k) blocks.
Le système de fichiers /dev/mapper/crons-10PE_Crons a maintenant une taille de 40960 blocs.


  • Reduce your lv with lvreduce command :
root@lvm# lvreduce -L-10M /dev/mapper/cron-10PE_Crons
  Rounding up size to full physical extent 8,00 MB
  WARNING: Reducing active logical volume to 48,00 MB
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce 10PE_Crons? [y/n]: y
  Reducing logical volume 10PE_Crons to 48,00 MB
  Logical volume 10PE_Crons successfully resized


lvchange
  • Use lvchange to :

    • desactivate an lv (an)
    • no flag a tells lv is desactivate
root@lvm# lvchange -an /dev/mapper/cron-10PE_Crons
root@lvm# lvs 
  LV         VG    Attr   LSize  Origin Snap%  Move Log Copy%  Convert
  10PE_Crons crons -wi--- 48,00M   


    • activate an lv (ay)
    • flag a tells lv is activate
root@lvm# lvchange -ay /dev/mapper/cron-10PE_Crons
root@lvm# lvs 
  LV         VG    Attr   LSize  Origin Snap%  Move Log Copy%  Convert
  10PE_Crons crons -wi-a- 48,00M    

  • An lv must be unmounted to be activate or desactivate

vgchange
  • Use vgchange to :

    • desactivate a vg (an)
root@lvm# lvchange -an crons


    • activate a vg (ay)
root@lvm# vgchange -ay crons    


lvrename, vgrename
  • Using lvnames with size in it is not a good idea, an lv will always grow or be resized.

  • Use lvrename to rename your lv :
root@lvs# lvrename /dev/crons/10_PEcrons /dev/crons/lvcron
 Renamed "10PE_Crons" to "lvcrons" in volume group "crons"
root@lvs# lvrename /dev/data/96M_Data /dev/data/lvdata
 Renamed "96M_Data" to "lvdata" in volume group "data"


  • You don't need to umount lv to rename it.

  • Use vgrename to rename your vg :
root@lvs# vgrename crons vgcrons
 Volume group "crons" successfully renamed to "vgcrons"
root@lvs# vgrename log vglogs
vgrename logs vglogs
  Volume group "logs" successfully renamed to "vglogs"
root@lvs# vgrename data vgdata
volume group "data" still has active LVs
root@lvs# lvchange -an /dev/data/lvdata
root@lvs# vgrename data lvdata
 Volume group "data" successfully renamed to "vgdata"
root@lvs# vgs
  VG      #PV #LV #SN Attr   VSize   VFree
  vgcrons   2   1   0 wz--n-  96,00M 48,00M
  vgdata    3   1   0 wz--n- 144,00M 48,00M
  vglogs    2   0   0 wz--n-  96,00M 96,00M
root@lvs# lvchange -ay /dev/vgdata/lvdata


  • As you seen you must desactive active lv before renaming vg, use lvchange to do that.

Snapshots
  • Create a new backup vg :
root@lvs# vgcreate /dev/hdb14 /dev/hdb15
  Volume group "vgcronsb" successfully created


  • Create a new backup lv :
root@lvs# lvcreate -n lvcronsb -L96M vgcronsb
  Logical volume "lvcronsb" created
root@lvs# mke2fs /dev/vgcronsb/lvcronsb
root@lvs# mkdir -p /mnt/backup
root@lvs# mount /dev/vgcronsb/lvconrsb /mnt/backup


  • Create the snapshot (you must have free space on your vg) :
root@lvs# lvcreate -L 48M -s -n lvcrons_snapshot /dev/vgcrons/lvcrons
  Logical volume "lvcrons_snapshot" created
root@lvs# lvdisplay /dev/vgcrons/lvcrons
  --- Logical volume ---
  LV Name                /dev/vgcrons/lvcrons
  VG Name                vgcrons
  LV UUID                trHnRK-ghGG-8gXN-qT92-2ESC-0HKO-R9D8Ai
  LV Write Access        read/write
  LV snapshot status     source of
                         /dev/vgcrons/lvcrons_snapshot [active]
  LV Status              available
  # open                 0
  LV Size                48,00 MB
  Current LE             12
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:0


  • Mount your just create snapshot :
root@lvs# mkdir -p /mnt/lvcrons_backup
root@lvs# mount /dev/vgcrons/lvcrons_snapshot
root@lvs# ls -l /mnt/lvcrons_backup
total 16
-rw-r--r-- 1 root root     0 fév  4 04:22 a_file
-rw-r--r-- 1 root root     0 fév  4 04:22 another_file
-rw-r--r-- 1 root root    28 fév  4 04:22 last_file
drwx------ 2 root root 12288 fév  4 02:09 lost+found
root@lvs# ls -l /mnt/lvcrons
total 16
-rw-r--r-- 1 root root     0 fév  4 04:22 a_file
-rw-r--r-- 1 root root     0 fév  4 04:22 another_file
-rw-r--r-- 1 root root    28 fév  4 04:22 last_file
drwx------ 2 root root 12288 fév  4 02:09 lost+found