Este artículo muestra de forma práctica como montar un sistema de backup de MySQL basado en snapshots de LVM.
Básicamente, se siguen los siguientes pasos:
Este mecanismo permite hacer backup de MySQL evitando las herramientas mysqldump y mysqlhotcopy, que para BBDD de tamaños grandes producen bloqueos de hasta minutos de duración con el consecuente corte de servicio.
Si no está ya incluído en nuestro sistema, instalamos los paquetes de LVM y cargamos en memoria los módulos dm_mod, dm_mirror y dm_snapshot:
root@server:~# apt-get install lvm2 mylvmbackup root@server:~# modprobe dm_mod root@server:~# modprobe dm_mirror root@server:~# modprobe dm_snapshot
Creamos una partición de tipo LVM que sea, al menos, del 125% del tamaño que pensemos dejar para /var/lib/mysql. Ese 25% de espacio adicional (en mi ejemplo va a ser casi un 75% adicional) son bloques LVM libres que permitan generar el snapshot del filesystem de datos de MySQL:
root@server:~# fdisk -l /dev/cciss/c0d1
Disk /dev/cciss/c0d1: 146.7 GB, 146778685440 bytes
255 heads, 32 sectors/track, 35132 cylinders
Units = cylinders of 8160 * 512 = 4177920 bytes
Disk identifier: 0x0d909842
Device Boot Start End Blocks Id System
/dev/cciss/c0d1p1 1 15559 63480704 83 Linux
/dev/cciss/c0d1p2 15560 35132 79857840 8e Linux LVM
root@server:~# pvcreate /dev/cciss/c0d1p2
Physical volume "/dev/cciss/c0d1p2" successfully created
root@server:~# pvdisplay /dev/cciss/c0d1p2
--- NEW Physical volume ---
PV Name /dev/cciss/c0d1p2
VG Name
PV Size 76,16 GB
Allocatable NO
PE Size (KByte) 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID LB4H0W-8pwL-y0MN-cWUH-fYX3-gD1U-hm5saW
root@server:~# vgcreate -s 8 vgmysql /dev/cciss/c0d1p2
Volume group "vgmysql" successfully created
root@server:~# vgdisplay vgmysql
--- Volume group ---
VG Name vgmysql
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 1
Act PV 1
VG Size 76,16 GB
PE Size 8,00 MB
Total PE 9748
Alloc PE / Size 0 / 0
Free PE / Size 9748 / 76,16 GB
VG UUID Az7RTH-DqxW-wXRJ-l3GF-vgT4-t35f-lkumuf
root@server:~# lvcreate -L 40G -n data vgmysql
Logical volume "data" created
root@server:~# mkfs.ext3 /dev/vgmysql/data
mke2fs 1.40.8 (13-Mar-2008)
root@server:~# tune2fs -m 1 /dev/vgmysql/data
tune2fs 1.40.8 (13-Mar-2008)
Setting reserved blocks percentage to 1% (104857 blocks)
A continuación detenemos MySQL y movemos los datos al nuevo Logical Volume:
root@server:~# /etc/init.d/mysql stop
* Stopping MySQL database server mysqld [ OK ]
root@server:~# cd /var/lib/
root@server:/var/lib# ls -ld mysql
drwxr-xr-x 9 mysql mysql 4096 2010-04-08 09:20 mysql
root@server:/var/lib# mv mysql mysql2
root@server:/var/lib# mkdir mysql
root@server:/var/lib# chown mysql:mysql mysql
root@server:/var/lib# grep mysql /etc/fstab
/dev/vgmysql/data /var/lib/mysql ext3 relatime 0 2
root@server:/var/lib# mount -a
root@server:/var/lib# chown mysql:mysql mysql
root@server:/var/lib# ls -ld mysql
drwxr-xr-x 3 mysql mysql 4096 2010-05-12 17:36 mysql
root@server:/var/lib# df -h /var/lib/mysql
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vgmysql-data
40G 177M 40G 1% /var/lib/mysql
root@server:/var/lib# mv mysql2/* mysql/
root@server:/var/lib/mysql# /etc/init.d/mysql start
* Starting MySQL database server mysqld [ OK ]
* Checking for corrupt, not cleanly closed and upgrade needing tables.
Creamos los directorios necesarios para alojar nuestros backups, y configuramos mylvmbackup con los datos de MySQL, VGs, LVs y directorios adecuados:
root@server:~# mkdir /backup/ root@server:~# mkdir /backup/lvmysql root@server:~# mkdir /backup/lvsnapshot root@server:~# cat /etc/mylvmbackup.conf [mysql] user=root password=passwd_root_mysql host=localhost port=3306 socket= mycnf=/etc/mysql/my.cnf # LVM-specific options [lvm] vgname=vgmysql lvname=data backuplv=backup lvsize=10G # File system specific options [fs] xfs=0 mountdir=/backup/lvsnapshot/ backupdir=/backup/lvmysql/ relpath= # Full path names of required external utilities [tools] lvcreate=/sbin/lvcreate lvremove=/sbin/lvremove mount=/bin/mount tar=/bin/tar rsync=/usr/bin/rsync umount=/bin/umount # Other configuration options [misc] backuptype=tar prefix=backup tararg=cvzf tarsuffixarg= rsyncarg=-avWP datefmt=%Y%m%d_%H%M%S innodb_recover=0 pidfile=/var/tmp/mylvmbackup_recoverserver.pid skip_flush_tables=0 extra_flush_tables=0 # Logging options. The Sys::Syslog module is required for syslog option [logging] # 'console' (STDOUT, STDERR) or 'syslog' or 'both'. log_method=console # 'native', 'tcp', 'udp'. Default is 'native' syslog_socktype=native syslog_facility= # If using remote syslog, don't forget to specify the socket type to tcp or udp. syslog_remotehost=
Ejecutamos mylvmbackup, que leerá su fichero de configuración y realizará el backup de la BBDD. Como podemos ver en el siguiente ejemplo, el tiempo de corte real en esta base de datos es de menos de 1 segundo (en el mismo minuto 09:18:16 se hace tanto el FLUSH como el UNLOCK).
root@server:~# mylvmbackup 20100513 09:18:16 Info: Connecting to database... 20100513 09:18:16 Info: Flushing tables with read lock... 20100513 09:18:16 Info: Taking position record... 20100513 09:18:16 Info: Taking snapshot... File descriptor 3 left open Logical volume "backup" created 20100513 09:18:16 Info: Unlocking tables... 20100513 09:18:16 Info: Disconnecting from database... 20100513 09:18:16 Info: Mounting snapshot... 20100513 09:18:16 Info: Copying my.cnf... 20100513 09:18:16 Info: Taking actual backup... 20100513 09:34:18 Info: Creating tar archive /backup/lvmysql/backup-20100513_093418_mysql.tar.gz backup/ backup/phpmyadmin/ backup/phpmyadmin/pma_relation.MYD backup/phpmyadmin/pma_history.MYI backup/phpmyadmin/pma_table_coords.MYI (...) backup/accesorios/db.opt backup/accesorios/usuarios.MYD backup/accesorios/usuarios.MYI backup/accesorios/usuarios.frm backup-pos/backup-20100513_093418_mysql.pos backup-pos/backup-20100513_093418_my.cnf 20100513 09:36:46 Info: DONE 20100513 09:36:46 Info: Cleaning up... 20100513 09:36:46 Info: LVM Usage stats: 20100513 09:36:46 Info: LV VG Attr LSize Origin Snap% Move Log Copy% 20100513 09:36:46 Info: backup vgmysql swi-a- 10,00G data 0,00 Logical volume "backup" successfully removed
Finalmente, programamos el backup en el cron del sistema:
root@server:~# grep -i my /etc/crontab
# Backups MySQL
0 3 * * * root mylvmbackup > /dev/null
50 3 * * * root find /backup/lvmysql -name "*.gz" -mtime +8 -exec rm {} \;
De esta forma tenemos backups diarios totalmente consistentes sin afectación al servicio de BBDD.