Chinaunix首页 | 论坛 | 博客
  • 博客访问: 637412
  • 博文数量: 244
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 130
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-27 09:53
个人简介

记录学习,记录成长

文章分类

全部博文(244)

我的朋友

分类: LINUX

2015-10-10 13:30:49

备份策略:逻辑卷(完全备份)+二进制日志(增量备份)
前提:
1.数据文件要在逻辑卷上;
2.逻辑卷所在卷组必须有足够的空间存放快照卷;
3.事务日志和数据文件要在同一个逻辑卷上;
4.备份单个数据库时,要使用INnoDB引擎,且打开innodb_file_per_table功能;

一.
创建快照卷时,假如正好有一个事务正在进行,如果此时备份,那么该事务并不会被备份,所以应该在备份时加上读锁,让事务先暂停,并记录下此时的二进制日志文件及其记录位置,等备份完成事务执行后,可以根据二进制日志将事务还原;
会话1(执行事务):
mysql> use mydb;
mysql> start transaction;
mysql> insert into course values(6,'HTML');
mysql> select * from course;

会话2(备份):
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
mysql> select * from course;
+-----+-------+
| cno | cname |
+-----+-------+
|   1 | Linux |
|   2 | C++   |
|   3 | C     |
|   4 | sql   |
|   5 | A     |
+-----+-------+
因为会话1还未提交事务所以会话2看不到,但是能施加锁:
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.06 sec)
而且此时对于会话1,其事务也无法再执行操作了:
mysql> insert into course values(7,'ARM');


会话2:
flushlogs将二进制日志的文件和位置保存下来,以便知道在备份时二进制日志到了哪一刻,将来在备份完成后可以根据二进制日志文件还原
mysql> flush logs;
mysql> show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| www-bin.000002 |      120 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
或者打开另一个会话3(因为读锁不能解除):
[root@www ~]# mysql -e 'show master status\G' > /tmp/lvm_logs.info
[root@www ~]# cat /tmp/lvm_logs.info 
*************************** 1. row ***************************
             File: www-bin.000002
         Position: 120
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 
这样因为在备份时加了锁,事务无法进行,但是将事务记入了二进制日志中。当备份完成取消锁后,事务立即被执行,但可以根据二进制日志的文件及位置来将这些事务还原,这样就不会造成数据丢失的情况了;

二.创建快照卷
MYSQL的数据都放在/dev/myvg/mydata下,该创建过程不在赘述;
1.创建快照卷
[root@www ~]# lvcreate -L 50M -s -p r -n mysql-snap /dev/myvg/mydata
  Rounding up size to full physical extent 52.00 MiB
  Logical volume "mysql-snap" created

2.会话2上解除锁:
mysql> unlock tables;
Query OK, 0 rows affected (0.01 sec)
mysql> show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| www-bin.000002 |      120 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+

会话1的事务会立即执行:
mysql> insert into course values(7,'ARM');
Query OK, 1 row affected (34 min 17.41 sec)

会话1提交该事务:
mysql> commit;

会话2上会立即将两次插入的操作记入二进制日志中:
mysql> show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| www-bin.000002 |      447 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+

3.挂载LVM快照
[root@www ~]# mount /dev/myvg/mysql-snap /lvm-snap/ -o ro

[root@www ~]# cd /lvm-snap/

[root@www lvm-snap]# ls data/ (所有的数据都存放在此目录中)
auto.cnf  ib_logfile0  mydb   performance_schema     www-bin.000002
ibdata1   ib_logfile1  mysql         www-bin.000001  www-bin.index

4.开始备份
对于data目录中的二进制日志文件,因为它没有保存后来的事务操作的数据,所以不需要备份,其他的最好都备份;
[root@www data]# mkdir -p /backup/all-backup-`date +%F`
[root@www data]# cp -a ./* /backup/all-backup-2015-10-09/
[root@www ~]# cd /backup/all-backup-2015-10-09/
[root@www all-backup-2015-10-09]# rm -rf www-bin.*

5.备份完成后有卸载快照卷并删除该快照
[root@www ~]# umount /lvm-snap/
[root@www ~]# lvremove --force /dev/myvg/mysql-snap 
  Logical volume "mysql-snap" successfully removed

三.恢复数据
1.如果此时恢复数据,那么前面插入的两行不会被恢复,所以还需对二进制日志进行备份
[root@www all-backup-2015-10-09]# cd /mysqldata/data/
[root@www data]# cat /tmp/lvm_logs.info
*************************** 1. row ***************************
             File: www-bin.000002
         Position: 120
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 
只需备份该文件以后的文件即可(如果记录跨文件,那么使用时间来备份即--start-datatime)
[root@www data]# mysqlbinlog --start-position=120 www-bin.000002 > /tmp/lvm.sql

2.模拟数据损坏
[root@www data]# service mysqld stop
Shutting down MySQL.. SUCCESS! 
[root@www data]# pwd
/mysqldata/data
[root@www data]# rm -rf ./*

3.恢复数据
[root@www ~]# cp -a /backup/all-backup-2015-10-09/* /mysqldata/data/
[root@www ~]# ls /mysqldata/data/
auto.cnf  ib_logfile0  mydb   performance_schema  
ibdata1   ib_logfile1  mysql  
[root@www ~]# service mysqld start
Starting MySQL SUCCESS! 
[root@www ~]# ls /mysqldata/data/
auto.cnf  ib_logfile0  mydb   performance_schema     www-bin.index
ibdata1   ib_logfile1  mysql         www-bin.000001

4.连接MYSQL测试:
mysql> use mydb;
mysql> select * from course;
+-----+-------+
| cno | cname |
+-----+-------+
|   1 | Linux |
|   2 | C++   |
|   3 | C     |
|   4 | sql   |
|   5 | A     |
+-----+-------+

mysql> show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| www-bin.000001 |      120 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+

这里没有插入的两个数据,所以还需把刚刚备份的lvm.sql文件导入,才能完整的还原数据:
mysql> set sql_log_bin=0;
mysql> source /tmp/lvm.sql;
mysql> select * from course;
+-----+-------+
| cno | cname |
+-----+-------+
|   1 | Linux |
|   2 | C++   |
|   3 | C     |
|   4 | sql   |
|   5 | A     |
|   6 | HTML  |
|   7 | ARM   |
+-----+-------+

mysql> set sql_log_bin=1;

mysql> show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| www-bin.000001 |      120 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+

其过程总结起来就是:
1.打开会话,施加读锁锁定所有表;
2.打开另一个会话来保存二进制日志文件及其相关位置;
3.创建快照卷;
4.释放锁;
5.挂载快照并备份数据;
6.删除快照;
7.模拟数据库损坏并还原数据;
阅读(397) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~