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.