利用LVM的快照功能做MySQL資料庫備份,這種方法最大的好處是完全不影響MySQL的運作,這是一種幾乎熱備的備份方式。
一、步驟
1、首先對資料庫施加讀鎖
2、記錄二進制日志檔案的檔案名和事件位置
3、建立快照卷
4、解鎖資料庫
5、挂載快照卷,複制資料檔案
6、删除快照卷
二、準備工作
首先,要對LVM的快照有所了解(http://svenman.blog.51cto.com/6867097/1357510這篇部落格寫了LVM的快照),并将資料檔案放在LVM上。
其次,在資料庫中建立一張測試用的表
mysql> select * from data.info;
+-----+-------+------+
| sid | name | age |
+-----+-------+------+
| 1 | tom | 25 |
| 2 | jerry | 26 |
| 3 | jim | 40 |
| 4 | ccr | 34 |
| 5 | dss | 21 |
| 6 | safe | 44 |
+-----+-------+------+
6 rows in set (0.00 sec)
三、開始備份
1. 首先對資料庫施加讀鎖
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)
2. 記錄二進制日志檔案的檔案名和事件位置
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 964 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
3. 建立快照卷
[root@mysql ~]# cat /etc/my.cnf
[client]
user=root
password=mysql
[mysqld]
datadir=/mysql/data
socket=/tmp/mysql.sock
user=mysql
[root@mysql ~]# df -Th
/dev/mapper/myvg-mydata
ext4 689M 128M 527M 20% /mysql
#可以看到mysql的資料放在myvg下的mydata這個邏輯卷上
[root@mysql ~]# lvcreate -n snap-data -L 100M -p r -s /dev/myvg/mydata
Logical volume "snap-data" created
#快照完成
4. 解鎖資料庫
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
5. 挂載快照卷,複制資料檔案
[root@mysql mnt]# mount -o ro /dev/myvg/snap-data /mnt/
[root@mysql mnt]# cd /mnt/
[root@mysql mnt]# ls
data lost+found
[root@mysql mnt]# tar -jcvf /root/mysql-backup-`date +%F`.tar.bz2 data/
[root@mysql mnt]# cd ~
[root@mysql ~]# ls
anaconda-ks.cfg install.log install.log.syslog mysql-backup-2014-02-22.tar.bz2
6. 删除快照卷
[root@mysql ~]# umount /mnt/
[root@mysql ~]# lvremove /dev/myvg/snap-data
Do you really want to remove active logical volume snap-data? [y/n]: y
Logical volume "snap-data" successfully removed
這樣就備份完成了。
三、恢複測試
1. 在建立的info表中再插入2行資料
mysql> insert into info(name,age) values('seven',30),('eight',49);
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
2. 備份上次lvm快照開始的position号以後的二進制檔案
[root@mysql ~]# mysqlbinlog --start-position=964 /mysql/data/mysql-bin.000002 > /root/bak.sql
mysqlbinlog的用法:
A.指定恢複時間 --start-date和--stop-date選項,格式“2014-2-22 16:33:04”
B.指定恢複位置 --start-position和--stop-position選項
3. 删除所有檔案
[root@mysql ~]# service mysqld stop
[root@mysql ~]# rm /mysql/* -fr
4. 開始恢複(LVM完全備份的恢複)
[root@mysql ~]# tar -jxvf mysql-backup-2014-02-22.tar.bz2 -C /mysql/
[root@mysql ~]# service mysqld start
Starting MySQL [ OK ]
[root@mysql ~]# mysql
mysql> select * from data.info;
+-----+-------+------+
| sid | name | age |
+-----+-------+------+
| 1 | tom | 25 |
| 2 | jerry | 26 |
| 3 | jim | 40 |
| 4 | ccr | 34 |
| 5 | dss | 21 |
| 6 | safe | 44 |
+-----+-------+------+
6 rows in set (0.00 sec)
進行LVM快照後,我們新插入的資料沒有恢複過來
5. 利用二進制檔案基于時間點恢複(增量備份的恢複)
mysql> source /root/bak.sql
#這是第2步從二進制檔案中導出的腳本
mysql> select * from data.info;
+-----+-------+------+
| sid | name | age |
+-----+-------+------+
| 1 | tom | 25 |
| 2 | jerry | 26 |
| 3 | jim | 40 |
| 4 | ccr | 34 |
| 5 | dss | 21 |
| 6 | safe | 44 |
| 7 | seven | 30 |
| 8 | eight | 49 |
+-----+-------+------+
8 rows in set (0.00 sec)
#新插入的2行資料也恢複了
這樣,完全備份+增量備份的備份和恢複就完成了。
附:
邏輯備份工具mysqldump介紹
#導出全庫
mysqldump -u root -p --all-databases > dump.sql
#導出單個庫,或者單個庫中的某個表
mysqldump --u root -p data > dump.sql
mysqldump --u root -p data info > dump.sql
#導出多個資料庫
mysqldump --u root -p --databases data mysql > dump.sql
mysqldump -u user -ppasswd dbname --ignore-table=dbname.tableName > dump.sql