一、percona-xtrabackup
它是开源免费的支持MySQL 数据库热备份的软件,它能对InnoDB和XtraDB存储引擎的数据库非阻塞地备份。它不暂停服务创建Innodb热备份;
为mysql做增量备份;在mysql服务器之间做在线表迁移;使创建replication更加容易;备份mysql而不增加服务器的负载。
percona是一家老牌的mysql技术咨询公司。它不仅提供mysql的技术支持、培训、咨询,还发布了mysql的分支版本--percona Server。并围绕
percona Server还发布了一系统的mysql工具。
innobackupex比xtarbackup有更强的功能,它整合了xtrabackup和其他的一些功能,他不但可以全量备份/恢复,还可以基于时间的增量备份与恢复。
innobackupex备份原理
innobackupex首先调用xtrabackup来备份innodb数据文件,当xtrabackup完成后,innobackupex就查看文件 xtrabackup_suspended ;然后执行“FLUSH TABLES WITH READ LOCK”来备份其他的文件
innobackupex恢复原理
innobackupex首先读取my.cnf,查看变量
(datadir,innodb_data_home_dir,innodb_data_file_path,innodb_log_group_home_dir)
对应的目录是存在,确定相关目录存在后,然后先copy myisam表和索引,然后在copy innodb的表、索引和日志。
=========================================================================
环境:
centos6.6
数据库:mysql5.5.16
xtrabackup:v1.5.1
=========================================================================
1)完整备份
innobackupex --defaults-file=/etc/my.cnf --user=root --password=PASSWORD --database=DATE BACK_DIR_PATH
1. # PASSWORD 数据库密码
2. # DATE 数据库名
3. # --database=DATE 针对所有库做备份去掉该选项即可
4. # BACK_DIR_PATH 完全备份目录位置
5. 注:该命令执行后会在备份目录位置以当前时间为命名生成一个目录,备份的文件会备份到该目录中。例如2014-12-06_16-00-15
6. #--port=端口号
7. #--no-timestamp 此参数可以取消自动时间戳
2)完整备份的恢复
首先需要备份数据库
停止数据库运行
删除数据库目录内所有文件
然后执行下列命令进行恢复
恢复第一步:应用日志。
innobackupex --defaults-file=/etc/my.cnf --user=root --password=PASSWORD --database=DATE --apply-log BACK_DIR_PATH/
你的全备数据库文件名
参数:
# PASSWORD 数据库密码
# DATE 数据库名
# BACK_DIR_PATH 完全备份目录位置
#恢复第二步:拷贝文件。
innobackupex --defaults-file=/etc/my.cnf --user=root --password=PASSWORD --database=DATE --copy-back /BACK_DIR_PATH
注释一下,常用的参数。
--defaults-file=/etc/my.cnf 恢复会使用my.cnf文件把需要恢复的文件,恢复到my.cnf指定的位置。
--apply-log 这是备份时产生的日志,
--copy-back 这是备份源,解压后的备份文件。
--database=DATE 如果不加此参数,默认恢复全部数据库
提示:如果重启服务报错。文章结尾有解决办法。
3)增量备份
innobackupex --defaults-file=/etc/my.cnf --user=root --password=PASSWORD --database=DATE --incremental-basedir=BACK_DIR_PATH/全备数据库的文件名 --incremental BACK_DIR_ZENG_1
2. # PASSWORD 数据库密码
3. # DATE 数据库名
4. # BACK_DIR_PATH 完全备份目录位置
5. # BACK_DIR_ZENG_1 第一次增量备份目录位置
6. # --incremental-basedir 该选项后面写的为第一次完整备份的路径
7. 注:此次增量备份是在第一次完整备份的基础之上进行的增量备份
4)第二次增量备份
innobackupex --defaults-file=/etc/my.cnf --user=root --password=PASSWORD --database=DATE --incremental-basedir=BACK_DIR_ZENG_1 --incremental BACK_DIR_ZENG_2
2. # PASSWORD 数据库密码
3. # DATE 数据库名
4. # BACK_DIR_PATH 完全备份目录位置
5. # BACK_DIR_ZENG_1 第一次增量备份目录位置
6. # BACK_DIR_ZENG_2 第二次增量备份目录位置
7. # --incremental-basedir 该选项后面写的为第一次增量备份的路径
8. 注:此次增量备份是在第一次增量备份的基础之上进行的第二次增量备份
5)多次增量备份之后的恢复
1、首先需要备份现有数据库
2、停止数据库运行
3、删除数据库目录内所有文件
4、然后执行下列命令进行恢复
先恢复第一次全备的数据库的应用日志
命令:
innobackupex --defaults-file=/etc/my.cnf --user=root --password='密码' --apply-log --redo-only BACK_DIR_PATH
恢复第一次增量备份的数据库应用日志
innobackupex --defaults-file=/etc/my.cnf --user=root --password='密码' --apply-log --redo-only BACK_DIR_PATH --incremental-dir=BACK_DIR_ZENG_1
恢复第二次增量备份的数据库应用日志
innobackupex --defaults-file=/etc/my.cnf --user=root --password='密码' --apply-log BACK_DIR_PATH --incremental-dir=BACK_DIR_ZENG_2
1. # BACK_DIR_PATH 完全备份目录位置
2. # BACK_DIR_ZENG_1 第一次增量备份目录位置
3. # BACK_DIR_ZENG_2 第二次增量备份目录位置
4. 注: 如果只有2次增量备份则执行此条命令,如果有多次增量命令,则参照上一条命令
5. 最后一次恢复的时候不需要加--redo-only这个参数。
=========================================================================
恢复第三步:
修改文件权限。
cd 到data目录
chown -R mysql.mysql data、
可能出现的报错:
1、出现下面错误,
# ./mysql.server start Starting MySQL...The server quit without updating PID file (/u01/mysql/data/newbidb.pid).[FAILED]
初始化一下mysql
# ./mysql_install_db --basedir=/你的mysql 目录 --no-defaults --skip-name-resolve --user=mysql --datadir=/你的数据存放目录
2、权限:应该恢复使用的是root用户,但是MySQL需要MySQL用户去访问。
# ./mysql.server restart MySQL server PID file could not be found![FAILED] Starting MySQL.The server quit without updating PID file (/u01/mysql/data/newbidb.pid).[FAILED]
3、连接MySQL的时候
#./mysql -uroot -p Enter password: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
有这个文件,touch mysql.sock 并修改文件权限。
恢复备份文件要保证datadir文件为空,否则会报如下的错误
# innobackupex --user=root /data/backup/ IMPORTANT: Please check that the copy-back run completes successfully. At the end of a successful copy-back run innobackupex prints "completed OK!". Original data directory is not empty! at /usr/bin/innobackupex line 568.
=========================================================================
实例脚本:
脚本是每周天整备,周一到周六增倍
自动判断是否存在昨天和今天的数据来进行全备或者增倍
#!/bin/bash export PATH=$PATH:/usr/local/xtrabackup/bin HOST=127.0.0.1 DATE=`date +"%Y-%m-%d-%A"` LASTDATE=`date +"%Y-%m-%d-%A" -d "-1 days"` DATEDAY=`date +%A` WEEKDAY='Sunday' BACKUP_DIR_PATH=/要备份的目录 FILE_CNF=/usr/local/mysql55/conf/配置文件 USER_NAME=用户名 PASSWORD="密码" MYPORT=端口号 #全备备份函数 cd $BACKUP_DIR_PATH all_bak () { echo "start $DATE-all" >> $BACKUP_DIR_PATH/access.log innobackupex --defaults-file=$FILE_CNF --user=$USER_NAME --password=$PASSWORD --port=MYPORT --host=$HOST --no-timestamp $BACKUP_DIR_PATH/$DATE-all if [ $? -eq 0 ];then echo "$DATE-all is succeed" >> $BACKUP_DIR_PATH/access.log tar -zcvf $BACKUP_DIR_PATH/$DATE-all.tar.gz $DATE-all if [ $? -eq 0 ];then echo "$DATE-all is packaging succeed" >> $BACKUP_DIR_PATH/access.log # rm -rf $DATE-all else echo "$DATE-all is packaging failure" >> $BACKUP_DIR_PATH/access.log fi else echo "$DATE-all is failure" >> $BACKUP_DIR_PATH/access.log fi echo "stop $DATE-all" >> $BACKUP_DIR_PATH/access.log } #增量备份函数 incremental(){ echo "start $DATE-incremental" $BACKUP_DIR_PATH/access.log innobackupex --defaults-file=$FILE_CNF --user=$USER_NAME --password=$PASSWORD --port=MYPORT --host=$HOST --incremental-basedir=$BACKUP_DIR_PATH/$LASTDATE-$1 --no-timestamp --incremental $BACKUP_DIR_PATH/$DATE-incremental if [ $? -eq 0 ];then echo "$DATE-incremental is succeed" >> $BACKUP_DIR_PATH/access.log tar -zcvf $BACKUP_DIR_PATH/$DATE-incremental.tar.gz $DATE-incremental if [ $? -eq 0 ];then echo "$DATE-incremental is packaging succeed" >> $BACKUP_DIR_PATH/access.log # rm -rf $DATE-incremental else echo "$DATE-ncremental is packaging failure" >> $BACKUP_DIR_PATH/access.log fi else echo "$DATE-incremental is failure" >> $BACKUP_DIR_PATH/access.log fi echo "stop $DATE-incremental" >> $BACKUP_DIR_PATH/access.log } #判断数据库备份存放目录,不存在创建 if [ ! -d $BACKUP_DIR_PATH ];then mkdir $BACKUP_DIR_PATH fi #判断如果今天是周天,那么全备,否则增备 if [ $DATEDAY = $WEEKDAY ];then if [ ! -d "$BACKUP_DIR_PATH/$DATE-all" ];then all_bak fi else #判断昨天的数据是否存在 if [ ! -d "$BACKUP_DIR_PATH/$LASTDATE-all" ];then if [ ! -d "$BACKUP_DIR_PATH/$LASTDATE-incremental" ];then if [ ! -d "$BACKUP_DIR_PATH/$DATE-all" ];then if [ ! -d "$BACKUP_DIR_PATH/$DATE-incremental" ];then all_bak fi fi else if [ ! -d "$BACKUP_DIR_PATH/$DATE-incremental" ];then incremental incremental fi fi else #如果昨天是全备,今天增量不存在,那么进行增量备份 if [ ! -d "$BACKUP_DIR_PATH/$DATE-incremental" ];then incremental all fi fi fi