Xtrabackup只使用InnoDB引擎,在InnoDB内部维护一个redo日志文件,也就是事务日志。该日志会存储每一个InnoDB表数据的修改记录信息。当InnoDB启动的时候,会检查数据文件和事物日志,同时会执行两个步骤: 应用前滚已经提交的事物日志到数据文件,同时将修改过但还没有提交的数据进行回滚
Xtrabackup在启动时就会记录LSN,并且复制所有的数据文件。在复制的过程中,数据会有改动(新加或删除等)。那将会是数据库处于一个不同的时间点。 此时,xtrabackup会运行一个后台进程,用来监控事物日志,并不断从事物日志中复制最新的修改信息。xtrabackup是必须持续的做这个操作,是因为事物日志是会轮转重复的写入的,并且事物日志可以被重复使用。所有xtrabackup在启动的时候,就把事务日志中修改的数据都记录下来了。
Xtrabackup增量备份的原理 1.首先完成一个全备,并记录此时检查点LSN; 2.然后增量备份时,比较表空间中每个页的LSN是不是大于上次备份的LSN,若是则备份改页并记录当时检查点的LSN(日志顺序号) 增量备份 在InnoDB 中,每个page中都记录着LSN-日志顺序号信息,每当数据产生变化,page的LSN就会自动增加,xtrabackupd的增量备份就是依据这一原理进行的。xtrabackup将上次备份以来LSN改变的page进行备份。给予这个原因 所以第一次要做全备,之后可以基于此进行增量备份以及恢复。 增量备份优点: 1.数据库太大没有足够的空间全量备份,增量备份能有效节省空间,且效率高; 2.支持热备份,备份换成不锁表[针对InnoDB],不阻塞数据库的读写; 3.每天只产生少量数据,也可采用远程备份,节省本地空间; 4.备份恢复基于文件操作,降低直接对数据库操作风险; 5.备份效率高,恢复效率也高;
实战xtrabackup-部署 OS:Centos 6.7 application: percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm
#安装依赖 yum install -y perl-DBD-MySQL per-DBI perl-Time-HiRes libaio* rsync perl l perl-Digest-MD5 perl perl-devel libaio libaio-devel #rpm安装会提示缺少.4()(64bit) 解决办法:安装()(64bit) 地址:http://rpmfind.net/linux/RPM/index.html 搜索.4()(64bit),下载 rpm -ivh libev-4.04-2.e16.x86_64.rpm 缺什么都可以在上面的链接找到
#安装库以及主程序 rpm -ivh libev-4.04-2.el6.x86_64.rpm rpm -ivh percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm
#检查安装结果
Xtrabackup 应用参数 常用参数: --user=USER #指定备份用户,不指定的话为当前系统用户 --password=PASSWD #指定备份用户密码 --port=PORT #指定数据库端口 --defaults-group=GROUP-NAME #在多实例的时候使用 --host=HOST #指定备份的主机,可以为远程数据库服务器 --apply-log #回滚日志 --database #指定需要备份的数据库,多个数据库之间以空格分开 --defaults-file #指定mysql的配置文件 --copy-back #将备份数据复制回原始位置 --incremental #增量备份,后面跟要增量备份的路径 --incremental-basedir=DIRECTORY #增量备份时使用指向上一次的增量备份所在的目录 --incremental-dir=DIRECTORY #增量备份还原的时候用来合并增量备份到全量,用来指定全备路径 --redo-only #对增量备份进行合并 --rsync #加快本地文件传输,适用于non-InnoDB数据库引擎。不与--stream 共用 --safe-slave-backup --no-timestamp #生成的备份文件不以时间戳为目录. #创建全备-目录 /home/backup/full #创建增备-目录 /home/backup/inc
#全量备份and 恢复 全量备份 innobackupex --defaults-file=/etc/my.cnf --use-memory=4G --user=root --password='12345678' --socket=/tmp/mysql.sock /home/backup/full innobackupex --defaults-file=/etc/my.cnf --use-memory=4G --user=root --password='lNWj9s0n4c4G2C7L' --socket=/tmp/mysql.sock /home/backup/full lNWj9s0n4c4G2C7L
说明: 上面的命令在我的/data/backup/full 目录生成了一个文件夹【2017-01-20_10-52-43】 一般情况下,这个备份不能用于恢复,因为备份的数据中可能含有尚未提交的事务或者已经提交的事务但尚未同步至数据文件的事务,此时数据文件处于不一致的状态。 因此,我们现在就是要通过回滚未提交的事务及同步已经提交的事务至数据文件也使得数据文件处于一致性状态。
#开启apply-log恢复过程 innobackupex --user=root --password --defaults-file=/etc/my.cnf --apply-log /home/backup/full/2018-08-05_17-58-56
#恢复演练 1)关闭数据库,备份原数据,创建新的数据目录 mv /home/mysql/data /home/mysql/data_bak mkdir -p /home/mysql/data chown mysql.mysql -R /home/mysql/data innobackupex --defaults-file=/etc/my.cnf --copy-back --rsync /home/backup/full/2018-08-05_19-51-06/ 恢复
innobackupex --defaults-file=/etc/my.cnf --copy-back --rsync /home/backup/full
#第一次增量备份 innobackupex --defaults-file=/etc/my.cnf --user=root --password=12345678 --incremental /home/backup/inc --incremental-basedir=/home/backup/full/2018-08-05_21-00-05/
innobackupex --defaults-file=/etc/my.cnf --user=root --password=12345678 --incremental /home/backup/inc1 --incremental-basedir=/home/backup/full/2018-08-07_15-22-53/
--incremental-basedir 指的是完全备份所在的目录
此命令执行结束后,innobackupex命令会在/home/backup/inc1目录中创建一个新的以时间命名的目录以存放所有的增量备份数据。
另外,在执行过增量备份之后再一次进行增量备份时,其--incremental-basedir应该指向上一次的增量备份所在的目录。
需要注意的是,增量备份仅能应用于InnoDB或XtraDB表,对于MyISAM表而言,执行增量备份时其实进行的是完全备份。
检查增量的结果
#第二次增量 mkdir -p /home/backup/inc2 #执行 innobackupex --defaults-file=/etc/my.cnf --user=root --password='12345678' --socket=/tmp/mysql.sock --incremental /home/backup/inc2 --incremental-basedir=/home/backup/inc/2018-08-05_21-11-30
innobackupex --defaults-file=/etc/my.cnf --user=root --password='12345678' --socket=/tmp/mysql.sock --incremental /home/backup/inc2/ --incremental-basedir=/home/backup/inc1/2018-08-07_15-39-15/
innobackupex --defaults-file=/etc/my.cnf --user=root --password='12345678' --socket=/tmp/mysql.sock --incremental /home/backup/inc2 --incremental-basedir=/home/backup/inc1/2018-08-07_15-39-15/ #第三次增量
如果需要恢复的话需要先执行如下操作
innobackupex --apply-log --redo-only /home/backup/full/2018-08-05_21-00-05/ innobackupex --apply-log --redo-only /home/backup/full/2018-08-05_21-00-05 --incremental-dir=/home/backup/inc/2018-08-05_21-11-30/ innobackupex --apply-log --redo-only /home/backup/full/2018-08-07_15-22-53 --incremental-dir=/home/backup/inc1/2018-08-07_15-39-15/
如果存在多次增量备份的话,就多次执行如下命令。此处执行针对的是第二次增量备份
innobackupex --apply-log --redo-only /home/backup/full/2018-08-05_21-00-05 --incremental-dir=/home/backup/inc2/2018-08-05_21-22-02/
恢复演习: 模拟环境,误删两个数据库-进行恢复
drop database db_wifi; drop database performance_schema;
备份: 全备:full innobackupex --defaults-filr=/etc/my.cnf --user=root --password='12345678' --socket=/tmp/mysql.sock /home/backup/full 增备:inc innobackupex --defaults-file=/etc/my.cnf --user=root --password=12345678 --incremental /home/backup/inc --incremental-basedir=/home/backup/full/2018-08-05_21-00-05/
备份过程 一【全备】 innobackupex --defaults-filr=/etc/my.cnf --user=root --password='123456' --socket=/tmp/mysql.sock /home/backup/full innobackupex --defaults-file=/etc/my.cnf --use-memory=4G --socket=/tmp/mysql.sock --user=root --password='NcfmFocqgi2XTvVi' /home/backup/full 二【开启apply-log恢复过程】 innobackupex --defaults-filr=/etc/my.cnf --user=root --password='123456' --apply-log /home/backup/full/2018-09-17_15-09-41 三 【第一次增量】 innobackupex --defaults-file=/etc/my.cnf --user=root --password='123456' --incremental /home/backup/inc1 --incremental-basedir=/home/backup/full/2018-09-17_15-09-41/ 四 【第二次增量】 innobackupex --defaults-file=/etc/my.cnf --user=root --password='123456' --incremental /home/backup/inc2 --incremental-basedir=/home/backup/inc1/2018-09-17_15-14-54/ 五 【第三次增量】 innobackupex --defaults-file=/etc/my.cnf --user=root --password='123456' --incremental /home/backup/inc3 --incremental-basedir=/home/backup/inc2/2018-09-17_15-18-02/ 恢复总结: 增量备份的还原3步骤:1.恢复完整备份;2.恢复增量备份到完整备份(第一个恢复的增量备份要添加--redo-only参数,最后一个恢复的增量备份去掉--redo-only参数);3.对整体的完整备份进行恢复,回滚未提交的数据。 预备增量备份:1.需要先预备全备,但是只重做已提交事务,不回滚未提交事务,然后应用到全备,也是只重做已提交事务,不回滚未提交事务 ;2.回滚未提交事务 1.恢复前需要回滚未提交的事务以及同步已经提交的事务至数据文件使数据文件处于一致性状态 #实例# innobackupex --apply-log --redo-only /home/backup/full/2018-08-05_21-00-05/
2.将增量备份合进全备中-有多个增量备份就相对应执行几次(有点累) 小节点:你想恢复到第几次增备点,就将增备合并进全备中 1+1=2 #实例#-恢复到第一次增量节点 innobackupex --apply-log --redo-only /home/backup/full/2018-08-07_15-22-53 --incremental-dir=/home/backup/inc1/2018-08-07_15-39-15/ 3.停数据库并删除数据 service mysqld.service stop rm -rf /home/mysql/data
4.执行恢复-恢复到你需要的时间上 -注意看后面的事从全备恢复,这是因为第2步已经将增量数据合进全备中啦 innobackupex --defaults-file=/etc//my.cnf --user=root --password=12345678 --copy-back /data/backup/full/2017-01-20_10-52-43 innobackupex --defaults-file=/etc/my.cnf --user=root --password=12345678 --copy-back /home/backup/full/2018-08-08_20-46-16/ 5.赋权要不然数据库起不起来 chown mysql.mysql -R data
总结 第一阶段:检查与连接的准备阶段 执行备份命令之后,备份开始,XtraBackup工具尝试去连接MySQL服务器,连接成功之后,执行MySQL版本检查,版本检查完毕。使用给定的用户、密码、端口、socket文件连接使用5.7.22版本的MySQL服务器。
第二阶段:持续拷贝redo log 这部分内容并没有在备份的输出日志里体现,推测通过开启general log可以看到,也不一定,也许要通过源码才能看到。 修正:我的测试备份环境是一个静止的数据库,在备份时,既没有发生写操作,也没有发生读操作。所以没有看到一直在做"输出看到大量log scanned up to (xxx),对应就是持续扫描redo log"
第三阶段:拷贝ibdata1和ibd文件 xtrabackup进程开始执行一系列工作 1、调用系统函数posix_fadvise(),该函数是用来清理缓存的,不太理解此处使用的意图?了解的童鞋给我科普下,谢谢。 2、进入到/data/mysql/mysql3306/data目录下面 3、把打开文件请求限制调整为65535 4、使用以下InnoDB配置: innodb_data_home_dir = . #innodb数据存放在当前目录 innodb_data_file_path = ibdata1:100M:autoextend #innodb共享表空间文件为1个,初始大小为100M,类型为自动扩展 innodb_log_group_home_dir = ./ #innodb日志文件存放在当前目录 innodb_log_files_in_group = 3 #innodb日志文件个数为3个 innodb_log_file_size = 104857600 #innodb日志文件大小为100M 5、使用O_DIRECT标志,目的为绕过缓冲区高速缓存,直接把数据传递到文件或设备,实际就是无需缓存来拷贝数据 6、默认使用单线程进行备份 7、日志扫描到2643241字节的位置 8、形成一个表表空间的列表 9、为mysql/plugin分配表空间为2,旧的最大值是0 10、把ibdata1文件拷贝到备份目录下面,直到完成 11、把ibd文件拷贝到备份目录下面,直到所有的ibd文件拷贝完成
第四阶段:备份非事务表的准备阶段 innobackupex进程开始执行一系列工作 1、扫描日志文件到2643241,这是已经写入redo的LSN 2、执行FLUSH TABLES,关闭所有打开的表,使用NO_WRITE_TO_BINLOG选项,也就是该语句不会被记录到binlog里面 3、执行FTWRL,使用全局读锁来锁定整个实例
第五阶段:备份非事务表 开始拷贝非innodb引擎表和文件,包括所有的.frm文件等,直到所有的都拷贝完成 修正: .frm文件:保存了每个表的元数据,包括表结构的定义等; .ibd文件:InnoDB引擎开启了独立表空间(my.ini中配置innodb_file_per_table = 1)产生的存放该表的数据和索引的文件。
第六阶段:整个备份完成后的后续工作 1、开始写xtrabackup_binlog_info文件,此处推测,获取执行过的GTID值和位点信息的语句在general log里面有记录 2、执行引擎的日志刷新,也就是把日志刷新到磁盘 3、最后的检查点是2643232字节的位置,也就是数据持久化到的LSN 4、停止拷贝线程 5、扫描日志文件到2643241 6、执行UNLOCK TABLES,释放全局读锁 7、开始拷贝ib_buffer_pool,直到拷贝完成,这是一堆数字,不知道做什么用处,了解的童鞋给我科普下,谢谢。 修正:拷贝缓冲池里的数据,以备恢复后,可以快速加载和预热访问量最高的数据。 8、打印出备份结束的位点和执行过的GTID值 9、写backup-my.cnf文件 10、写xtrabckup_info 11、LSN从2643232到2643241的事务日志拷贝完成 12、打印备份成功的标志,completed OK!
故障记录: InnoDB: Error number 24 means 'Too many open files' 网上解释
修改ulimit ulimit -n 65535 使用 ulimit -n 65535 可即时修改,但重启后就无效了。(注ulimit -SHn 65535 等效 ulimit -n 65535,-S指soft,-H指hard) 有如下三种修改方式: 1.在/etc/rc.local 中增加一行 ulimit -SHn 65535 2.在/etc/profile 中增加一行 ulimit -SHn 65535 3.在/etc/security/limits.conf最后增加如下两行记录
- soft nofile 65535
- hard nofile 65535
















