MySQL 备份与恢复
一、数据库备份的类型
按照服务器的运行状态,可分为:冷备、热备、温备。
冷备:数据库处于停机状态下进行备份。
热备:数据库处于运行状态下备份,在热备期间,数据库的读写操作均可正常进行。
在mysql中,MyISAM存储引擎不支持热备,InnoDB存储引擎支持热备。
温备:数据库处于运行状态下备份,但是在温备期间数据库只能进行读操作,不能进行写操作
按照备份后的内容量,可分为:全备、增备、差异备份。
- 全量备份:对所有数据进行一个完全的备份。
- 增备备份:对上一次”备份”以后变化的数据的备份。
- 差异备份:对上一次”全量备份”以后变化的数据的备份。
按照备份的方式,可分为:逻辑备份、物理备份。
逻辑备份:将数据从数据库中导出,并将导出的数据进行存档备份。
物理备份:直接备份数据库所对应的数据文件。物理备份相对逻辑备份来说,性能更强。
二、数据库备份方式
在数据库备份当中,一般会采用逻辑备份、物理备份这两种方式对数据库进行备份。
2.1 逻辑备份
基于SQL语句进行备份。
常见得逻辑备份方式:
以binlog方式进行备份
使用mysqldump备份工具备份
replication(数据库主从)
select into outfile (使用SQL语句导出数据到文件)
2.2 物理备份
基于数据文件的备份。
常见物理备份方式:
- 使用xtrabackup备份工具备份
三、MySQL主流备份工具之mysqldump
mysqldump是MySQL自带的免费备份工具,是一种逻辑备份工具。
在MySQL 5.7中新增了一个mysqldump的改进版备份工具mysqlpump,它支持基于表级别的并行备份。
3.1 备份方法
- 备份单表或者一组指定的库表
mysqldump [options] db_name [tbl_name ...] |
- 备份一组或者一个数据库下的所有表
mysqldump [options] --databases db_name ... |
- 备份整个数据库实例
mysqldump [options] --all-databases |
3.2 mysqldump常用命令行选项
- -A,–all-databases:备份所有数据库下的所有表。
- -B,–databases:备份指定数据库下的所有表。
- –master-data[=value]:则在备份文件中会生成一 条CHANGE MASTER TO语句(包含binlog pos,binlog file)
- value=2:备份文件中生成的CHANGE MASTER TO语句将被注释
- value=1:该语句不会被注释
- value=0:不记录CHANGE MASTER TO语句
- -F,–flush-logs:在开始备份之前刷新MySQL二进制日志文件。
- -E,–events:在备份数据中包含数据库的事件。
- –triggers:在备份文件中包含每个备份表的触发器。
- –single-transaction:在备份数据之前开启一个事务快照,然后在事务快照内进行备份。
- 结合–master-data实现热备
- -d,–no-data:不备份表数据,只备份表结构。
- -t,–no-create-info:只备份数据,不备份表结构。
- -R,–routines:备份数据中存储过程和函数。
3.3 mysqldump备份注意
- mysqldump在备份和恢复时都需要MySQL实例启动为前提
- 一般数据量级100G以内,大约15-30分钟可以恢复(TB、PB、EB就需要考虑别的方式)
- mysqldump是以覆盖的形式恢复数据的
3.4 实战:模拟完全备份和恢复
在备份源数据库中插入一些数据
mysql> select * from test; |
在远程备份服务器中使用mysqldump远程备份数据:
[root@db02 ~]# mkdir /data/backup/mysql/mysqldump -p |
查看备份文件中的binlog pos位置、binlog文件:
[root@db02 mysqldump]# head -100 backup_2020-06-19_23_37_03.sql | grep -i CHANGE |
把备份文件导入恢复服务器的数据库实例中:
[root@db01 mysqldump]# mysql -uroot -p123 -e "reset master;" |
登录恢复服务器中的数据库,校验数据:
mysql> select * from test; |
四、MySQL主流备份工具之XtraBackup
XtraBackup是一款开源的热备份软件(物理备份),它可以非阻塞地对InnoDB和XtraDB数据库进行备份。
XtraBackup的出现,解决了mysqldump在备份数据量大的数据库时,备份和恢复的时间高开销的问题。
4.1 XtraBackup的都优点
- 快速可靠地完成备份。
- 在备份期间不间断地处理事务。
- 节省磁盘空间和网络带宽。
- 自动备份验证。
- 更快地恢复,以保障业务有更长的在线时间。
4.2 备份方式(物理备份)
- 对于非innodb表(比如myisam)是直接锁表,cp数据文件,属于一种温备。
- 对于innodb的表(支持事务),不锁表,cp数据页最终以数据文件方式保存下来,并且把redo和undo一并备走,属于热备方式。
- 备份时读取配置文件/etc/my.cnf
4.3 下载安装XtraBackup软件
XtraBackup 的 RPM 包可去 Percona 官网下载相应的版本。
- 安装依赖
yum install -y perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL |
- 安装XtraBackup
yum install -y https://downloads.percona.com/downloads/Percona-XtraBackup-2.4/Percona-XtraBackup-2.4.22/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.22-1.el7.x86_64.rpm |
4.4 innobackupex命令常用选项
- –user=USER:备份服务器数据库用户名
- –password=PASSWORD:备份服务器数据库密码
- –host=HOST:备份服务器的IP
- –port=PORT:备份服务器的端口号
- –no-timestamp:不在指定备份目录下创建以时间戳命名的目录
- –defaults-file:指定默认的my.cnf配置文件
- –apply-log:在指定备份目录下执行应用xtrabackup_logfile文件中的事务日志操作,同时根据配置文件中的innodb_log_file_size系统参数生成新的事务日志
- –redo-only:针对未提交的事务不执行回滚操作,结合–apply-log一起使用
- –copy-back:会从指定目录中读取数据文件,并复制到目标数据库的数据目录中
- –incremental:告诉xtrabackup创建一个增量备份,而不是一个完整的备份
- –incremental-basedir=DIRECTORY:与–incremental一同使用,指定完全备份或上一次增量备份的路径
- –incremental-dir=DIRECTORY:项用于在应用redo日志时指定一个增量备份目录
4.5 实战:模拟完全备份与恢复
使用innobackupex命令完全备份数据库文件,并将备份文件放在/data/backup/mysql/test_backup
目录下。
[root@db01 ~]# mkdir -p /data/backup/mysql/test_backup |
对备份目录执行–apply-log操作:
[root@db01 ~]# innobackupex --user=root --password=123 --apply-log /data/backup/mysql/test_backup/ |
现在模拟数据库数据丢失情况。即先停止数据库,清空数据目录。
[root@db01 ~]# /etc/init.d/mysqld stop |
恢复数据,对备份目录执行–copy-back操作,把备份文件复制到之前清空的数据目录下:
[root@db01 ~]# innobackupex --defaults-file=/etc/my.cnf --copy-back /data/backup/mysql/test_backup/ |
修改数据目录的属主、属组,启动数据库:
[root@db01 ~]# chown -R mysql:mysql /usr/local/mysql/data |
登录数据库,校验数据是否正确:
[root@db01 ~]# mysql -uroot -p123 -e "show databases;" |
4.6 实战:模拟增量备份与恢复
增量备份特性:
- 基于上一次备份进行增量
- 增量备份无法单独恢复,必须基于全备进行恢复
- 所有增量必须要按顺序合并到全备当中
4.6.1 完全备份和增量备份
使用innobackupex命令给数据库进行一次完全备份,备份目录到backup-$(date +%F)
[root@db01 ~]# innobackupex --user=root --password=123 --no-timestamp /data/backup/mysql/backup-$(date +%F) |
完全备份成功后,进入数据库新建库、表并插入一些数据(制造增量数据):
mysql> create database test1; |
进行第一次增备备份。第一次增量备份的basedir是完全备份,因为在第一 次增量备份之前的最近一次备份只有完全备份。
[root@db01 ~]# innobackupex --user=root --password=123 --no-timestamp --incremental-basedir=/data/backup/mysql/backup-2020-06-22/ --incremental /data/backup/mysql/incremental_one |
继续制造测试数据:
mysql> create table tb2(id int,name varchar(10)); |
进行第二次增量备份。第二次增量备份就不需要再基于完全备份了,因为最近一次备份是第一次增量备份,这里第二次增量备份的basedir
是基于第一次增量备份的。
[root@db01 ~]# innobackupex --user=root --password=123 --no-timestamp --incremental-basedir=/data/backup/mysql/incremental_one/ --incremental /data/backup/mysql/incremental_two |
4.6.2 增量备份恢复
在恢复数据前,先停止数据库并清空相关数据目录(建议先备份在情况)。
[root@db01 ~]# /etc/init.d/mysqld stop |
进入完全备份目录,执行–apply-log操作需要带上–redo-only选项,只应用完成redo日志,不对未提交的事务执行回滚操作。
[root@db01 ~]# cd /data/backup/mysql/backup-2020-06-22 |
在完全备份的基础上执行第一次增量备份–apply-log操作(带上–redo-only)
[root@db01 backup-2020-06-22]# innobackupex --apply-log --redo-only /data/backup/mysql/backup-2020-06-22/ --incremental-dir=/data/backup/mysql/incremental_one/ |
在执行–apply-log操作的第一次增量备份的完全备份目录中,再对第二次增量备份执行–apply-log操作,因为这是最后一次增量备份,所以不需要加–redo-only选项。
[root@db01 backup-2020-06-22]# innobackupex --apply-log /data/backup/mysql/backup-2020-06-22/ --incremental-dir=/data/backup/mysql/incremental_two/ |
最后,在对完全备份目录执行一次–apply-log操作,生成redo log文件。
[root@db01 backup-2020-06-22]# innobackupex --apply-log --redo-only /data/backup/mysql/backup-2020-06-22/ |
将完全备份目录下的数据文件复制到相关目录下:
[root@db01 backup-2020-06-22]# innobackupex --copy-back ./ |
修改数据目录属主并启动MySQL:
[root@db01 ~]# chown -R mysql.mysql /usr/local/mysql/data/ |
登录数据库,效验数据。
[root@db01 ~]# mysql -uroot -p123 -e "use test1;select * from tb1,tb2;" |