因为percona打算放弃使用innobackupex备份工具,因此我们这里也说明一下innobackupex的兄弟工具xtraceback工具的使用
这个工具的安装可以参考上面的一些博文,上面详细说明了innobackupex的备份与使用:https://www.cnblogs.com/wxzhe/p/10033983.html
首先我们来看一下xtracbackup的帮助文档:
[root@test3 ~]# xtrabackup --help xtrabackup: recognized server arguments: xtrabackup: recognized client arguments: --user=root --password=* --user=root --password=* --host=localhost xtrabackup version 2.4.12 based on MySQL server 5.7.19 Linux (x86_64) (revision id: 170eb8c) Open source backup tool for InnoDB and XtraDB ...... Usage: [xtrabackup [--defaults-file=#] --backup | xtrabackup [--defaults-file=#] --prepare] [OPTIONS] Default options are read from the following files in the given order: /etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf The following groups are read: xtrabackup mysqld The following options may be given as the first argument: ....... 后面是一些参数信息
xtracebackup是一款物理的在线备份工具,那么其备份的原理是什么?我们应该知道在备份过程数据时可以写入的。
xtracebackup的备份过程详解:http://www.cnblogs.com/zhoujinyi/p/5888271.html
下面通过实例来说明使用xtracebackup的备份与恢复
[root@test3 backup]# xtrabackup --user=root --password=123456 --backup --target-dir=backup/ xtrabackup: recognized server arguments: xtrabackup: recognized client arguments: --user=root --password=* --user=root --password=* --host=localhost --user=root --password=* --backup=1 --target-dir=backup/ 181230 11:39:15 version_check Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_group=xtrabackup;host=localhost' as 'root' (using password: YES). Failed to connect to MySQL server: DBI connect(';mysql_read_default_group=xtrabackup;host=localhost','root',...) failed: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) at - line 1314 181230 11:39:15 Connecting to MySQL server host: localhost, user: root, password: set, port: not set, socket: not set Failed to connect to MySQL server: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2).
#这个报错是因为MySQL5.7是源码安装,sock文件不在默认的/var/lib/mysql下面,可以做个软连接指定到/var/lib/mysql/mysql.sock这里,
#或者使用“-S”参数,指定mysql.sock的文件位置
xtracebackup2.3版本之前不能备份innodb的表,而innobackupex可以备份innodb的表,因此在2.3之前的版本通常使用innobackupex,innobackupex对xtracebackup做了封装,在备份innodb的表时使用innobackupex,而在备份非innodb表时内部调用接口使用了xtracebackup工具。因为这两个工具中一个是使用perl写的,另一个是使用c写的,通信相对困难。在xtracebackup2.4之后,重写了这两个,都使用c写的,把innobackupex的功能附加到了xtracebackup中,也就是xtracebackup既可以备份非innodb表也可以备份innodb表。
下面通过一次完全备份,来理解xtracebackup备份的过程。
在备份过程中,您应该看到很多输出显示正在复制的数据文件,以及日志文件线程反复扫描日志文件并从中复制。
[root@test3 ~]# xtrabackup --user=root --password=123456 --backup --target-dir=backup/ #target-dir参数指定备份文件存在的目录 xtrabackup: recognized server arguments: xtrabackup: recognized client arguments: --user=root --password=* --backup=1 --target-dir=backup/ 181230 11:48:02 version_check Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_group=xtrabackup' as 'root' (using password: YES). 181230 11:48:02 version_check Connected to MySQL server 181230 11:48:02 version_check Executing a version check against the server... 181230 11:48:02 version_check Done. 181230 11:48:02 Connecting to MySQL server host: localhost, user: root, password: set, port: not set, socket: not set #连接mysql server Using server version 5.7.22 xtrabackup version 2.4.12 based on MySQL server 5.7.19 Linux (x86_64) (revision id: 170eb8c) xtrabackup: uses posix_fadvise(). xtrabackup: cd to /data/mysql/ #首先备份innodb表 xtrabackup: open files limit requested 0, set to 1024 xtrabackup: using the following InnoDB configuration: xtrabackup: innodb_data_home_dir = . xtrabackup: innodb_data_file_path = ibdata1:12M:autoextend xtrabackup: innodb_log_group_home_dir = ./ xtrabackup: innodb_log_files_in_group = 2 xtrabackup: innodb_log_file_size = 50331648 InnoDB: Number of pools: 1 181230 11:48:03 >> log scanned up to (293834975) xtrabackup: Generating a list of tablespaces InnoDB: Allocated tablespace ID 17 for mysql/slave_worker_info, old maximum was 0 181230 11:48:03 [01] Copying ./ibdata1 to /root/backup/ibdata1 181230 11:48:03 [01] ...done 181230 11:48:03 [01] Copying ./mysql/slave_worker_info.ibd to /root/backup/mysql/slave_worker_info.ibd 181230 11:48:03 [01] ...done 181230 11:48:03 [01] Copying ./mysql/server_cost.ibd to /root/backup/mysql/server_cost.ibd ......... 181230 11:48:08 Executing FLUSH NO_WRITE_TO_BINLOG TABLES... 181230 11:48:08 Executing FLUSH TABLES WITH READ LOCK... #加上读锁,开始备份non-innodb表 181230 11:48:08 Starting to backup non-InnoDB tables and files 181230 11:48:08 [01] Copying ./performance_schema/socket_summary_by_instance.frm to /root/backup/performance_schema/socket_summary_by_instance.frm 181230 11:48:08 [01] ...done 181230 11:48:08 [01] Copying ./performance_schema/socket_summary_by_event_name.frm to /root/backup/performance_schema/socket_summary_by_event_name.frm 181230 11:48:08 [01] ...done 181230 11:48:08 [01] Copying ./performance_schema/users.frm to /root/backup/performance_schema/users.frm 181230 11:48:08 [01] ...done 181230 11:48:08 [01] Copying ./performance_schema/hosts.frm to /root/backup/performance_schema/hosts.frm ............ 181230 11:48:11 Finished backing up non-InnoDB tables and files 181230 11:48:11 Executing FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS... #把日志刷新到磁盘 xtrabackup: The latest check point (for incremental): '293834966' xtrabackup: Stopping log copying thread. .181230 11:48:11 >> log scanned up to (293834975) 181230 11:48:11 Executing UNLOCK TABLES #完成non-innodb表的备份 181230 11:48:11 All tables unlocked #所有的表解锁 181230 11:48:11 [00] Copying ib_buffer_pool to /root/backup/ib_buffer_pool 181230 11:48:11 [00] ...done 181230 11:48:11 Backup created in directory '/root/backup/' 181230 11:48:11 [00] Writing /root/backup/backup-my.cnf 181230 11:48:11 [00] ...done 181230 11:48:11 [00] Writing /root/backup/xtrabackup_info 181230 11:48:11 [00] ...done xtrabackup: Transaction log of lsn (293834966) to (293834975) was copied. 181230 11:48:11 completed OK! 181230 11:48:08 [01] ...done
查看一下备份出来的文件:
[root@test3 backup]# ls #这里的信息和innobackupex备份出来的信息差不多,因为没有开启二进制日志,因此,少了二进制日志的相关信息。 backup-my.cnf employees ib_buffer_pool ibdata1 mysql performance_schema sbtest sys xtrabackup_checkpoints xtrabackup_info xtrabackup_logfile [root@test3 backup]# cat xtrabackup_checkpoints backup_type = full-backuped #指明了这是一个完全备份 from_lsn = 0 to_lsn = 293834966 last_lsn = 293834975 compact = 0 recover_binlog_info = 0 [root@test3 backup]# cat xtrabackup_info uuid = ba508f21-0be5-11e9-8fc2-fa336351fc00 name = tool_name = xtrabackup tool_command = --user=root --password=... --backup --target-dir=backup/ tool_version = 2.4.12 ibbackup_version = 2.4.12 server_version = 5.7.22 start_time = 2018-12-30 11:48:02 end_time = 2018-12-30 11:48:11 lock_time = 0 binlog_pos = innodb_from_lsn = 0 innodb_to_lsn = 293834966 partial = N incremental = N format = file compact = N compressed = N encrypted = N
xtracebackup备份时在线备份,也就是再备份的过程中,数据库是可以进行操作的,备份的数据时间点自然就是不一致的,时间范围是从备份开始到备份结束这段时间,因此在使用备份出来的数据进行恢复之前,首先要做的就是准备数据,利用重做日志把数据恢复到同一个时间点。
您可以在任何机器上运行准备操作; 它不需要位于原始服务器或您要还原的服务器上。您可以将备份复制到实用程序服务器并在那里进行准备。
准备过程如下:
[root@test3 ~]# xtrabackup --prepare --target-dir=backup/
......
......
xtrabackup: starting shutdown with innodb_fast_shutdown = 1
InnoDB: FTS optimize thread exiting.
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 293839318
181230 14:22:32 completed OK!
恢复过程
恢复过程和之前使用innobackupex工具备份恢复的过程是一样的,需要注意的是,xtracebackup和innobackupex备份的数据恢复需要停掉原来的数据库。
[root@test3 ~]# service mysqld stop #停掉数据库 [root@test3 ~]# rm -fr /data/mysql/* #清空数据库目录 [root@test3 ~]# xtrabackup --copy-back --target-dir=/root/backup/ #恢复数据,其实就是一个copy过程 。。。。。。 181230 14:28:17 [01] ...done 181230 14:28:17 [01] Copying ./xtrabackup_info to /data/mysql/xtrabackup_info 181230 14:28:17 [01] ...done 181230 14:28:17 completed OK! [root@test3 ~]# chown -R mysql:mysql /data/mysql/ #修改数据库目录的属主和属组 [root@test3 ~]# service mysqld start #启动数据库 Starting MySQL. SUCCESS! [root@test3 ~]#
上面就是一个完整的数据库备份与恢复过程,当然xtracebackup还是有很多参数的,可以在使用的时候查看!
说两个参数吧! --galera-info This options creates the xtrabackup_galera_info file which contains the local node state at the time of the backup. Option should be used when performing the backup of Percona-XtraDB-Cluster. Has no effect when backup locks are used to create the backup.
#我们公司使用的mariadb集群,因此备份的时候会加上这个选项,备份一些集群信息。 --slave-info This option is useful when backing up a replication slave server. It prints the binary log position and name of the master server. It also writes this information to the "xtrabackup_slave_info" file as a "CHANGE MASTER" command. A new slave for this master can be set up by starting a slave server on this backup and issuing a "CHANGE MASTER" command with the binary log position saved in the "xtrabackup_slave_info" file.
#这个就不用说了,是一些slave的信息。
上面是一个完整实例说明全备的备份与恢复,下面来说明一个增量备份的用法!
增量备份
摘自官方文档: 增量备份
增量备份有效,因为每个InnoDB页面都包含一个日志序列号或LSN。该LSN是整个数据库系统的版本号。每个页面的LSN显示它最近的更改。
增量备份会复制其LSN比先前的增量备份或完整备份的LSN更新的每个页面。有两种算法用于查找要复制的此类页面集。第一个可用于所有服务器类型和版本的是通过读取所有数据页来直接检查页面LSN。Percona Server提供的第二个 功能是在服务器上启用更改的页面跟踪功能,该功能将在更改页面时记录这些功能。然后,该信息将在紧凑的单独的所谓位图文件中写出。该xtrabackupbinary将使用该文件只读取增量备份所需的数据页,从而可能节省许多读取请求。如果xtrabackup二进制文件找到位图文件,则默认启用后一种算法。即使位图数据可用,也可以指定xtrabackup --incremental-force-scan 读取所有页面。
增量备份实际上并不将数据文件与先前备份的数据文件进行比较。实际上,如果您知道其LSN,则可以使用它 来执行增量备份,甚至不需要先前的备份。增量备份只是读取页面并将其LSN与最后一个备份的LSN进行比较。但是,您仍需要完整备份来恢复增量更改; 如果没有完整备份作为基础,增量备份将毫无用处。
第一步:完全备份:
[root@test3 ~]# xtrabackup --user=root --password=123456 --backup --target-dir=/root/backup/ -S /data/mysql/mysql.sock [root@test3 ~]# cd backup/ #这个文件记录了最后的lsn信息 [root@test3 backup]# cat xtrabackup_checkpoints backup_type = full-backuped from_lsn = 0 to_lsn = 293839337 last_lsn = 293839346 compact = 0 recover_binlog_info = 0 [root@test3 backup]#
然后我们对数据库做一些更改!
[root@test3 backup]# mysql -uroot -p123456 -S /data/mysql/mysql.sock mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or g. Your MySQL connection id is 6 Server version: 5.7.22-log MySQL Community Server (GPL) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or 'h' for help. Type 'c' to clear the current input statement. mysql> use sbtest; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> create table test(dt datetime); Query OK, 0 rows affected (0.03 sec) mysql> insert into test select now(); Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> select * from test; +---------------------+ | dt | +---------------------+ | 2018-12-30 14:50:07 | +---------------------+ 1 row in set (0.00 sec) mysql>
#如上,仅创建了一张表,插入了一行记录!
开始做增量备份
[root@test3 ~]# xtrabackup --user=root --password=123456 -S /data/mysql/mysql.sock --backup --incremental-basedir=/root/backup/ --target-dir=/root/inc1
#--backup:指定操作是备份
#--incremental-basedir:此次增量备份时基于哪一个备份文件的。
#--target-dir: 指定增量备份的文件地址
#查看增量备份的文件
[root@test3 ~]# cd backup/inc1/
[root@test3 inc1]# ls
backup-my.cnf ib_buffer_pool ibdata1.meta performance_schema sys xtrabackup_checkpoints xtrabackup_logfile
employees ibdata1.delta mysql sbtest xtrabackup_binlog_info xtrabackup_info
[root@test3 inc1]# cat xtrabackup_checkpoints
backup_type = incremental
from_lsn = 293839337
to_lsn = 293846059
last_lsn = 293846068
compact = 0
recover_binlog_info = 0
[root@test3 inc1]#
思考?这里的增量备份时基于全备开始,如果我们还想继续下一次的增量备份,该基于全备呢?还是基于第一个增量备份呢?回想一下增量备份时根据lsn来备份的,如果想要下一个增量备份,肯定是基于前面的一个增量备份开始的!
增量备份恢复操作
和上面的一样,也需要先准备阶段!
增量备份的步骤与完全备份的步骤不同。在完全备份中,执行两种类型的操作以使数据库保持一致:从日志文件中对数据文件重放已提交的事务,并回滚未提交的事务。在准备增量备份时,必须跳过未提交事务的回滚,因为备份时未提交的事务可能正在进行中,并且很可能它们将在下一次增量备份中提交。您应该使用--apply-log-only该 选项来阻止回滚阶段
准备的时候先prepare全备数据,如果有多个增量备份,则按照to_lsn的顺序来执行prepare操作!
执行全备的prepare阶段 [root@test3 ~]# xtrabackup --prepare --apply-log-only --target-dir=/root/backup/ #执行增量备份的prepare阶段 [root@test3 ~]# xtrabackup --prepare --target-dir=/root/backup/ --incremental-dir=/root/inc1/
#将增量文件和全备文件附件在一起
特别需要注意一点:
xtrabackup --apply-log-only should be used when merging all incrementals except the last one. That’s why the previous line doesn’t contain the
xtrabackup --apply-log-only option. Even if the xtrabackup --apply-log-only was used on the last step, backup would still be consistent but in
that case server would perform the rollback phase.
#--apply-log-only参数应该被用于除最后一个增量备份之外的所有的增量备份(最后一个增量备份不使用),原因有点不太理解,先这样用。
数据准备完成之后,就会恢复了,和之前的过程是一样的!
停掉MySQL服务,清空datadir目录 [root@test3 ~]# xtrabackup --copy-back --target-dir=/root/backup/ [root@test3 ~]# chown -R mysql:mysql /data/mysql [root@test3 ~]# service mysqld start Starting MySQL.. SUCCESS! [root@test3 ~]# mysql -uroot -p123456 -S /data/mysql/mysql.sock #验证增量备份 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or g. Your MySQL connection id is 2 Server version: 5.7.22-log MySQL Community Server (GPL) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or 'h' for help. Type 'c' to clear the current input statement. mysql> use sbtest; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from test; +---------------------+ | dt | +---------------------+ | 2018-12-30 14:50:07 | +---------------------+
可以看到增量备份已经恢复成功!
后续:
在实际中可能会更经常遇到基于时间点的恢复,譬如我经常遇到的是恢复到某天的23:59:59的数据,如果这样的话,这个增量可能无法满足,因此建议使用二进制日志来做增量备份。
关于二进制日志的增量备份,在上一篇博文中innobackupex备份中已经说明了,不再赘述!