MySQL的备份与还原

一、备份的分类

1、根据是否需要数据库离线

 冷备(Cold Backup):需关闭mysql服务,读写操作均不可进行

 温备(Warm Backup):不用关闭mysql服务,读操作可执行,但写操作不可执行

 热备(Hot Backup):不用关闭mysql服务,读写操作均可  

 注:
   MyISAM 支持温备,不支持热备
   InnoDB 都支持

2、根据备份数据或文件

 物理备份:直接复制数据文件进行备份,与存储引擎有关,占用较多的空间,速度快

 逻辑备份:从数据库中导出数据并另存的方式,与存储引擎有关,占用空间少,速度慢

3、根据备份的数据集合范围

 完全备份(Full Backup):指对某一个时间点上的所有数据进行的一个完全拷贝。

  优点:备份与恢复操作简单方便;

  缺点:数据存在大量的重复;占用大量的备份空间;备份与恢复空间长;

 增量备份(Incremental Backup):指在一次全备份或上一次增量备份后,以后每次的备份只需备份与前一次相比增加和者被修改的文件。这就意味着,第一次增量备份的对象是进行全备后所产生的增加和修改的文件;第二次增量备份的对象是进行第一次增量备份后所产生的增加和修改的文件,如此类推。

  优点:没有重复数据,备份量不大,时间短;

  缺点:恢复麻烦;需要上次完全备份及完全备份之后所有的增量备份才能恢复,而且要对所有增量备份进行逐个反推恢复;

 差异备份(Differential Backup):指在一次全备份后到进行差异备份的这段时间内,对那些增加或者修改文件的备份。在进行恢复时,我们只需对第一次全备份和最后一次差异备份进行恢复。

二、备份的方式

1、物理备份的方式

 使用cp、tar等复制归档工具,将数据文件拷贝到另一位置备份,适用与所有的存储引擎;只支持冷备;

  优点:备份和恢复操作都比较简单;恢复速度快,属于文件系统级别

  缺点:需要关闭mysql服务

#如数据目录为 /data/mysql/,备份命令为
[root@localhost ~]# /etc/init.d/mysqld stop
Shutting down MySQL.. SUCCESS! 
[root@localhost ~]# tar -czvf mysql-backup_$(date +%F).tar.gz /data/mysql/

2、LVM快照的方式

 先加锁,再做快照,之后再解锁;借助文件系统工具进行备份;

 前提:
  快照的vg和备份源必须是同一个;
  此逻辑卷需要有足够空间进行快照;
  数据文件和事物日志放在同一个逻辑卷上;

2.1、备份

 (1) 查看系统逻辑卷信息

[root@localhost ~]# lvs
  LV   VG     Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root centos -wi-ao---- <37.50g                                                    
  swap centos -wi-ao----   2.00g                                                    
[root@localhost ~]# vgs
  VG     #PV #LV #SN Attr   VSize   VFree
  centos   1   2   0 wz--n- <39.50g    0 
[root@localhost ~]# pvs
  PV         VG     Fmt  Attr PSize   PFree
  /dev/sda2  centos lvm2 a--  <39.50g    0

 (2) 空间不够,在虚拟机上新加一块10G的硬盘

[root@localhost ~]# echo - - - > /sys/class/scsi_host/host0/scan
[root@localhost ~]# fdisk -l /dev/sdb

Disk /dev/sdb: 10.7 GB, 10737418240 bytes, 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

 (4) 扩展逻辑卷

[root@localhost ~]# pvcreate /dev/sdb
  Physical volume "/dev/sdb" successfully created.
[root@localhost ~]# pvs
  PV         VG     Fmt  Attr PSize   PFree 
  /dev/sda2  centos lvm2 a--  <39.50g     0 
  /dev/sdb          lvm2 ---   10.00g 10.00g
[root@localhost ~]# vgextend centos /dev/sdb
  Volume group "centos" successfully extended
