对于不少运维同行来讲,平时管理mysql除了应开的需求查询一些数据条目和监控性能外,更多的则是为了保证数据的可靠性对其进行备份和复制的操做管理, 不过最近听很多同行都说如今的互联网已经进入了缓存和nosql为王的时代,大可取代mysql这种关系型数据库,不得不认可在大量甚至海量的业务且要求数据即时响应回馈的场景中,如微信,微博,缓存和nosql的重要性和性能体现(如redis),但要说取代mysql的话,我只能表示:呵呵mysql
其实mysqldump这种热备+逻辑的备份方式被应用的仍是蛮多的,但其单线程的工做模式及生成sql写入文件的这种方式,与文件系统级别的物理备份相比,效率就显得有些差了。
redis
这里介绍一下innodb的开源备份工具Xtrabackup,至于说其实现物理热备的原理,简单来讲其理解innodb底层存储机制,相似逐页请求锁定,不会产生阻塞和按数据块来备份。percona官网对其和Innodb Hot Backup的所支持的功能和各项参数作了较详细的对比,有兴趣的朋友能够看一下,地址 http://www.percona.com/software/percona-xtrabackup,固然了,他们不免有些王婆卖瓜之嫌,但我感受人家敢明目张胆的贴出来和Innodb Hot Backup进行叫板,并且也没被mysql官方惹上什么官司,就已经说明人家的实力了吧。若是平常工做中对mysql或者说innodb类的库操做比较多的,建议你们多了解和关注一下percona的官网。其对Xtrabackup的推荐介绍中有如下几点:sql
Backups that complete quickly and reliablyshell
Uninterrupted transaction processing during backups数据库
Savings on disk space and network bandwidthcentos
Automatic backup verification缓存
Higher uptime due to faster restore time服务器
简单理解的话就是:微信
快速可靠的彻底备份网络
备份过程当中不会打扰到事务操做
能执行压缩数据流网络传输,有效节省带宽和磁盘资源
自动备份校验
恢复速度比较快
既然优势这么多,咱们来认识和使用一下这个工具,使用以前,请确实mysql的版本为5.5+,若是安装报错相似:perl(Time:HiRes),用yum安装上便可,若是想使用其一些高级特性比较导入导出单张表,那就请在配置文件中设置innodb_file_per_table = 1(对每一个新建立的表生成并使用单独的表空间)。可以使用官方提供的rpm包直接安装,下载地址: http://www.percona.com/downloads/XtraBackup/
个人操做系统环境为centos6.2_64位,mysql版本为5.5.33
yum -y install perl-Time-HiRes
rpm -ivh percona-xtrabackup-2.1.4-656.rhel6.x86_64.rpm
看一下安装的文件,其中innobackupex为主命令程序,使用时会自行判断你的mysql版本是5.5仍是5.6,使用innobackupex --help可查看其使用的语法格式。
[root@gzy ~]# rpm -ql percona-xtrabackup /usr/bin/innobackupex /usr/bin/innobackupex-1.5.1 /usr/bin/xbcrypt /usr/bin/xbstream /usr/bin/xtrabackup /usr/bin/xtrabackup_55 /usr/bin/xtrabackup_56 /usr/share/doc/percona-xtrabackup-2.1.4 /usr/share/doc/percona-xtrabackup-2.1.4/COPYING
建立一个适用于备份操做的最小权限用户:
mysql> grant reload,lock tables,replication client on *.* to 'backup'@'localhost' identified by '123456'; Query OK, 0 rows affected (0.30 sec) mysql> flush privileges; Query OK, 0 rows affected (0.08 sec)
接下来具体使用和测试一下备份innodb类型的库,演示一下彻底+增量备份,最后用彻底+增量+二进制日志恢复的过程。
innobackupex --user=backup -password=123456 /backup/
用户是以前建立的备份用户,/backup/是备份的目录,在执行过程当中会打印不少执行时的信息,若是执行成功的话,最后会显示:
innobackupex: Backup created in directory '/backup/2014-02-17_01-09-48' innobackupex: MySQL binlog position: filename 'mysql-bin.000021', position 354 140217 01:09:57 innobackupex: Connection to database server closed 140217 01:09:57 innobackupex: completed OK!
发现了吗?自动在咱们的备份目录下建立了个以当前日期和时间命名格式的目录,查看一下,发现除了备份的相关库和数据文件以外,还生成了一些xtrabackup相关文件。
[root@gzy ~]# ll /backup/2014-02-17_01-09-48/ total 26664 -rw-r--r--. 1 root root 260 Feb 17 01:09 backup-my.cnf -rw-r-----. 1 root root 27262976 Feb 17 01:09 ibdata1 drwxr-xr-x. 2 root root 4096 Feb 17 01:09 mydb drwxr-xr-x. 2 root root 4096 Feb 17 01:09 mysql drwxr-xr-x. 2 root root 4096 Feb 17 01:09 performance_schema drwxr-xr-x. 2 root root 4096 Feb 17 01:09 test -rw-r--r--. 1 root root 13 Feb 17 01:09 xtrabackup_binary -rw-r--r--. 1 root root 23 Feb 17 01:09 xtrabackup_binlog_info -rw-r-----. 1 root root 89 Feb 17 01:09 xtrabackup_checkpoints -rw-r-----. 1 root root 2560 Feb 17 01:09 xtrabackup_logfile drwxr-xr-x. 2 root root 4096 Feb 17 01:09 zabbix
这里对其工做流程作一下说明,首先,使用innobakupex备份时,其会调用xtrabackup备份全部的InnoDB表,复制全部关于表结构定义的相关文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相关文件,同时还会备份触发器和数据库配置信息相关的文件。这些文件会被保存至一个以时间命令的目录中。
xtrabackup_checkpoints : 备份类型(如彻底或增量)、备份状态(如是否已经为prepared状态,这个为准备工做,包括事务日志和数据文件,把事务日志中已提交的事务同步至数据文件,未提交的进行回滚)和LSN(日志序列号)范围信息;每一个InnoDB页(一般为16k大小)都会包含一个日志序列号,即LSN。LSN是整个数据库系统的系统版本号,每一个页面相关的LSN可以代表此页面最近是如何发生改变的。查看一下其内容:
[root@gzy ~]# cd /backup/2014-02-17_01-09-48/ [root@gzy 2014-02-17_01-09-48]# cat xtrabackup_checkpoints backup_type = full-backuped # 表示备份类型为彻底备份 from_lsn = 0 # LSN号从0开始 to_lsn = 5618613 # LSN号到0结束 last_lsn = 5618613 # 最后的lsn号,换句话说,一会进行增量备份时会以这个数字开始,能够理解为 xtrabackup为每次备份打的开始和结束的标记 compact = 0 # 0表示未启用压缩
xtrabackup_binlog_info: mysql服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置。这个容易理解:
[root@gzy 2014-02-17_01-09-48]# cat xtrabackup_binlog_info mysql-bin.000021 354
xtrabackup_binary:备份中用到的xtrabackup的可执行文件,由于mysql版本是5.5,因此其调用的是/usr/bin/xtrabackup_55
[root@gzy 2014-02-17_01-09-48]# cat xtrabackup_binary xtrabackup_55
backup-my.cnf:备份命令用到的配置选项信息,也就是my.cnf配置文件中定义的相关参数
[root@gzy 2014-02-17_01-09-48]# cat backup-my.cnf # This MySQL options file was generated by innobackupex. # The MySQL server [mysqld] innodb_data_file_path=ibdata1:10M:autoextend innodb_log_files_in_group=2 innodb_log_file_size=5242880 innodb_fast_checksum=0 innodb_page_size=16384 innodb_log_block_size=512
接下来咱们添加一个叫test1的用户,而后进行一次增量备份。
mysql> grant all on *.* to 'test1'@'localhost' identified by '123456'; Query OK, 0 rows affected (0.04 sec) mysql> flush privileges; Query OK, 0 rows affected (0.07 sec) mysql> select Host,User,Password from mysql.user; +------------------+--------+-------------------------------------------+ | Host | User | Password | +------------------+--------+-------------------------------------------+ | localhost | root | *2CF528CA7B474EC019B52035BDF52F143D939DBA | | gzy.tongzhou.com | root | *2CF528CA7B474EC019B52035BDF52F143D939DBA | | 127.0.0.1 | root | *2CF528CA7B474EC019B52035BDF52F143D939DBA | | % | zabbix | *2CF528CA7B474EC019B52035BDF52F143D939DBA | | localhost | backup | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | localhost | test1 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | +------------------+--------+-------------------------------------------+ 6 rows in set (0.01 sec)
每一个InnoDB的页面都会包含一个LSN信息,每当相关的数据发生改变,相关的页面的LSN就会自动增加。这正是InnoDB表能够进行增量备份的基础,即innobackupex经过备份上次彻底备份以后发生改变的页面来实现。
增量备份的语法: innobackupex --incremental /backup --incremental-basedir=BASEDIR
其中,BASEDIR指的是彻底备份所在的目录,此命令执行结束后,innobackupex命令会在/backup目录中建立一个新的以时间命名的目录以存放这次增量备份数据。--incremental意思是类型为增量备份,另外,在执行过增量备份以后再一次进行增量备份时,其--incremental-basedir应该指向上一次的增量备份所在的目录。
innobackupex -user=backup -password=123456 --incremental /backup/ --incremental-basedir=/backup/2014-02-17_01-09-48/
备份成功会显示相关内容的,以及LSN号,备份生成的目录,及二进制日志文件及其pos点信息
xtrabackup: The latest check point (for incremental): '5618623' xtrabackup: Stopping log copying thread. .>> log scanned up to (5618623) xtrabackup: Transaction log of lsn (5618623) to (5618623) was copied. 140217 13:26:48 innobackupex: All tables unlocked innobackupex: Backup created in directory '/backup/2014-02-17_13-26-38' #这次增量生成的数据目录 innobackupex: MySQL binlog position: filename 'mysql-bin.000021', position 574 140217 13:26:48 innobackupex: Connection to database server closed 140217 13:26:48 innobackupex: completed OK!
接下来咱们再进入mysql建立一个用户test2
mysql> grant all on *.* to 'test2'@'localhost' identified by '123456'; Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; Query OK, 0 rows affected (0.01 sec) mysql> select Host,User,Password from mysql.user; +------------------+--------+-------------------------------------------+ | Host | User | Password | +------------------+--------+-------------------------------------------+ | localhost | root | *2CF528CA7B474EC019B52035BDF52F143D939DBA | | gzy.tongzhou.com | root | *2CF528CA7B474EC019B52035BDF52F143D939DBA | | 127.0.0.1 | root | *2CF528CA7B474EC019B52035BDF52F143D939DBA | | % | zabbix | *2CF528CA7B474EC019B52035BDF52F143D939DBA | | localhost | backup | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | localhost | test1 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | localhost | test2 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | +------------------+--------+-------------------------------------------+ 7 rows in set (0.00 sec)
查看一下当前使用的二进制日志:
mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000021 | 794 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec)
接下来把这个二进制日志备份到别处,并删除mysql的数据目录来进行恢复测试,此时并无再进行增量备份的操做哦!(注意!!!生产环境中mysql的二进制日志文件与数据文件的有同等的重要性!因此其保存路径必定要与mysql的数据目录区分开的,且在硬件级别最少保证raid1,固然了使用mysql的复制结构如主从,多主等模型也是不可少的)
个人mysql 数据目录为/data
[root@gzy ~]# cp /data/mysql-bin.000021 /tmp [root@gzy ~]# ls /data/ gzy.tongzhou.com.err mysql mysql-bin.000006 mysql-bin.000012 mysql-bin.000018 test gzy.tongzhou.com.pid mysql-bin.000001 mysql-bin.000007 mysql-bin.000013 mysql-bin.000019 zabbix ibdata1 mysql-bin.000002 mysql-bin.000008 mysql-bin.000014 mysql-bin.000020 ib_logfile0 mysql-bin.000003 mysql-bin.000009 mysql-bin.000015 mysql-bin.000021 ib_logfile1 mysql-bin.000004 mysql-bin.000010 mysql-bin.000016 mysql-bin.index mydb mysql-bin.000005 mysql-bin.000011 mysql-bin.000017 performance_schema
接下来中止mysql进程并删除/data......
Shutting down MySQL.... SUCCESS! [root@gzy ~]# rm -rf /data/* [root@gzy ~]#
如今四大皆空了,接下来用刚才建立的彻底备份+增量备份+二进制日志来进行恢复操做。
首先将已提交的事务进行“重放”,以后全部的增量备份数据将合并到彻底备份上,全部备份数据中未提交的事务进行“回滚”。
先进行彻底备份的准备:
innobackupex --apply-log --redo-only /backup/2014-02-17_01-09-48/
再进行增量备份的准备:
innobackupex --apply-log --redo-only /backup/2014-02-17_01-09-48/ --incremental-dir=/backup/2014-02-17_13-26-38/
确保2次操做都出现成功的提示:
completed OK!
由于增量备份的数据都已合并到彻底备份中去了,因此此时只恢复彻底备份便可
innobackupex --copy-back /backup/2014-02-17_01-09-48/
再来查看一下数据目录/data
[root@gzy ~]# ll /data/ total 26644 -rw-r--r--. 1 root root 27262976 Feb 17 14:10 ibdata1 drwxr-xr-x. 2 root root 4096 Feb 17 14:10 mydb drwxr-xr-x. 2 root root 4096 Feb 17 14:10 mysql drwxr-xr-x. 2 root root 4096 Feb 17 14:10 performance_schema drwxr-xr-x. 2 root root 4096 Feb 17 14:10 test drwxr-xr-x. 2 root root 4096 Feb 17 14:10 zabbix
貌似恢复回来了?!好吧,把该目录的属主属组变成mysql后启动一下服务试试
[root@gzy ~]# chown mysql.mysql /data -R [root@gzy ~]# service mysqld start Starting MySQL........ SUCCESS!
提示启动成功,咱们进入mysql来查看一下刚才咱们所建立的测试用户是否存在: