¿Qué es LVM y por qué se usa en Linux?
Logical Volume Manager o LVM por sus siglas (Gestión del Volumen Lógico)), consiste en una arquitectura lógica que agrupa varios discos de sistema que suman todo su tamaño para conformar un único espacio sobre el que se pueden crear diferentes filesystem, cada uno con su tamaño específico.
Es decir, podemos tener un disco de 50GB y otro de 100 para agruparlos en un único espacio de 150GB. A esta estructura se la llama Volume Group. Con ella, podríamos crear un filesystem de 20GB, otro de 100 y otro de 30, si quisiéramos.
La flexibilidad que presenta LVM frente al sistema clásico de particionamiento de disco es mucho más ventajosa. Podemos crear snapshots de un volumen lógico a modo de copia de seguridad o clonación de datos, ampliar filesystems en caliente usando un disco nuevo asignado al VG o, incluso, podemos mover los datos de un disco a otro del mismo VG sin afectar al servicio, pues no requiere parada alguna.
Esta funcionalidad es muy útil en los entornos profesionales en los que es habitual migrar los discos de una cabina a otra más moderna o menos saturada.
A continuación, vamos a ver más ventajas de LVM y cómo utilizarlo.
Estructura básica de LVM
La estructura básica de LVM consiste en:
- Physical Volume (PV): Son los discos físicos o LUNs.
- Volume Group (VG): Es la agrupación de discos.
- Logical Volume (LV): Es el espacio reservado dentro de la arquitectura LVM sobre el cuál crearemos un filesystem.
Ahora nos conectamos al sistema operativo para visualizar una estructura LVM:
- Nombre de los VGs que hay definidos:
# vgs
VG #PV #LV #SN Attr VSize VFree
vg00 1 12 0 wz--n- 99.80g 37.32g
vgMySQL 1 1 0 wz--n- 499.99g 0
vgall01 2 1 0 wz--n- 1.46t 85.98g
vgrear 4 2 0 wz--n- 3.91t 497.00g
#
- Nombre de los PVS que forman cada VG:
# pvs
PV VG Fmt Attr PSize PFree
/dev/sda2 vg00 lvm2 a--u 99.80g 37.32g
/dev/sdb1 vgall01 lvm2 a--u 999.99g 0
/dev/sdc1 vgrear lvm2 a--u 999.99g 0
/dev/sdd1 vgrear lvm2 a--u 999.99g 497.00g
/dev/sde1 vgMySQL lvm2 a--u 499.99g 0
/dev/sdf1 vgrear lvm2 a--u 999.99g 0
/dev/sdg1 vgall01 lvm2 a--u 499.99g 85.98g
/dev/sdh1 vgrear lvm2 a--u 999.99g 0
#
- LVs definidos en cada VG:
# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
auditvol vg00 -wi-ao---- 1.50g
homevol vg00 -wi-ao---- 4.00g
lvISO vg00 -wi-ao---- 22.00g
lvplanific vg00 -wi-ao---- 500.00m
lvstats vg00 -wi-ao---- 500.00m
nbupdates vg00 -wi-ao---- 5.00g
optvol vg00 -wi-ao---- 2.00g
rhomevol vg00 -wi-ao---- 2.00g
rootvol vg00 -wi-ao---- 7.00g
swapvol vg00 -wi-ao---- 2.00g
tmpvol vg00 -wi-ao---- 6.00g
varvol vg00 -wi-ao---- 10.00g
lvbackupmysql vgMySQL -wi-ao---- 499.99g
lvall01 vgall01 -wi-ao---- 1.38t
lvcg2html vgrear -wi-ao---- 3.00g
lvrear vgrear -wi-ao---- 3.42t
#
Toda la información anterior también la podemos sacar con un solo comando:
# vgdisplay -v vgrear
Using volume group(s) on command line.
--- Volume group ---
VG Name vgrear
System ID
Format lvm2
Metadata Areas 4
Metadata Sequence No 73
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 2
Open LV 2
Max PV 0
Cur PV 4
Act PV 4
VG Size 3.91 TiB
PE Size 4.00 MiB
Total PE 1023992
Alloc PE / Size 896760 / 3.42 TiB
Free PE / Size 127232 / 497.00 GiB
VG UUID Mt4umD-nrUM-YdJW-DjzH-bnO9-TkH3-fbfOAH
--- Logical volume ---
LV Path /dev/vgrear/lvrear
LV Name lvrear
VG Name vgrear
LV UUID ewn6LF-j6Z4-fiN0-22Py-eSWB-i73L-PBXzDn
LV Write Access read/write
LV Creation host, time lhpilox01, 2015-05-21 08:09:11 +0200
LV Status available
# open 1
LV Size 3.42 TiB
Current LE 895992
Segments 14
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:3
--- Logical volume ---
LV Path /dev/vgrear/lvcg2html
LV Name lvcg2html
VG Name vgrear
LV UUID 85fOnD-cKgv-vRLI-5SXJ-zd9J-siZq-jb3MgD
LV Write Access read/write
LV Creation host, time lhpilox01, 2017-05-04 10:55:25 +0200
LV Status available
# open 1
LV Size 3.00 GiB
Current LE 768
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:4
--- Physical volumes ---
PV Name /dev/sdh1
PV UUID KWD76w-fCCp-OjPC-RVG1-pcuS-H1rs-zVZCST
PV Status allocatable
Total PE / Free PE 255998 / 0
PV Name /dev/sdc1
PV UUID 0b2nTr-JtxA-3u4y-jFSv-O7db-G16u-TD9387
PV Status allocatable
Total PE / Free PE 255998 / 0
PV Name /dev/sdf1
PV UUID Hyog2W-uisc-bZLG-1Gyo-SxA3-2fJJ-lD6c0Q
PV Status allocatable
Total PE / Free PE 255998 / 0
PV Name /dev/sdd1
PV UUID UhOknb-6uvu-aKRk-qt3p-oKof-E6xd-Odqza0
PV Status allocatable
Total PE / Free PE 255998 / 127232
#
Si miramos cómo están montados los filesystems, nos daremos cuenta de que cada filesystem apunta a un LV distinto:
# mount |grep mapper
/dev/mapper/vg00-rootvol on / type ext3 (rw)
/dev/mapper/vg00-homevol on /home type ext3 (rw,nosuid,nodev)
/dev/mapper/vg00-optvol on /opt type ext3 (rw,nodev)
/dev/mapper/vg00-rhomevol on /root/home type ext3 (rw,nosuid,nodev)
/dev/mapper/vg00-tmpvol on /tmp type ext3 (rw,nosuid,nodev)
/dev/mapper/vg00-varvol on /var type ext3 (rw,nodev)
/dev/mapper/vg00-auditvol on /var/log/audit type ext3 (rw,noexec,nosuid,nodev)
/dev/mapper/vgall01-lvall01 on /AL type ext4 (rw,acl)
/dev/mapper/vg00-lvstats on /stats type ext4 (rw)
/dev/mapper/vg00-lvplanific on /planific type ext4 (rw)
/dev/mapper/vgrear-lvrear on /REAR type ext4 (rw)
/dev/mapper/vgMySQL-lvbackupmysql on /Backup_MySQL type ext4 (rw)
/dev/mapper/vg00-lvISO on /ISO type ext4 (rw)
/dev/mapper/vg00-nbupdates on /usr/openv/nbupdates type ext3 (rw,nodev)
/dev/mapper/vgrear-lvcg2html on /cfg2html type ext4 (rw)
#
Cómo crear un Volume Group de LVM
Ahora que ya sabemos qué es Logical Volume Manager y para qué sirve, vamos a crear una estructura LVM con un physical volume, un volume group, un logical volume y, para finalizar, la creación de un filesystem.
Physical Volume
Con pvcreate «disco» indicamos que un determinado disco, por ejemplo, el /dev/sdb va a ser utilizado en LVM, es decir, le damos formato LVM. En el caso de RedHat, cuando creamos el VG ya ejecuta pvcreate automáticamente, pero en otros sistemas UNIX, como HP-UX, no es así.
De hecho, en RedHat ya se crea automáticamente el dispositivo y el directorio del VG (mknod y mkdir /dev/vg).
Volume Group
Una vez que ya tenemos claro los discos que vamos a utilizar para crear un VG, lo creamos:
vgcreate Nombre_del_VG disco1 disco2 discoN
Por ejemplo:
vgcreate vgMySQL /dev/sdb /dev/sdc
Logical Volume
Finalmente, creamos los volúmenes lógicos (lv) que necesitemos dentro de la estructura del VG:
lvcreate -n Nombre_del_LV -LTamaño VG
Por ejemplo:
lvcreate -n lvMySQL -L10G vgMySQL
Filesystem
Una vez creada la estructura LVM, podemos crear un filesystem sobre ella del formato que queramos. Por ejemplo:
mkfs.xfs /dev/vgMySQL/lvMySQL
Unificar dos VGs (vgmerge)
Si queremos unificar dos volume groups en uno solo, utilizaremos el comando vgmerge. Hay que tener en cuenta que el nombre de los logical volumes no puede coincidir y que el tamaño de extent (pv extent) deber ser idéntico en ambos VGs.
El procedimiento es muy sencillo:
[root@server1 ~]# umount /Backup_MySQL
[root@server1 ~]# umount /BackupPostgreSQL
[root@server1 ~]# vgchange -an vgPostreSQL
0 logical volume(s) in volume group "vgPostreSQL" now active
[root@server1 ~]# vgmerge vgMySQL vgPostreSQL
Volume group "vgPostreSQL" successfully merged into "vgMySQL"
You have new mail in /var/spool/mail/root
[root@server1 ~]# lvchange -a y vgMySQL/lvbackuppostgres
You have new mail in /var/spool/mail/root
[root@server1 ~]#
Comandos más utilizados en LVM
Ampliar un filesystem
lvextend -L512M /dev/VolGroup00/LogVol02
resize2fs /dev/VolGroup00/LogVol02
resize2fs es el comando que se utiliza para ampliar filesystems de tipo ext4 pero cada sistema de archivos tiene su propio comando de ampliación. Por ejemplo, en XFS, el comando a utilizar sería xfs_grow /dev/VolGroup00/LogVol02.
Con el comando anterior, hemos dejado el LV (y luego el FS) con un tamaño total de 512MB pero si lo que queremos es añadir 512MB al tamaño que ya tiene el FS, utilizaríamos:
lvextend -L+512M /dev/VolGroup00/LogVol02
Podrías necesitar incrementar el tamaño de journal del filesystem si no tienes bloques suficientes para la amplicación.
Reducir el tamaño de un filesystem
No todos los filesystems permiten reducir su tamaño. Por ejemplo, EXT4 sí lo permite. Se haría de la siguiente manera:
#Reducimos el FS a 95G, hace el umount+fsck+reducción
# resize2fs -M /dev/mapper/vgdml-lvdml
resize2fs 1.41.12 (17-May-2010)
Resizing the filesystem on /dev/mapper/vgdml-lvdml to 23444391 (4k) blocks.
The filesystem on /dev/mapper/vgdml-lvdml is now 23444391 blocks long.
#Reducimos el disco a 95G, hace el umount+fsck+reducción
# lvreduce -r -L95G /dev/mapper/vgdml-lvdml
Do you want to unmount "/DML_OLD"? [Y|n] y
fsck from util-linux-ng 2.17.2
/dev/mapper/vgdml-lvdml: 29296/6553600 files (0.3% non-contiguous), 23397618/26214400 blocks
resize2fs 1.41.12 (17-May-2010)
Resizing the filesystem on /dev/mapper/vgdml-lvdml to 24903680 (4k) blocks.
The filesystem on /dev/mapper/vgdml-lvdml is now 24903680 blocks long.
Reducing logical volume lvdml to 95.00 GiB
Logical volume lvdml successfully resized
#
Eliminar un volúmen lógico (lv)
Para poder eliminar un LV, éste, debe estar en desuso, es decir, el FS debe estar desmontado. Luego, ya podemos eliminar el LV:
lvremove /dev/VolGroup00/LogVol02
Creación de un mirror de un volúmen lógico
Si no tenemos configurado el RAID de discos a nivel hardware, podremos configurar LVM para que haga el mirror de cada LV si tenemos espacio suficiente en el VG y en diferentes discos.
lvextend -m 1 /dev/VolGroup00/LogVol02
En las versiones más recientes de RedHat ya no se usa lvextend para crear mirrors, sino lvconvert.
lvconvert -m1 /dev/VolGroup00/LogVol02 /dev/sdae
Con m0 eliminamos el mirrror.
¿Qué tal si elaboramos un poco más la creación de un mirror, eliminamos uno de los discos y lo rehacemos?
Cuando no tenemos discos en cabinas, sino que son locales, es útil crear un mirror para no perder nuestros datos en caso de que tengamos alguna avería hardware en alguno de los discos.
Con LVM (Logical Volume Manager) podemos crear los mirrors. A continuación, se explica cómo crear un logical volume en mirror y cómo crear el mirror de un logical volume que actualmente no lo tiene configurado:
[root@cnt6tst ~]# uname -a
Linux cnt6tst 2.6.32-696.20.1.el6.x86_64 #1 SMP Fri Jan 26 17:51:45 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[root@cnt6tst ~]#
Listado de discos disponibles en el sistema
[root@cnt6tst ~]# fdisk -l |grep dev |grep -v mapper
Disk /dev/sda: 12.9 GB, 12884901888 bytes
/dev/sda1 * 1 39 307200 83 Linux
/dev/sda2 39 1410 11017216 83 Linux
/dev/sda3 1410 1567 1257472 82 Linux swap / Solaris
Disk /dev/sdb: 5368 MB, 5368709120 bytes
Disk /dev/sdc: 5368 MB, 5368709120 bytes
[root@cnt6tst ~]#
Creamos un volume group nuevo
[root@cnt6tst ~]# vgcreate vgtest /dev/sdb /dev/sdc
Physical volume "/dev/sdb" successfully created
Physical volume "/dev/sdc" successfully created
Volume group "vgtest" successfully created
[root@cnt6tst ~]#
Creamos un logical volume en mirror y un filesystem
[root@cnt6tst ~]# lvcreate -n lvtest -m1 -L 4500M vgtest
Logical volume "lvtest" created.
[root@cnt6tst ~]#
Observamos que la sincronización de ambos discos está en marcha:
[root@cnt6tst ~]# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lvtest vgtest mwi-a-m--- 4.39g [lvtest_mlog] 13.96
[root@cnt6tst ~]#
Podemos crear un filesystem en paralelo:
[root@cnt6tst ~]# mkfs.ext4 /dev/vgtest/lvtest
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
288000 inodes, 1152000 blocks
57600 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=1182793728
36 block groups
32768 blocks per group, 32768 fragments per group
8000 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 33 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
[root@cnt6tst ~]#
[root@cnt6tst ~]# mount /dev/vgtest/lvtest /test
[root@cnt6tst ~]# df -hP /test
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vgtest-lvtest 4.3G 8.9M 4.0G 1% /test
[root@cnt6tst ~]#
Copiamos un archivo
[root@cnt6tst ~]# cp -p /mnt/hgfs/Centos/CentOS-6.9-x86_64-bin-DVD1.iso /test
[root@cnt6tst ~]# ls -lh /test
total 3.7G
-rwxrwxrwx. 1 root root 3.7G Mar 10 21:46 CentOS-6.9-x86_64-bin-DVD1.iso
drwx------. 2 root root 16K Mar 13 06:38 lost+found
[root@cnt6tst ~]#
También veo que ha finalizado la sincronización del mirror:
[root@cnt6tst ~]# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lvtest vgtest mwi-aom--- 4.39g [lvtest_mlog] 100.00
[root@cnt6tst ~]#
Eliminamos del mirror uno de los discos
[root@cnt6tst ~]# lvconvert -m0 /dev/vgtest/lvtest
Logical volume lvtest converted.
[root@cnt6tst ~]# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lvtest vgtest -wi-ao---- 4.39g
[root@cnt6tst ~]#
Esto me permite eliminar uno de los discos del volume group:
[root@cnt6tst ~]# pvs
PV VG Fmt Attr PSize PFree
/dev/sdb vgtest lvm2 a--u 5.00g 616.00m
/dev/sdc vgtest lvm2 a--u 5.00g 5.00g
[root@cnt6tst ~]#
[root@cnt6tst ~]# vgreduce vgtest /dev/sdc
Removed "/dev/sdc" from volume group "vgtest"
[root@cnt6tst ~]#
[root@cnt6tst ~]# pvs
PV VG Fmt Attr PSize PFree
/dev/sdb vgtest lvm2 a--u 5.00g 616.00m
/dev/sdc lvm2 ---- 5.00g 5.00g
[root@cnt6tst ~]#
Rehacemos el mirror
Ahora vamos a rehacer el mirror pero no el logical volume, ya que lo hemos creado previamente:
[root@cnt6tst ~]# vgextend vgtest /dev/sdc
Volume group "vgtest" successfully extended
[root@cnt6tst ~]# lvconvert -m1 /dev/vgtest/lvtest
vgtest/lvtest: Converted: 0.0%
vgtest/lvtest: Converted: 11.8%
vgtest/lvtest: Converted: 23.7%
vgtest/lvtest: Converted: 35.4%
vgtest/lvtest: Converted: 47.7%
vgtest/lvtest: Converted: 60.5%
vgtest/lvtest: Converted: 72.4%
vgtest/lvtest: Converted: 84.4%
vgtest/lvtest: Converted: 97.1%
vgtest/lvtest: Converted: 100.0%
[root@cnt6tst ~]# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lvtest vgtest mwi-aom--- 4.39g [lvtest_mlog] 100.00
[root@cnt6tst ~]#
Comprobación del estado de los datos
Como vemos, nuestros datos siguen intactos:
[root@cnt6tst ~]# ls -lh /test
total 3.7G
-rwxrwxrwx. 1 root root 3.7G Mar 10 21:46 CentOS-6.9-x86_64-bin-DVD1.iso
drwx------. 2 root root 16K Mar 13 06:38 lost+found
[root@cnt6tst ~]#
Mover datos de un disco a otro del mismo VG (pvmove)
A veces nos interesa sustituir un disco de un VG por otro. Esto es típico en la administración de sistemas de grandes empresas cuando compran una cabina de discos nueva y han de mover los datos del disco antiguo al nuevo sin afectar al servicio. Esto se hace en tres pasos:
1. Incorprar los discos de la cabina nueva al VG (vgextend Nombre_VG disco_nuevo).
2. Moviendo los datos del disco viejo al nuevo (pvmove disco_viejo disco_nuevo). Por ejemplo: pvmove /dev/sdb /dev/sdc.
# pvmove /dev/sdg1 /dev/sdk1
/dev/sdg1: Moved: 0.0%
/dev/sdg1: Moved: 2.0%
/dev/sdg1: Moved: 4.0%
…
/dev/sdg1: Moved: 94.7%
/dev/sdg1: Moved: 98.8%
/dev/sdg1: Moved: 100.0%
#
3. Eliminando del VG los discos viejos. Por ejemplo: vgreduce Nombre_VG /dev/sdb.
Activar o desactivar un VG
Esto se utiliza más cuando estamos configurando clusters. En realidad, es el propio cluster quien activa el VG en el nodo correspondiente pero, si nos interesara activar o desactivar un VG manualmente, lo haríamos con el siguiente comando:
vgchange -a y Nombre VG
vgchange -a n Nombre VG
Escanear VGs
Cuando estamos montando clusters vemos los mismos discos en todos los servidores que van a formar el cluster para que cualquier servidor pueda montar los filesystems en caso de incidencia. Por lo tanto, también debe ver los mismos VGs con la misma estructura de datos.
Con el comando vgscan cada servidor escaneará la estructura LVM. Es decir, si creamos un VG en uno de los servidores del cluster, al ejecutar vgscan en otro de los servidores, tendrá visibilidad sobre el mismo VG.
Crear un snapshot de un filesystem con LVM
Crear un snapshot de un filesystem puede ser útil para hacer marcha atrás de un cambio. Por ejemplo, hemos actualizado el sistema operativo y hay algo que no funciona como esperábamos. Con un snapshot del filesystem de sistema podríamos restaurar el estado original.
Ocurriría lo mismo con cualquier otra aplicación.
Si los cambios han funcionado correctamente, podemos dejarlos permanentes y eliminar el snapshot.
Veamos como funciona:
- Versión del sistema operativo donde voy a hacer la prueba:
[root@centostst1 ~]# lsb_release -a
LSB Version: :core-4.1-amd64:core-4.1-noarch:cxx-4.1-amd64:cxx-4.1-noarch:desktop-4.1-amd64:desktop-4.1-noarch:languages-4.1-amd64:languages-4.1-noarch:printing-4.1-amd64:printing-4.1-noarch
Distributor ID: CentOS
Description: CentOS Linux release 7.3.1611 (Core)
Release: 7.3.1611
Codename: Core
[root@centostst1 ~]#
- Creo un fichero en el filesystem del que voy a hacer el snapshot:
[root@centostst1 ~]# df -hP /test
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vgtest-lvtest 477M 2.3M 445M 1% /test
[root@centostst1 ~]# echo "Primer fichero" > /test/fichero1.txt
[root@centostst1 ~]# ll /test
total 13
-rw-r--r-- 1 root root 15 Apr 13 13:26 fichero1.txt
drwx------ 2 root root 12288 Apr 13 13:25 lost+found
[root@centostst1 ~]#
- Hago el snapshot:
[root@centostst1 ~]# lvcreate -s -n lvtest_snapshot -L 100M /dev/vgtest/lvtest
Using default stripesize 64.00 KiB.
Logical volume "lvtest_snapshot" created.
[root@centostst1 ~]# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root vg00 -wi-ao---- 10.80g
swap vg00 -wi-ao---- 3.42g
lvtest vgtest owi-aos--- 500.00m
lvtest_snapshot vgtest swi-a-s--- 100.00m lvtest 0.01
[root@centostst1 ~]#
- Ahora creo un segundo fichero en el filesystem /test, para guardar un cambio en el filesystem:
[root@centostst1 ~]# echo "Segundo fichero" > /test/fichero2.txt
[root@centostst1 ~]# ll /test
total 14
-rw-r--r-- 1 root root 15 Apr 13 13:26 fichero1.txt
-rw-r--r-- 1 root root 16 Apr 13 13:29 fichero2.txt
drwx------ 2 root root 12288 Apr 13 13:25 lost+found
[root@centostst1 ~]#
- Pero, por aquellas circunstancias de la vida, deseo hacer marcha atrás del cambio:
[root@centostst1 ~]# umount /test
[root@centostst1 ~]# lvconvert --merge /dev/vgtest/lvtest_snapshot
Merging of volume vgtest/lvtest_snapshot started.
lvtest: Merged: 100.00%
[root@centostst1 ~]# mount /test
[root@centostst1 ~]# ll /test
total 13
-rw-r--r-- 1 root root 15 Apr 13 13:26 fichero1.txt
drwx------ 2 root root 12288 Apr 13 13:25 lost+found
[root@centostst1 ~]#
- Ahora vuelvo a realizar un nuevo cambio y esta vez quiero conservarlo. Simplemente, elimino el snapshot:
[root@centostst1 ~]# lvremove /dev/vgtest/lvtest_snapshot
Do you really want to remove active logical volume vgtest/lvtest_snapshot? [y/n]: y
Logical volume "lvtest_snapshot" successfully removed
[root@centostst1 ~]# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root vg00 -wi-ao---- 10.80g
swap vg00 -wi-ao---- 3.42g
lvtest vgtest -wi-ao---- 500.00m
[root@centostst1 ~]# ll /test
total 14
-rw-r--r-- 1 root root 15 Apr 13 13:26 fichero1.txt
-rw-r--r-- 1 root root 16 Apr 13 13:37 fichero2.txt
drwx------ 2 root root 12288 Apr 13 13:25 lost+found
[root@centostst1 ~]# umount /test
[root@centostst1 ~]# mount /test
[root@centostst1 ~]# ll /test
total 14
-rw-r--r-- 1 root root 15 Apr 13 13:26 fichero1.txt
-rw-r--r-- 1 root root 16 Apr 13 13:37 fichero2.txt
drwx------ 2 root root 12288 Apr 13 13:25 lost+found
[root@centostst1 ~]#
Mover una base de datos a una cabina de discos más rápida con LVM
Alguna vez os he hablado de las incidencias que suelen reportar los usuarios de una aplicación con mensajes poco aclaratorios como «la aplicación me va lenta» y casi nunca pasa nada en los servidores a nivel de sistema operativo, que es lo que administro yo. Suele ser una consulta de Oracle que no va por índice, un problema de memory leak, garbage collector de Java, faltan incorporar nuevos servidores de aplicaciones, alguna operativa que ha lanzando un usuario cuando no tocaba y estaba machacando la base de datos… Pueden ser mil cosas y hay que analizarlo todo.
¿Por qué estoy migrando la base de datos a otra SAN?
Pues esta vez el problema estaba en la cabina de discos. Resulta que revisando las métricas de Average Service Time, que te da el tiempo que tarda un disco en responder, en los peores tiempos, el sistema enviaba una petición de lectura o escritura al disco y la cabina tardaba un minuto en responder, cuando lo normal tiene que ser menos de diez milisegundos.
Resultado: La base de datos se quedaba todo el rato esperando respuesta del disco. Venían nuevas peticiones de los usuarios que se encolaban por disco que se convirtieron en una bola de nieve que fue creciendo hasta colapsar el servidor. Load alto, etc.
Así que tuvimos que tomar medidas:
- El equipo de Storage tendría que analizar el estado de la cabina de discos y optimizar su rendimiento.
- En paralelo, para solucionar la incidencia, quedamos en que moveríamos los datos a otra cabina que estuviera más descargada y pudiese darnos los tiempos habituales de respuesta (menos de 10ms).
¿Cómo estoy migrando una base de datos Oracle a otra cabina de discos sin afectar al servicio?
El escenario de alta disponibilidad de disco de este entorno consiste en utilizar dos discos de dos cabinas diferentes y crear un mirror por software entre ambos. De esta manera, si cae una cabina de discos, los datos siguen accesibles por el disco de la otra cabina. No es el mejor sistema de HA pero es el que hay configurado en este entorno.
A nivel de sistema operativo, utilizamos Logical Volume Manager o LVM, lo que significa que dentro del volume group (VG) incorporamos los mirrors (Physical Volumes) que contienen los datos de la base de datos.
La gracia de LVM consiste en que permite mover datos en caliente de un disco a otro. Esto se consigue con el comando pvmove. Por lo tanto, la intervención o RFC (Request for change) la he programado de la siguiente manera:
- Solicito nuevos discos en las cabinas rápidas.
- Configuro el multipath. Esto se hace añadiendo las siguientes líneas en el fichero /etc/multipath.conf (RedHat 6). El WWID es el identificador del disco que me ha proporcionado el equipo de Storage.
multipath {
wwid 360002ac0000000000000009c000206ca
alias md16_rem_1
}
multipath {
wwid 360002ac0000000000000012d0002090f
alias md16_rem_2
}
multipath {
wwid 360002ac0000000000000009d000206ca
alias md17_rem_1
}
multipath {
wwid 360002ac0000000000000012c0002090f
alias md17_rem_2
}
- Creo los mirrors por software apuntando al nombre del multipath.
mdadm --create --verbose /dev/md16 --name=0 --level=1 --raid-devices=2 /dev/mapper/md16_rem_1 /dev/mapper/md16_rem_2
mdadm -Db /dev/md16 >> /etc/mdadm.conf
mdadm --create --verbose /dev/md17 --name=0 --level=1 --raid-devices=2 /dev/mapper/md17_rem_1 /dev/mapper/md17_rem_2
mdadm -Db /dev/md17 >> /etc/mdadm.conf
- Incorporo los mirrors al VG actual de la base de datos.
vgextend vg_rem /dev/md16 /dev/md17
- Muevo los datos desde los discos de la cabina actual a la nueva con pvmove. Para ello, lanzo con nohup el siguiente script:
nohup pvmoves.sh &
cat pvmoves.sh
# Disco 500GB
pvmove -i 300 /dev/md6 /dev/md16
# Disco 500GB
pvmove -i 300 /dev/md8 /dev/md17
# Disco 200GB
pvmove -i 300 /dev/md15 /dev/md16
# Disco 100GB
pvmove -i 300 /dev/md10 /dev/md17
# Disco 100GB
pvmove -i 300 /dev/md12 /dev/md17
# Disco 150GB
pvmove -i 300 /dev/md2 /dev/md16
# Disco 50GB
pvmove -i 300 /dev/md9 /dev/md17
- Elimino del VG los discos en desuso para no volver a utilizar la cabina lenta.
vgreduce vg_rem /dev/md10 /dev/md12 /dev/md15 /dev/md2 /dev/md6 /dev/md8 /dev/md9
Por último, reconfiguro el cluster de ServiceGuard para que el paquete de servicio levante los nuevos mirrors. Pero de este producto hablo en el artículo Configuración de un cluster de ServiceGuard 12 en Linux RedHat 6.
¿Cuál es el mejor momento para mover datos de una cabina a otra?
No sé si hace falta decirlo, pero este tipo de intervenciones hay que realizarlas fuera de horario de servicio por dos motivos:
- Representa un riesgo evidente para el servicio que podría afectar a los usuarios.
- El pvmove lee discos de una cabina, los escribe en la nueva y los borra en la antigua, de manera continua, lo que representa mucha actividad de IO que va a afectar al rendimiento de la aplicación.
Uso de una LUN ampliada en RedHat y LVM sin rebotar el sistema
Cuando necesitamos ampliar un filesystem en RedHat, normalmente solicitamos una nueva LUN con el tamaño que necesitamos y la añadimos a la estructura LVM.
Sin embargo, me he encontrado casos en los que bien desde la cabina de discos, bien a nivel de VMWare, amplían la LUN que ya estaba utilizando.
En este segundo caso, para poder utilizar el nuevo espacio de la LUN sin tener que rebotar el servidor, seguiremos los siguientes pasos:
Rescaneamos los discos del sistema
find /sys/devices -name rescan |awk '{print echo "echo 1 > " $1}' |sh
En el log del sistema (/var/log/messages), detectamos el cambio de tamaño de la LUN:
Aug 26 11:25:49 sgdsrmdlh001 kernel: sdl: detected capacity change from 10737418240 to 42949672960
Lo podemos comprobar con un fdisk, por ejemplo:
Disk /dev/sdl: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Ampliamos el physical volume (PV)
pvs |grep sdl
/dev/sdl vg_sybase lvm2 a-- 10.00g 0
pvresize /dev/sdl
Physical volume "/dev/sdl" changed
1 physical volume(s) resized / 0 physical volume(s) not resized
pvs |grep sdl
/dev/sdl vg_sybase lvm2 a-- 40.00g 30.00g
Ampliar el logical volume (LV) y filesystem
Ahora ya podemos extender el logical volume y ampliar el filesystem como lo hacemos habitualmente:
lvextend -n NombreLV -L+30G
xfs_growfs /dev/NombreVG/NombreLV
Problemas con LVM
En esta sección detallaré algunas de las incidencias relevantes con las que me he topado.
Cannot archive volume group metadata for vgopt to read-only filesystem
Esta mañana me he quedado perplejo cuando estaba intentado ampliar un physical volume de una LUN ampliada de un servidor virtual porque decía que el filesystem estaba presentado en modo lectura, pero no veía ningún FS del volume group vgopt montado en modo lectura.
[root@lgekdpx0 ~]# pvresize /dev/sdb1
Cannot archive volume group metadata for vgopt to read-only filesystem.
0 physical volume(s) resized / 1 physical volume(s) not resized
[root@lgekdpx0 ~]# pvs
PV VG Fmt Attr PSize PFree
/dev/sda2 vg00 lvm2 a-- 99.51g 120.00m
/dev/sdb1 vgopt lvm2 a-- 50.00g 0
/dev/sdc1 vgopt lvm2 a-- 100.00g 9.99g
/dev/sdd1 vgopt lvm2 a-- 100.00g 0
[root@lgekdpx0 ~]#
[root@lgekdpx0 ~]# mount |grep vgopt
/dev/mapper/vgopt-lvoptdata on /opt/PostgresqlDataGEFACT type xfs (rw,relatime,attr2,inode64,noquota)
/dev/mapper/vgopt-lvpostgresqllog on /opt/PostgresqlLog type xfs (rw,relatime,attr2,inode64,noquota)
/dev/mapper/vgopt-lvoptscript on /opt/PostgresqlScriptsGEFACT type xfs (rw,relatime,attr2,inode64,noquota)
/dev/mapper/vgopt-lvpostgresqlbackup on /opt/PostgresqlBackupGEEC type xfs (rw,relatime,attr2,inode64,noquota)
/dev/mapper/vgopt-lvoptback on /opt/PostgresqlBackupGEFACT type xfs (rw,relatime,attr2,inode64,noquota)
/dev/mapper/vgopt-lvpostgresqldata on /opt/PostgresqlDataGEEC type xfs (rw,relatime,attr2,inode64,noquota)
/dev/mapper/vgopt-lvpostgresqlwalcompr on /opt/PostgresqlWalComprGEEC type xfs (rw,relatime,attr2,inode64,noquota)
/dev/mapper/vgopt-lvpostgresqlxlog on /opt/PostgresqlXlogGEEC type xfs (rw,relatime,attr2,inode64,noquota)
/dev/mapper/vgopt-lvoptcom on /opt/PostgresqlWalComprGEFACT type xfs (rw,relatime,attr2,inode64,noquota)
/dev/mapper/vgopt-lvoptxlog on /opt/PostgresqlXlogGEFACT type xfs (rw,relatime,attr2,inode64,noquota)
/dev/mapper/vgopt-lvpostgresqlscripts on /opt/PostgresqlScriptsGEEC type xfs (rw,relatime,attr2,inode64,noquota)
[root@lgekdpx0 ~]#
Así, que pensé que había ocurrido algo a nivel de VMWare y el disco que me habían presentado estaba en modo lectura, ya que no era la primera vez que me había ocurrido. Pero nada de eso, resulta que el filesystem raíz estaba montado en modo lectura. De hecho, para mi sorpresa, ni siquiera estaba configurado en el fichero /etc/fstab!!!!
El problema quedó resuelto tras remontarlo con permisos de lectura y escritura.
[root@lgekdpx0 ~]# mount |grep -v rw
/dev/mapper/vg00-rootvol on / type xfs (ro,relatime,attr2,inode64,noquota)
[root@lgekdpx0 ~]# mount -o remount,rw /dev/mapper/vg00-rootvol
[root@lgekdpx0 ~]# pvresize /dev/sdb1
Physical volume "/dev/sdb1" changed
1 physical volume(s) resized / 0 physical volume(s) not resized
[root@lgekdpx0 ~]# pvs |grep sdb1
/dev/sdb1 vgopt lvm2 a-- 100.00g 50.00g
[root@lgekdpx0 ~]#
Esto me ocurrió en un Linux RedHat 7.3.
Volume «VG_Name» is not active locally
Este error me ha ocurrido en un entorno con un cluster de ServiceGuard. Tengo algunos VGs que los activa el propio ServiceGuards pero este error me dio en un VG local que no me dejaba activar:
[root ~]# lvcreate -n openv -l+100%FREE vgopenv
Volume "vgopenv/openv" is not active locally.
Aborting. Failed to wipe start of new LV.
[root ~]#
La solución fue añadir este VG local en la directiva volume_list del fichero /etc/lvm/lvm.conf:
[root ~]# grep -i volume_list /etc/lvm/lvm.conf |grep -v "#"
volume_list = [ "vg00" "vgopenv"]
[root ~]#
En el propio fichero lvm.conf viene un poco de información acerda de esta directiva:
lvm.conf# If volume_list is defined, each LV is only activated if there is a match against the list.
Devices file sys_wwid eui.194931df14b96e2c000c296999b11a28 PVID Qn1sf7s8Z6vIBZQ59h2OpVAaHTyHjsk4 last seen on /dev/nvme0n1p2 not found
En el error del título anterior, podemos ver como LVM no encuentra el physical volume, a pesar de que sí existe en el sistema:
[root@rhel9casa lvm]# pvs
Devices file sys_wwid eui.194931df14b96e2c000c296999b11a28 PVID Qn1sf7s8Z6vIBZQ59h2OpVAaHTyHjsk4 last seen on /dev/nvme0n1p2 not found.
Devices file sys_wwid eui.09014718d126ac0a000c29607ed81a01 PVID 1DdcV6JwdF0ffE7NtJ6bhm0zVkhA8GrB last seen on /dev/nvme0n2 not found.
[root@rhel9casa lvm]#
El problema estaba en una entrada que había en el fichero /etc/lvm/devices/system.devices:
[root@rhel9casa lvm]# cat /etc/lvm/devices/system.devices
# LVM uses devices listed in this file.
# Created by LVM command vgcreate pid 14646 at Wed Jan 25 15:29:23 2023
#VERSION=1.1.3
#IDTYPE=sys_wwid IDNAME=eui.194931df14b96e2c000c296999b11a28 DEVNAME=/dev/nvme0n1p2 PVID=Qn1sf7s8Z6vIBZQ59h2OpVAaHTyHjsk4 PART=2
#IDTYPE=sys_wwid IDNAME=eui.09014718d126ac0a000c29607ed81a01 DEVNAME=/dev/nvme0n2 PVID=1DdcV6JwdF0ffE7NtJ6bhm0zVkhA8GrB
[root@rhel9casa lvm]#
Al comentar esa entrada, el comando pvs ya responde con normalidad:
[root@rhel9casa lvm]# pvs
PV VG Fmt Attr PSize PFree
/dev/nvme0n1p2 vg00 lvm2 a-- <24.00g 0
[root@rhel9casa lvm]#
El propósito principal de /etc/lvm/devices/system.devices
es proporcionar un mecanismo para controlar qué dispositivos de almacenamiento (como discos duros, particiones, etc.) pueden ser usados por LVM. Esto es útil en situaciones donde quieres evitar que LVM interactúe con ciertos dispositivos por razones de rendimiento, seguridad, o para evitar conflictos con otros sistemas de almacenamiento o particiones.
Te puede interesar
- Comandos básicos sobre el sistema de archivos de Linux
- Administración del sistema de archivos de Linux
- Ampliar una partición y un filesystem NO LVM
- Sistema de archivos BTRFS
- Ahorra espacio en disco con dispositivos VDO
Mi pasión por la tecnología me lleva constantemente a explorar las últimas tendencias y aplicaciones, buscando siempre formas de implementar soluciones innovadoras que mejoren la eficiencia. En puerto53.com comparto contenido valioso para ayudar a otros profesionales y entusiastas de la informática a navegar y dominar el complejo mundo de la tecnología. Mi especialidad en Linux RedHat.
Más sobre mí en el este enlace,