[root@localhost ~]# vgs
  VG     #PV #LV #SN Attr   VSize  VFree  
  centos   2   2   0 wz--n- 49.49g <10.00g

 (4) 请求锁定所有表

mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.00 sec)

 (5) 记录二进制日志文件及事件位置

mysql> FLUSH LOGS;
Query OK, 0 rows affected (0.02 sec)

mysql> SHOW MASTER LOGS;
+---------------+-----------+-----------+
| Log_name      | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 |       519 | No        |
| binlog.000002 |       155 | No        |
+---------------+-----------+-----------+
2 rows in set (0.00 sec)

[root@localhost ~]# mysql -uroot -p -e "SHOW MASTER LOGS;" > logbin_position.txt
Enter password: 
[root@localhost ~]# ls -l logbin_position.txt 
-rw-r--r-- 1 root root 71 May 20 14:09 logbin_position.txt
[root@localhost ~]# cat logbin_position.txt
Log_name    File_size    Encrypted
binlog.000001    519    No
binlog.000002    155    No

 (6) 创建快照

#ext4文件系统可用以下命令
[root@localhost ~]# lvcreate -L 1G -s -p r -n mysql_snap /dev/centos/root
  Logical volume "mysql_snap" created.
#xfs文件系统,使用 -p r 选项导致挂载不上,用以下命令即可
[root@localhost ~]# lvcreate -L 1G -s -n  mysql_snap /dev/centos/root
  Logical volume "mysql_snap" created.

 (7) 释放锁

mysql> UNLOCK TABLES;
Query OK, 0 rows affected (0.00 sec)

 (8) 挂载快照卷,执行数据备份

#xfs文件系统需加-o nouuid选项,不然挂载不上,ext4可不加
[root@localhost ~]# mount -o nouuid /dev/centos/mysql_snap /mnt/mysql_data
[root@localhost mysql_data]# cd /mnt/mysql_data/
[root@localhost mysql_data]# ls
auto.cnf       ca-key.pem       ib_buffer_pool  ibtmp1        mysql.ibd           private_key.pem  server-key.pem
binlog.000001  ca.pem           ibdata1         #innodb_temp  mysql.sock          public_key.pem   sys
binlog.000002  client-cert.pem  ib_logfile0     log           mysql.sock.lock     run              undo_001
binlog.index   client-key.pem   ib_logfile1     mysql         performance_schema  server-cert.pem  undo_002
[root@localhost mysql_data]# tar -czvf mysql-$(date +%F).tar.gz ./*
[root@localhost mysql_data]# cp mysql-2020-05-20.tar.gz /root/

 (9) 备份完成后,删除快照卷

[root@localhost ~]# umount /mnt/mysql_data/
[root@localhost ~]# lvremove /dev/centos/mysql_snap 
Do you really want to remove active logical volume centos/mysql_snap? [y/n]: y
  Logical volume "mysql_snap" successfully removed

 (10)  制定好策略,通过原卷备份二进制日志

mysql> show master logs;
+---------------+-----------+-----------+
| Log_name      | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 |       519 | No        |
| binlog.000002 |       155 | No        |
+---------------+-----------+-----------+
2 rows in set (0.00 sec)

mysql> create database testdb;
Query OK, 1 row affected (0.01 sec)

mysql> show master logs;
+---------------+-----------+-----------+
| Log_name      | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 |       519 | No        |
| binlog.000002 |       346 | No        |
+---------------+-----------+-----------+
2 rows in set (0.00 sec)

[root@localhost ~]# /usr/local/mysql/bin/mysqlbinlog --start-position=155 --stop-position=346 /data/mysql/binlog.000002 > mysqlbinlog.sq

2.2、还原

[root@localhost ~]# rm -rf /data/mysql/*
[root@localhost ~]# tar -zcvf mysql-2020-05-20.tar.gz -C /data/mysql/
[root@localhost ~]# chown -R mysql:mysql /data/mysql/ [root@localhost ~]# mysql < mysqlbinlog.sql

