实验环境 centos6.4 x86_64 ,mysql编译安装 版本5.5.37
系统关闭 防火墙 seLinux
一 测试环境准备
1.1 编辑/etc/my.cnf 把二进制日志存放到其他非数据目录,innodb每表一个表空间
建立存放 二进制日志 目录
mkdir /binlog
chown mysql:mysql /binlog
修改my.cnf
vim /etc/my.cnf
log-bin = /binlog/mysql-bin #配置文件有此选项直接修改即可,不用添加
innodb_file_per_table = 1
重启mysqld
service mysqld restart
1.2 创建测试数据库与测试表
mysql> create database db;
mysql> use db;
mysql> create table db1(id int primary key auto_increment,name varchar(10),phone int,sex char(10));
mysql> insert into db1 (name,phone,sex) values ('tom',1123213,'m');
mysql> insert into db1 (name,phone,sex) values ('jar',1123,'m');
mysql> insert into db1 (name,phone,sex) values ('xiaozhang',1127,'m');
1.3 创建用于存放备份目录
mkdir /backup
chown �CR mysql:mysql /backup
二 用mysqldump备份
案例1 备份单一数据库,删除后,恢复
1 备份数据库
mysqldump -uroot -predhat --master-data=2 --databases db > /backup/db.sql
2 删除数据库
mysql> drop database db;
3 恢复数据库
mysql> source /backup/db.sql # 如恢复不成功,可先建立数据库,再恢复
案例2 完整备份+增量备份+二进制日志
1 完整热备份
mysqldump -uroot -predhat --single-transaction --events --routines --triggers --master-data=2 --databases db >/backup/db_`date +%F`.sql
2 假设第二天 做一些相关操作,做增量备份
mysql> create table db2(id int);
mysql> insert into db2 values (1),(2);
查看当前日志文件位置
mysql> show master status;
+--------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------+----------+--------------+------------------+
| mysql.000010 | 13452 | | |
+--------------+----------+--------------+------------------+
查看上次完整备份 日志文件位置
less db_2014-06-20.sql
CHANGE MASTER TO MASTER_LOG_FILE='mysql.000010', MASTER_LOG_POS=12977;
做增量备份
mysqlbinlog --start-position=12977 --stop-position=13452 mysql.000010 > /backup/db_`date +%F_%H`.sql
3假设第三天 出现故障 恢复数据库
mysql> insert into db2 values (3),(4);
mysql> insert into db2 values (5),(6),(7),(8);
mysql> drop database db;
恢复数据
mysql>show master status;
查看当前日志位置 如 mysql.000017
mysqlbinlog mysql.000017
找到最后操作正确的位置
mysqlbinlog --start-position=13452 --stop-position=13828 mysql.000010 > /tmp/db.sql
mysql> set sql_log_bin=0; #关闭二进制日志
mysql> flush logs;
mysql -uroot -predhat < /backup/db_2014-06-20.sql
mysql -uroot -predhat < /backup/db_2014-06-20_18.sql
mysql -uroot -predhat < /tmp/db.sql
mysql> flush privileges; 重读授权文件
mysql> set sql_log_bin=1
三 LVM 快照 备份 恢复
( 事务日志和快照必须在一个逻辑卷上)
( sync_binlog =1 防止事务丢失,事务提交,立即同步到磁盘 一般不设为1 备份完成 重新改为 0 )
1 迁移数据库至LVM
备份数据库
mysqldump -uroot -predhat --lock-all-tables --all-databases --routines --triggers --events > /backup/db_all_`date +%F`.sql
停止mysqld
service mysqld stop
删除原数据库
rm �Crf /mydata/*
创建LVM 过程略
建立LVM卷,挂载到/mydata/data
初始化mysql的数据目录 /mydata/data
Vim /etc/my.cnf
sync_binlog=1
恢复数据
mysql> set sql_log_bin=0;
mysql> source /backup/db_all_2014-06-20.sql
mysql> flush priviledges; # 密码生效
mysql> set sql_log_bin=1;
2 快照 备份
mysql> flush tables with read lock; #把所有表从内存刷新到磁盘 ,并请求全局锁
mysql> flush logsl;
mysql> show master status;
+--------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------+----------+--------------+------------------+
| mysql.000017 | 107 | | |
+--------------+----------+--------------+------------------+
1 row in set (0.00 sec)
不要退出此会话
另开一个会话
保存当前日志位置
mysql -uroot -predhat -e 'show master status' > /backup/binlog.txt
创建快照
lvcreate -L 100M -s -p r -n mydata-snap /dev/myvg/mydata
在前一个会话中 释放读锁
mysql > unlock tables;
挂载快照,拷贝出来,卸载快照,删除快照
mount /dev/myvg/mydata /mnt
mkdir /backup/lvm
cp -pR /mnt/* /backup/lvm/
umont /mnt
lvremove /dev/myvg/mydata-snap
测试数据
service mysqld stop
rm -rf /mydata/data/*
cp -Rp /backup/lvm/data/* /mydata/data/
service mysqld start
恢复后 数据如不完整 ,可使用二进制日志恢复
mysqlbinlog --start-position=107 mysql.000017 > /backup/snap.sql;
mysql> set sql_log_bin=0;
mysql> source /backup/snap.sql
mysql> set sql_log_bin=1;
四 xtrabackup
1 下载安装 xtrabackup
yum install libaio
yum install perl-dbd-mysql
yum install perl-Time-HiRes
rpm �Civh percona-xtrabackup-2.1.4-656.rhel6.x86_64.rpm
2 为备份建立一个只有备份权限的用户
mysql> create user 'user'@'localhost' identified by '1234567';
mysql> revoke all privileges ,grant option from 'user'@'localhost';
mysql> grant reload,lock tables,replication client on *.* to 'user'@'localhost';
mysql> flush privileges;
案例1 完整备份mysql
1 完整备份
innobackupex -uroot -predhat /backup/
数据会完整备份到/backup/ 以当期日期时间为目录名的目录下面
(1)xtrabackup_checkpoints ―― 备份类型(如完全或增量)、备份状态(如是否已经为prepared状态)和LSN(日志序列号)范围信息;
每个InnoDB页(通常为16k大小)都会包含一个日志序列号,即LSN。LSN是整个数据库系统的系统版本号,每个页面相关的LSN能够表明此页面最近是如何发生改变的。
(2)xtrabackup_binlog_info ―― mysql服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置。
(3)xtrabackup_binary ―― 备份中用到的xtrabackup的可执行文件;
(4)backup-my.cnf ―― 备份命令用到的配置选项信息;
2 停止mysql服务,删除数据库
service mysqld stop
rm �Crf /mydata/data
3 准备恢复阶段
innobackupex --apply-log /backup/2014-06-21_09-35-21/
--apply-log 把未提交的事务回滚,已提交的事务同步到磁盘
4 恢复数据库
innobackupex --copy-back /backup/2014-06-21_09-35-21/
5 修改数据库目录
chown �CR mysql:mysql /mydata/data
6 重启服务
service mysqld start
7 再次做完全备份 每次恢复数据后要重新做一个完全备份
innobackupex -uroot -predhat /backup/
案例2 完整备份 +增量备份+二进制日志
假设第一天 做完整备份
innobackupex -uroot -predhat /backup/
第二天 做增量备份
innobackupex --user=root --password=redhat --incremental /backup/ --incremental-basedir=/backup/2014-06-21_10-40-36/
--incremental-basedir 指定基于那个完整备份做增量
第三天 数据库崩溃
数据库服务停止,删空数据库目录
准备恢复数据
innobackupex --apply-log --redo-only /backup/2014-06-21_10-40-36/
--redo-only 未提交的事务不回滚,这个事务可能在增量备份中提交
innobackupex --apply-log --redo-only /backup/2014-06-21_10-40-36/ --incremental-dir=/backup/2014-06-21_10-48-58/
把增量备份添加到完整备份
恢复数据
innobackupex --copy-back /backup/2014-06-21_10-40-36
chown -R mysql:mysql /mydata/data
service mysql start
此时数据应该恢复到第二天 ,如要恢复第三天的数据 可利用二进制日志
进入完整备份目录
cat xtrabackup_binlog_info
mysql.000020 288
查看上次增量备份 二进制日志文件 位置
mysqlbinlog --start-position=288 mysql.000020 > /backup/db.sql
mysql> set sql_log_bin=0;
mysql> source /backup/db.sql
mysql> set sql_log_bin=1;