3、MySQL自带工具

3.1、 mysqldump工具

 mysqldump是mysql自带的逻辑备份工具,适用于所有存储引擎,温备;对InnoDB存储引擎支持热备,结合binlog的增量备份。

 优点:恢复简单,备份结果为ASCII文件,可以编辑;

 缺点:备份或恢复都需要mysql服务器进程参与;备份结果占据更多的空间;数据量大时,备份时间长;浮点数可能会丢失精度;

 命令格式:

mysqldump [OPTIONS] database [tables]
mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
mysqldump [OPTIONS] --all-databases [OPTIONS]

 常用选项:

 -A, --all-databases 备份所有数据库,含create database
 -B, --databases db_name… 指定备份的数据库,包括create database语句
 -E, --events:备份相关的所有event scheduler
 -F, --flush-logs :备份前滚动日志,锁定表完成后,执行flush logs命令,生成新的二进制日志文件,配合 -A 或 -B 选项时,会导致刷新多次数据库。建议在同一时刻执行转储和日志刷新,可通过和--single-transaction或-x,--master-data 一起使用实现,此时只刷新一次日志
 -R, --routines:备份所有存储过程和自定义函数
 --triggers:备份表相关触发器,默认启用,用--skip-triggers,不备份触发器
 --default-character-set=utf8 指定字符集
 --master-data[=#]: 此选项须启用二进制日志
     1:所备份的数据之前加一条记录为CHANGE MASTER TO语句,非注释,不指定#,默认为1
     2:记录为注释的CHANGE MASTER TO语句
     此选项会自动关闭 --lock-tables功能,自动打开-x | --lock-all-tables功能(除非开启--single-transaction)
 --compact 去掉注释,适合调试,生产不使用
 -d, --no-data 只备份表结构
 -f, --force 忽略SQL错误,继续执行
 -t, --no-create-info 只备份数据,不备份create table 
 -n, --no-create-db 不备份create database,可被-A或-B覆盖
 -q, --quick 不缓存查询,直接输出,加快备份速度
 --flush-privileges 备份mysql或相关时需要使用
 --hex-blob 使用十六进制符号转储二进制列,当有包括BINARY,VARBINARY,BLOB,BIT的数据类型的列时使用,避免乱码
 --ignore-table 备份时忽略指定表
 MyISAM备份选项:(支持温备;不支持热备,所以必须先锁定要备份的库,而后启动备份操作)
 -x,--lock-all-tables:加全局读锁,锁定所有库的所有表,同时加--single-transaction或--lock-tables选项会关闭此选项功能;注意:数据量大时,可能会导致长时间无法并发访问数据库
 -l,--lock-tables:对于需要备份的每个数据库,在启动备份之前分别锁定其所有表,默认为on,--skip-lock-tables选项可禁,对备份MyISAM的多个库,可能会造成数据不一致
  注:以上两个选项对InnoDB表一样生效,实现温备,但不推荐使用
 InnoDB备份选项:(支持热备,可用温备但不建议用)
 --single-transaction 此选项Innodb中推荐使用,不适用MyISAM,此选项会开始备份前,先执行START TRANSACTION指令开启事务;此选项和 --lock-tables 选项是相互排斥,备份大型表时,建议将--single-transaction选项和--quick结合一起使用        

 简单使用:

#备份单个库
mysqldump -h主机名 -P端口 -u用户名 -p密码 --databases 数据库名 > 文件名.sql
mysqldump -uroot -p --database db1 > db1.sql
#备份同时压缩
mysqldump -h主机名 -P端口 -u用户名 -p密码 --databases 数据库名 | gzip > 文件名.sql.gz
mysqldump -uroot -p --database db1 | gzip > db1.sql.gz
#备份同个库多个表
mysqldump -h主机名 -P端口 -u用户名 -p密码 --databases 数据库名 表1 表2 .... > 文件名.sql
mysqldump -uroot -p --database db1 tb1 tb2 > db1.sql
#同时备份多个库
mysqldump -h主机名 -P端口 -u用户名 -p密码 --databases 数据库名1 数据库名2 数据库名3 > 文件名.sql
mysqldump -uroot -p --database db1 db2 db3 > db.sql
#备份所有的数据库
mysqldump -h主机名 -P端口 -u用户名 -p密码 --all-databases > 文件名.sql
mysqldump -uroot -p --all-database  > all_dbs.sql
#备份指定数据库并排除某些表
mysqldump -h主机名 -P端口 -u用户名 -p密码 --databases 数据库名 --ignore-table=表1 --ignore-table=表2 > 文件名.sql
mysqldump -uroot -p db1 --database --ignore-table=db1.t1 --ignore-table=db1.t2 > db.sql

 生产环境的备份策略

#MyISAM:
mysqldump –uroot -p –A –F –E –R –x --master-data=1 --flush-privileges --triggers --default-character-set=utf8 --hex-blob > $BACKUP/fullbak_$BACKUP_TIME.sql
#InnoDB:
mysqldump –uroot -p –A –F –E –R --single-transaction --master-data=1 --flush-privileges --triggers --default-character-set=utf8 --hex-blob > $BACKUP/fullbak_$BACKUP_TIME.sql

3.2、文本导入导出

 select ... into outfile实现数据的备份

 load data infile 实现数据的恢复

 备份命令格式:

SELECT [列名] FROM table [WHERE 语句]
        INTO OUTFILE 目标文件 [OPTION];

 常用选项:

FIELDS TERMINATED BY 字符串:设置字符串为字段之间的分隔符,可以为单个或多个字符。默认值是"\t"
FIELDS ENCLOSED BY 字符:设置字符来括住字段的值,只能为单个字符。默认情况下不使用任何符号
FIELDS OPTIONALLY ENCLOSED BY 字符:设置字符来括住CHAR、VARCHAR和TEXT等字符型字段。默认情况下不使用任何符号
FIELDS ESCAPED BY 字符:设置转义字符,只能为单个字符。默认值为"\"
LINES STARTING BY 字符串:设置每行数据开头的字符,可以为单个或多个字符。默认情况下不使用任何字符
LINES TERMINATED BY 字符串:设置每行数据结尾的字符,可以为单个或多个字符。默认值是"\n"
  注:FIELDS和LINES两个子句都是自选的,但是如果两个子句都被指定了,FIELDS必须位于LINES的前面

 操作示例:

mysql> SELECT * FROM hellodb.students INTO OUTFILE /data/backup/students.txt
    -> FIELDS
    -> TERMINATED BY \t
    -> OPTIONALLY ENCLOSED BY \"
    -> LINES
    -> STARTING BY \>
    -> TERMINATED BY \r\n;
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
mysql> SHOW VARIABLES LIKE "secure_file_priv";
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | secure_file_priv | NULL  |
    +------------------+-------+
    1 row in set (0.00 sec)
mysql> SET GLOBAL secure_file_priv = "/data/backup";
ERROR 1238 (HY000): Variable secure_file_priv is a read only variable
mysql> exit
[root@localhost ~]# mkdir /data/backup
[root@localhost ~]# chown -R mysql.mysql /data/backup/
[root@localhost ~]# vim /etc/my.cnf
#在[mysqld]下添加此项
secure-file-priv=/data/backup    
注:
secure-file-priv的值有三种情况:
    secure_file_prive=null   ––限制mysqld 不允许导入导出
    secure_file_priv=/path/   --限制mysqld的导入导出只能发生在默认的/path/目录下
    secure_file_priv=‘‘     --不对mysqld 的导入导出做限制,但导出目录需要有mysql用户的写权限
#然后重启mysql,再次执行备份命令即可
[root@localhost ~]# /etc/init.d/mysqld restart    

 还原命令格式:

LOAD DATA  [LOW_PRIORITY] [LOCAL] INFILE file_name.txt [REPLACE | IGNORE]
        INTO TABLE tbl_name
        [FIELDS
            [TERMINATED BY \t]
            [OPTIONALLY] ENCLOSED BY ‘‘]
            [ESCAPED BY \‘ ]]
        [LINES
            [STARTING BY string]
            [TERMINATED BY string]]
        [IGNORE NUMBER LINES]
        [(col_name,   )]

 操作示例:

mysql> LOAD DATA INFILE /data/backup/students.txt 
    -> INTO TABLE hellodb.students
    -> FIELDS 
    -> TERMINATED BY \t 
    -> OPTIONALLY ENCLOSED BY \" 
    -> LINES 
    -> STARTING BY \> 
    -> TERMINATED BY \r\n;

 简单使用示例:

SELECT * FROM hellodb.students INTO OUTFILE /data/backup/students.txt
LOAD DATA INFILE /data/backup/students.txt INTO TABLE hellodb.students;
#如果指定local关键词,则表明从客户主机读文件。如果local没指定,文件必须位于服务器
mysql> LOAD DATA LOCAL INFILE /root/students.txt INTO TABLE testdb.students;
ERROR 1148 (42000): The used command is not allowed with this MySQL version
mysql> SHOW VARIABLES LIKE local_infile;
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| local_infile  | OFF   |
+---------------+-------+
1 row in set (0.01 sec)
mysql> SET GLOBAL local_infile=on;
[root@localhost ~]# mysql --local-infile=1 -uroot -p
mysql> LOAD DATA LOCAL INFILE /root/students2.txt INTO TABLE testdb.students;

3.3、基于二进制日志的数据恢复

 基于位置的恢复命令

#恢复数据到指定位置
mysqlbinlog --stop-position=操作 id 二进制日志 | mysql -u 用户名 -p 密码
#从指定的位置开始恢复数据
mysqlbinlog --start-position=操作 id 二进制日志 | mysql -u 用户名 -p 密码

 基于时间点恢复

#从日志开头截止到某个时间点的恢复
mysqlbinlog [–no-defaults] --stop-datetime=年-月-日 小时:分钟:秒 二进制日志 | mysql -u 用户名 -p 密码
#从某个时间点到日志结尾的恢复
mysqlbinlog [–no-defaults] --start-datetime=年-月-日 小时:分钟:秒 二进制日志 | mysql -u 用户名 -p 密码
#从某个时间点到某个时间点的恢复
mysqlbinlog [–no-defaults] --start-datetime=年-月-日 小时:分钟:秒 --stop-datetime=年-月-日 小时:分钟:秒 二进制日志 | mysql -u 用户名 -p 密码

4、第三方工具xtrabackup

 xtrabackup:由Percona公司提供支持,是世界上唯一的开源,免费的MySQL热备份软件,可以为InnoDB和XtraDB 数据库执行非阻塞备份。

 手册:https://www.percona.com/doc/percona-xtrabackup/8.0/index.html

 特点:

  备份还原过程快速、可靠;
  备份期间程不会打断正在执行的事务;
  能够基于压缩等功能节约磁盘空间和流量;
  自动实现备份检验;
  开源、免费

4.1、安装与授权

 安装:

[root@localhost ~]# yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
[root@localhost ~]# percona-release enable-only tools release
[root@localhost ~]# wget http://rpmfind.net/linux/epel/7/x86_64/Packages/l/libev-4.15-3.el7.x86_64.rpm
[root@localhost ~]# yum install libev-4.15-3.el7.x86_64.rpm
[root@localhost ~]# yum install percona-xtrabackup-80
[root@localhost ~]# rpm -ql  percona-xtrabackup-80
/usr/bin/xbcloud
/usr/bin/xbcloud_osenv
/usr/bin/xbcrypt
/usr/bin/xbstream
/usr/bin/xtrabackup
/usr/lib64/xtrabackup/plugin/keyring_file.so
/usr/lib64/xtrabackup/plugin/keyring_vault.so
/usr/share/doc/percona-xtrabackup-80-8.0.11
/usr/share/doc/percona-xtrabackup-80-8.0.11/LICENSE
/usr/share/man/man1/xbcrypt.1.gz
/usr/share/man/man1/xbstream.1.gz
/usr/share/man/man1/xtrabackup.1.gz    
[root@localhost ~]# xtrabackup -v
xtrabackup: recognized server arguments: --datadir=/data/mysql --innodb_file_per_table=1 
xtrabackup version 8.0.11 based on MySQL server 8.0.18 Linux (x86_64) (revision id: 486c270)

 授权用户可以进行备份:

mysql> CREATE USER bkpuser@localhost IDENTIFIED BY bkp123;
mysql> GRANT BACKUP_ADMIN, PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO bkpuser@localhost;
mysql> GRANT SELECT ON performance_schema.log_status TO bkpuser@localhost;
mysql> FLUSH PRIVILEGES;

4.2、xtrabackup命令用法

 命令格式:

xtrabackup [--defaults-file=#] --backup|--prepare|--copy-back|--stats [OPTIONS]

 常用选项:

-u, --user            表示备份的账号
-p, --password        表示账号的密码
-H, --host            表示备份数据库的地址
-P, --port            指定连接数据库的端口
-S, --socket         指定本地连接数据库的socket
--defaults-file       指定从哪个文件读取MySQL配置,必须放在命令行第一个选项位置
--print-defaults      打印出读取的默认配置选项
--backup              执行备份到target-dir目录
--target-dir          指定备份目录,如没有将创建,如有,则目录须为空,不然会报错
--compress            指定备份时的压缩算法,支持 quicklz 和 lz4,默认算法为quicklz
--compress-threads    指定压缩线程数量,默认为1
--decompress          在prepare一个备份前先解压缩,需要安装qpress,可以Percona仓库安装 yum install -y qpress
--remove-original     和--decompress,解压缩并清理压缩文件 
--prepare             为恢复一个备份做预处理
--copy-back           从一个备份目录里还原数据
--incremental-basedir    表示指定为前一次全备份或增量备份的目录
--incremental-dir     表示还原时要合并的增量备份的目录
--apply-log-only      此选项作用是通过回滚未提交的事务及同步已经提交的事务至数据文件使数据文件处于一致性状态
--user-memory         和--apply-log选项一起使用,当prepare 备份时,做crash recovery分配的内存大小,单位字节,也可1MB,1M,1G,1GB等,推荐1G
--export              与--prepare一起使用,表示开启可导出单独的表之后再导入其他Mysql中
--copy-back           做数据恢复时将备份数据拷贝到MySQL服务器的datadir
--move-back           这个选项与--copy-back相似,唯一的区别是它不拷贝文件,而是移动文件到目的地。这个选项移除backup文件,用时候必须小心。使用场景:没有足够的磁盘空间同时保留数据文件和Backup副本

   备份生成的相关文件:

(1) xtrabackup_info:xtrabackup工具执行时的相关信息,包括版本,备份选项,备份时长,备份LSN(log sequence number日志序列号),BINLOG的位置
(2) xtrabackup_checkpoints:备份类型(如完全或增量)、备份状态(如是否已经为prepared状态)和LSN范围信息,每个InnoDB页(通常为16k大小)都会包含一个日志序列号LSN。LSN是整个数据库系统的系统版本号,每个页面相关的LSN能够表明此页面最近是如何发生改变的
(3) xtrabackup_binlog_info:MySQL服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置,可利用实现基于binlog的恢复
(4) backup-my.cnf:备份命令用到的配置选项信息
(5) xtrabackup_logfile:备份生成的日志文件

4.3、备份与还原

4.3.1、全量备份与还原

(1) 在原主机做完全备份,然后将完全备份传到目标主机上

[root@localhost ~]# xtrabackup --user=bkpuser --password=bkp123 --backup --target-dir=/data/backups/
# scp -r /data/backups/* 目标主机:/data/backups/ 传到目标主机
[root@localhost ~]# scp -r /data/backups/* 192.168.11.10:/data/backups/

(2) 在目标主机上还原

#预准备:确保数据一致,提交完成的事务,回滚未完成的事务
[root@localhost ~]# xtrabackup --prepare --target-dir=/data/backups/
#还原备份:
[root@localhost ~]# xtrabackup --copy-back --target-dir=/data/backups/
    注意:恢复备份之前,datadir必须为空。同样重要的是要注意,在执行还原之前需要关闭MySQL服务器。您不能还原到正在运行的mysqld实例的数据目录(导入部分备份时除外)
#也可以使用 rsync 或 cp 来还原文件
# rsync -avrP /data/backups/ /data/mysql/
#还原属性:
[root@localhost ~]# chown -R mysql:mysql /data/mysql/
#启动服务:
[root@localhost ~]# /etc/init.d/mysqld start

4.3.2、增量备份与还原

1、备份过程

 (1) 完全备份

[root@localhost ~]# xtrabackup --user=bkpuser --password=bkp123 --backup --target-dir=/data/backups/base

 (2) 第一次修改数据

mysql> USE hellodb;
mysql> SHOW TABLES;
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes           |
| coc               |
| courses           |
| scores            |
| students          |
| teachers          |
+-------------------+
mysql> DROP TABLE coc;
mysql> SHOW TABLES;
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes           |
| courses           |
| scores            |
| students          |
| teachers          |
+-------------------+

 (3) 第一次增量备份

[root@localhost ~]# xtrabackup --user=bkpuser --password=bkp123 --backup --target-dir=/data/backups/inc1 --incremental-basedir=/data/backups/base

 (4) 第二次修改数据

mysql> SELECT * FROM teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
|   4 | Lin Chaoying  |  93 | F      |
+-----+---------------+-----+--------+
4 rows in set (0.01 sec)

mysql> DELETE FROM teachers WHERE tid=4;

 (5) 第二次增量备份

[root@localhost ~]# xtrabackup --user=bkpuser --password=bkp123 --backup --target-dir=/data/backups/inc2 --incremental-basedir=/data/backups/inc

 (6) 复制备份至目标主机

[root@localhost ~]# scp -r /data/backups/* 192.168.11.10:/data/backups/

2、还原过程

 (1) 预准备完成备份,此选项 --apply-log-only 阻止回滚未完成的事务

[root@localhost ~]# xtrabackup --prepare --apply-log-only --target-dir=/data/backups/base

 (2) 合并第1次增量备份到完全备份

[root@localhost ~]# xtrabackup --prepare --apply-log-only --target-dir=/data/backups/base --incremental-dir=/data/backups/inc1

 (3) 合并第2次增量备份到完全备份:最后一次还原不需要加选项--apply-log-only

[root@localhost ~]# xtrabackup --prepare --target-dir=/data/backups/base --incremental-dir=/data/backups/inc2

 (4) 复制到数据库目录,注意数据库目录必须为空,MySQL服务不能启动

[root@localhost ~]# xtrabackup --copy-back --target-dir=/data/backups/base

 (5) 还原属性,之后启动服务

[root@localhost ~]# chown -R mysql:mysql /data/mysql/
[root@localhost ~]# /etc/init.d/mysqld start
mysql> USE hellodb;
mysql> SHOW TABLES;
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes           |
| courses           |
| scores            |
| students          |
| teachers          |
+-------------------+
5 rows in set (0.00 sec)
mysql> SELECT * FROM teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
+-----+---------------+-----+--------+
3 rows in set (0.00 sec)

 还原注意事项:

(1) datadir 目录必段为空,除非指定 --force-non-empty-directorires 选项,否则--copy-back 选项不会覆盖,指定了 --force-non-empty-directorires 选项则已存在的文件不会被覆盖;
(2) 在恢复数据之前,必须关闭MySQL实例;
(3) 恢复备份后,记得修修文件的权限为mysql;chown -R mysql:mysql /data/mysql

4.3.3、压缩备份与还原

#备份时压缩
xtrabackup --backup --compress --target-dir=/data/compressed/
xtrabackup --backup --compress --compress-threads=4 --target-dir=/data/compressed/
#prepare前解压缩
xtrabackup --decompress --target-dir=/data/compressed/
xtrabackup --decompress --remove-original --target-dir=/data/compressed        #解压缩并清理压缩文件
#还原
xtrabackup --copy-back --target-dir=/data/backups/

4.3.4、部分备份与还原

 相关选项:

--tables        指定库中的表,支持正则表达式
    #备份test库中的所有表
    xtrabackup --backup --datadir=/var/lib/mysql --target-dir=/data/backups/ --tables="^test[.].*"
    #备份test库中的t1表
    xtrabackup --backup --datadir=/var/lib/mysql --target-dir=/data/backups/ --tables="^test[.]t1"
--tables-file   指定一个文件,该文件可以包含多个表名,文件中每行一个表名。仅备份文件中命名的表。名称完全匹配,区分大小写,不支持正则表达式匹配
    echo  "mydatabase.mytable" > /tmp/tables.txt
    xtrabackup --backup --tables-file = /tmp/tables.txt
--databases     接受以空格分隔的数据库和表列表,以databasename[.tablename]格式备份 
--databases-file    指定一个文件,该文件可以包含多个数据库和表格databasename[.tablename]形式的文件,文件中每行一个元素名称。仅备份命名的数据库和表。名称完全匹配,区分大小写,不支持正则表达式匹配
注:如要使用xtrabackup --copy-back还原数据库,还需要指定mysql,sys和performance_schema数据库,还原时需要使用这些数据库;
    xtrabackup --databases = mysql sys performance_schema ...
#部分备份
xtrabackup --user=bkpuser --password=bkp123 --backup --databases=mysql sys performance_schema hellodb --target-dir=/data/backups/partial 
#prepare部分备份
xtrabackup --prepare --export --target-dir=/data/backups/partial 
#还原
xtrabackup --copy-back --target-dir=/data/backups/partial

4.3.5、InnoDB单个表恢复

 需开启 innodb_file_per_table选项。默认情况下,所有InnoDB表和索引都存储在系统表空间的一个文件中。此选项使服务器为每个表创建一个表空间文件。

 (1) 先基于 --backup 备份数据库

xtrabackup --user=bkpuser --password=bkp123 --backup --databases=mysql sys performance_schema hellodb --target-dir=/data/backups/partial

 (2) 将数据发送到需要恢复的主机上,然后执行 --prepare

xtrabackup --prepare --export --target-dir=/data/backups/partial

 (3) 在数据库上创建表,假设为hellodb中的courses表

DROP TABLE courses;
CREATE TABLE `courses` (
    `CourseID` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
    `Course` varchar(100) NOT NULL,
    PRIMARY KEY (`CourseID`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

 (4) 丢弃表空间

ALTER TABLE hellodb.courses DISCARD TABLESPACE;

 (5) 将备份目录下的courses.ibd文件拷贝到数据库目录/data/mysql/hellodb/

cp /data/backups/partial/hellodb/courses.ibd /data/mysql/hellodb/

 (6) 导入表空间

ALTER TABLE hellodb.courses IMPORT TABLESPACE;

 (7) 验证数据即可

 

MySQL的备份与还原

上一篇:Oracle表分区[转]


下一篇:MYSQL查询今天昨天本周本月等的数据