mysql —备份和恢复

时间:2023-03-09 21:44:39
mysql —备份和恢复

备份的目的

   灾难恢复、硬件故障、软件故障、自然灾害、黑客攻击、误操作测试等数据 丢失场景

备份注意要点

  能容忍最多丢失多少数据

  恢复数据需要在多长时间内完成

  需要恢复哪些数据

还原要点

  做还原测试,用于测试备份的可用性

  还原演练

备份类型:

完全备份,部分备份

  完全备份:整个数据集

  部分备份:只备份数据子集,如部分库或表

完全备份、增量备份、差异备份

  增量备份:仅备份最近一次完全备份或增量备份(如果存在增量)以来变化 的数据,备份较快,还原复杂

  差异备份:仅备份最近一次完全备份以来变化的数据,备份较慢,还原简单

注意:二进制日志文件不应该与数据文件放在同一磁盘

冷、温、热备份

冷备:读写操作均不可进行

温备:读操作可执行;但写操作不可执行

热备:读写操作均可执行

   MyISAM:温备,不支持热备

   InnoDB: 都支持

物理和逻辑备份

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

逻辑备份:从数据库中“导出”数据另存而进行的备份,与存储引擎无关, 占用空间少,速度慢,可能丢失精度。

备份时需要考虑的因素

温备的持锁多久

备份产生的负载

备份过程的时长

恢复过程的时长

备份什么

数据

二进制日志、InnoDB的事务日志

程序代码(存储过程、存储函数、触发器、事件调度器)

服务器的配置文件

备份的目标

1、数据库数据,每个表空间单独存放

2、二进制日志,需要和数据分开存储

3、InnoDB的事务日志

4、存储过程、存储函数、触发器或事件调度器等

5、服务器的配置文件:/etc/my.cnf

备份工具

  • mysqlbackup工具:热备份,MySQL Enterprise Edition组件
  • mysqlhotcopy工具:几乎冷备,仅适用于MyISAM存储引擎
  • 基于lvm快照备份:几乎热备,需要在拍快照前锁表
  • tar + cp 等归档复制工具备份:完全冷备

mysqldump工具:逻辑备份工具,适用所有存储引擎温备;支持完全或部分备份;对InnoDB存储引擎支持热备;Schema(数据库的定义)和数据存储在一起。

mysqldump参考:
https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html
语法:
mysqldump [OPTIONS] database [tables]
mysqldump [OPTIONS] –B DB1 [DB2 DB3...]
mysqldump [OPTIONS] –A [OPTIONS]
选项:
-A:备份所有库
-B db_name1,[db_name2,...]:备份指定库
-E:备份相关的所有event scheduler
-R:备份所有存储过程和存储函数
--triggers:备份表相关触发器,默认启用,用--skip-triggers,不备份触发器
--master-data={|}:
:所备份的数据之前加一条记录为CHANGE MASTER TO语句,非注释,不指定默认为1
:记录为注释的CHANGE MASTER TO语句,注意:此选项会自动关闭--lock-tables功能,自动打开--lock-all-tables功能(除非开启--single-transaction)
-F:备份前滚动日志,锁定表完成后,执行flush logs命令,生成新的二进制日志文件,配合-A时,会导致刷新多次数据库,在同一时刻执行转储和日志刷新,
则应同时使用--flush-logs和-x,--master-data或-single-transaction,此时只刷新一次;建议:和-x,--master-data或 --single-transaction一起使用
--compact 去掉注释,适合调试,生产不使用
-d:只备份表结构
-t:只备份数据,不备份create table
-n:不备份create database,可被-A或-B覆盖
--flush-privileges:备份前刷新授权表,备份mysql库或相关时需要使用
-f:忽略SQL错误,继续执行
--hex-blob:使用十六进制符号转储二进制列(例如,“abc”变为0x616263),受影响的数据类型包括BINARY, VARBINARY,BLOB,BIT
-q:不缓存查询,直接输出,加快备份速度

MyISAM备份选项:支持温备;不支持热备,所以必须先锁定要备份的库,而后启动备份操作
-x,--lock-all-tables:加全局读锁,锁定所有库的所有表,同时加--single-transaction--lock-tables选项会关闭此选项功能,注意:数据量大时,可能会导致长时间无法并发访问数据库
-l,--lock-tables:对于需要备份的每个数据库,在启动备份之前分别锁定其所有表,默认为on,--skip-lock-tables选项可禁用,对备份MyISAM的多个库,可能会造成数据不一致

InnoDB备份选项:支持热备,可用温备但不建议用
--single-transaction:此选项Innodb中推荐使用,不适用MyISAM,此选项会开始备份前,先执
行START TRANSACTION指令开启事务此选项通过在单个事务中转储所有表来创建一致的快照。仅适用于存储在支持多版本控制的存储引擎中的表(目前只有InnoDB可以); 转储不保证与其他存储引擎保持一致。

​ 在进行单事务转储时,要确保有效的转储文件(正确的表内容和二进制日志位置),需要保证没有其他连接使用以下语句:ALTER TABLE,DROP TABLE,RENAME TABLE,TRUNCATE TABLE

​ 此选项和 --lock-tables(此选项隐含提交挂起的事务)选项是相互排斥备份大型表时,建议将--single-transaction选项和--quick结合一起使用

InnoDB建议备份策略:
mysqldump –uroot –A –F –E –R --single-transaction --master-data= --flush-privileges --triggers --hex-blob >$BACKUP/fullbak_$BACKUP_TIME.sql MyISAM建议备份策略:
mysqldump –uroot –A –F –E –R –x --master-data= --flush-privileges --triggers --hex-blob >$BACKUP/fullbak_$BACKUP_TIME.sql

xtrabackup工具:由Percona提供支持对InnoDB做热备(物理备份)的工具,支持完全备份、增量备份

由Percona公司提供的mysql数据库备份工具,开源的能够对innodb和xtradb数据库进行热备的工具;

xtrabackup 是用来备份 InnoDB 表的,不能备份非 InnoDB 表;

innobackupex 脚本用来备份非 InnoDB 表,同时会调用 xtrabackup 命令来备份 InnoDB 表,还会和 MySQL Server 发送命令进行交互,如加全局读锁(FTWRL)、获取位点(SHOW SLAVE STATUS)等。即innobackupex是在xtrabackup 之上做了一层封装实现的;

虽然目前一般不用 MyISAM 表,只是 MySQL 库下的系统表是 MyISAM 的,因此备份基本都通过 innobackupex 命令进行;

xtrabackup版本升级到2.4后,相比之前的2.1有了比较大的变化:innobackupex 功能全部集成到 xtrabackup 里面,只有一个 binary程序,另外为了兼容考虑,innobackupex作为 xtrabackup 的软链接,即xtrabackup现在支持非Innodb表备份,并且Innobackupex在下一版本中移除,建议通过xtrabackup替换innobackupex。

参考手册:https://www.percona.com/doc/percona-xtrabackup/LATEST/index.html

使用innobakupex备份时,其会调用xtrabackup备份所有的InnoDB表,复制所有关于表结构定义的相关文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相关文件,同时还会备份触发器和数据库配置信息相关的文件。
这些文件会被保存至一个以时间命名的目录中,在备份时,innobackupex还会在备份目录中创建如下文件:
)xtrabackup_checkpoints:备份类型(如完全或增量)、备份状态(如是否已经为prepared状态)和LSN(日志序列号)范围信息,每个InnoDB页(通常为16k大小)都会包含一个日志序列号,即LSN。
LSN是整个数据库系统的系统版本号,每个页面相关的LSN能够表明此页面最近是如何发生改变的;
)xtrabackup_binlog_info:MySQL服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置;
)xtrabackup_info:innobackupex工具执行时的相关信息;
)backup-my.cnf:备份命令用到的配置选项信息;
)xtrabackup_logfile:备份生成的日志文件。
用法:
innobackupex --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/
选项:
--user:该选项表示备份账号
--password:该选项表示备份的密码
--host:该选项表示备份数据库的地址
--databases:该选项接受的参数为数据名,如果要指定多个数据库,彼此间需要以空格隔开;如:"xtra_test dba_test",同时,在指定某数据库时,也可以只指定其中的某张表。
如:"mydatabase.mytable"。该选项对innodb引擎表无效,还是会备份所有innodb表
--defaults-file:该选项指定从哪个文件读取MySQL配置,必须放在命令行第一个选项位置
--incremental:该选项表示创建一个增量备份,需要指定--incremental-basedir
--incremental-basedir:该选项指定为前一次全备份或增量备份的目录,与--incremental同时使用
--incremental-dir:该选项表示还原时增量备份的目录
--include=name:指定表名,格式:databasename.tablename
--apply-log:一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。
因此,此时数据文件仍处理不一致状态。此选项作用是通过回滚未提交的事务及同步已经提交的事务至数据文件使数据文件处于一致性状态
--use-memory:该选项表示和--apply-log选项一起使用,prepare 备份的时候,xtrabackup做crash recovery分配的内存大小,单位字节。也可(1MB,1M,1G,1GB),推荐1G
--export:表示开启可导出单独的表之后再导入其他Mysql中
--redo-only:此选项在prepare base full backup,往其中merge增量备份时候使用
--copy-back:做数据恢复时将备份数据文件拷贝到MySQL服务器的datadir
--move-back:这个选项与--copy-back相似,唯一的区别是它不拷贝文件,而是移动文件到目的地。这个选项移除backup文件,用时候必须小心。
使用场景:没有足够的磁盘空间同事保留数据文件和Backup副本

注意:

1)datadir目录必须为空。除非指定innobackupex --force-non-empty-directorires选项指定,否则--copy-backup选项不会覆盖;

2)在restore之前,必须shutdown MySQL实例,不能将一个运行中的实例restore到datadir目录中;

3)由于文件属性会被保留,大部分情况下需要在启动实例之前将文件的属主改为mysql,chown -R mysql:mysql /data/mysqldb

备份方案

cp + tar == 物理冷备

将数据目录打包压缩备份,需要停服务,不推荐

​ 1)备份:

~]# mkdir /backup
~]# systemctl stop mariadb #停止服务
~]# tar Jcf /backup/mariadb_all.tar.xz /var/lib/mysql/ #打包压缩
backup]# systemctl start mariadb

​ 2)还原:

~]# systemctl stop mariadb
~]# rm /var/lib/mysql/ -rf #将损坏的库删除
~]# cd /backup/
backup]# tar xf mariadb_all.tar.xz #解压打包的数据库文件
backup]# cp -av var/lib/mysql/ /var/lib/ #还原
backup]# systemctl start mariadb #启动服务,恢复成功

lvm快照 + binlog == 几乎物理热备 + 增量备份

​ 1)备份:需要将数据库目录存放到lvm逻辑卷上

准备lvm环境:
~]# pvcreate /dev/sda5
~]# vgcreate vg0 /dev/sda5
~]# lvcreate -n lv_data -L 10G vg0
~]# lvcreate -n lv_binlog -L 10G vg0
~]# mkfs.xfs /dev/vg0/lv_data
~]# mkfs.xfs /dev/vg0/lv_binlog
~]# mkdir -pv /data/{mysqldb,binlog} #创建数据目录和二进制日志存放目录
~]# chown -R mysql:mysql /data/
~]# vim /etc/fstab
UUID=4e3d726a-d420-4c1e-812b-da315012ba86 /data/mysqldb xfs defaults
UUID=6dd98866-769f---291fbcc94ca1 /data/binlog xfs defaults
mysql < hellodb_innodb.sql   #hellodb_innodb.sql导入数据库,破坏students表
配置数据库
~]# yum install mariadb-server -y
~]# vim /etc/my.cnf
[mysqld]
datadir = /data/mysqldb #指定数据库存放路径
log_bin = /data/binlog/mariadb-bin #开启二进制日志记录,并且存放到指定路径
innodb_file_per_table = ON #开启每个表单独的表空间
~]# systemctl start mariadb
~]# mysql #连接数据库,这里省略了用户名和密码,以下都是如此
开始备份:
MariaDB [hellodb]> FLUSH TABLES WITH READ LOCK; #备份前切记锁表,防止用户继续写入
MariaDB [hellodb]> FLUSH LOGS; #滚动一下二进制日志
MariaDB [hellodb]> SHOW MASTER LOGS; #查看二进制日志的位置
+--------------------+-----------+
| Log_name | File_size |
+--------------------+-----------+
| mariadb-bin. | |
| mariadb-bin. | |
| mariadb-bin. | |
| mariadb-bin. | |
| mariadb-bin. | | #将此出记录下来,我们后边需要用到
+--------------------+-----------+
~]# lvcreate -L 5G -n lv_mysql_snap -s -p r /dev/vg0/lv_data #需要再开一个终端创建快照,不要退出mysql终端
MariaDB [hellodb]> UNLOCK TABLES; #创建快照后第一时间解锁,小心用户投诉
~]# mount -o nouuid,norecovery /dev/vg0/lv_mysql_snap /mnt/ #将快照挂载到/mnt
~]# cp -av /mnt/ /backup #拷贝数据到备份目录
~]# umount /mnt/
~]# lvremove /dev/vg0/lv_mysql_snap #拷贝完成后即时删除快照,影响服务器性能,到此完全备份完成~

2)还原:

模拟数据库损坏:
~]# rm -rf /data/mysqldb/* #服务器崩溃,直接清空库
~]# systemctl stop mariadb #停服务
开始还原:
~]# cp -av /backup/* /data/mysqldb/ #将备份的文件cp到对应的库目录下
在/etc/my.cnf的[mysqld]下加上skip_networking,禁止用户使用数据库,防止恢复过程中的数据写入
~]# systemctl start mariadb #启动服务
~]# ls -1 /data/binlog/ #查看二进制日记的文件个数
mariadb-bin.000001
mariadb-bin.000002
mariadb-bin.000003
mariadb-bin.000004
mariadb-bin.000005
mariadb-bin.000006
mariadb-bin.index
~]# mysqlbinlog --start-position=245 /data/binlog/mariadb-bin.000005 > binlog.sql #到出完全备份时间点以后的数据
~]# mysqlbinlog /data/binlog/mariadb-bin.000006 >> binlog.sql #将之后的所有数据都追加到同一sql文件中
~]# mysql < binlog.sql #利用二进制日志从我们之前完全备份的点开始增量还原

MariaDB [(none)]> use hellodb
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
MariaDB [hellodb]> show tables;
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes |
| coc |
| courses |
| scores |
| students |#已恢复
| teachers |
| toc |
+-------------------+
7 rows in set (0.00 sec)

到/etc/my.cnf的[mysqld]下删除skip_networking,重启服务,到此还原完成~

mysqldump + InnoDB + binlog= 完全逻辑热备 + 增量备份

​ 1)备份

~]# mysqldump -A -F -E -R --single-transaction --master-data= --flush-privileges  > /backup/full-`date +%F-%T`.sql  #全库完全备份

​ 2)模拟故障:

MariaDB [(none)]>MariaDB [  CREATE DATABASE db1;  #创建一个库
MariaDB [(none)]> CREATE DATABASE db2; #再创建一个库
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| db2 |
| hellodb |
| mysql |
| performance_schema |
| test |
+--------------------+
rows in set (0.00 sec)
MariaDB [none]> use hellodb;
MariaDB [hellodb]> DROP TABLE students; #误操作,将students表删除
Query OK, rows affected (0.01 sec) MariaDB [hellodb]> show tables; #students表已不在
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes |
| coc |
| courses |
| scores |
| teachers |
| toc |
+-------------------+
rows in set (0.00 sec) MariaDB [hellodb]> CREATE TABLE students (id INT() AUTO_INCREMENT PRIMARY KEY,name CHAR(),age TINYINT); #后续又有用户创建了其他的表
MariaDB [hellodb]> INSERT INTO students(name,age) VALUES ('user1',); #并且还加入了数据
MariaDB [hellodb]> select * from students; #查看后续用户创建的表里的内容
+----+-------+------+
| id | name | age |
+----+-------+------+
| | user1 | |
+----+-------+------+
row in set (0.00 sec)

3)还原:

此时,我们发现了有一个表不见了,需要紧急恢复,开始吧
MariaDB [(none)]> FLUSH TABLES WITH READ LOCK; #锁表
MariaDB [(none)]> FLUSH LOGS; #刷新滚动一次二进制日志文件
MariaDB [(none)]> SHOW MASTER LOGS; #查看当前的日志状态
MariaDB [hellodb]> show master logs;
+-------------------+-----------+
| Log_name | File_size |
+-------------------+-----------+
| maridb-bin. | |
| maridb-bin. | |
| maridb-bin. | |
| maridb-bin. | |
| maridb-bin. | |
| maridb-bin. | |
| maridb-bin. | |
| maridb-bin. | |
| maridb-bin. | |
| maridb-bin. | |
| maridb-bin. | |
| maridb-bin. | |
| maridb-bin. | |
| maridb-bin. | |
| maridb-bin. | |
+-------------------+-----------+
rows in set (0.00 sec) ~]# systemctl stop mariadb #停止服务,准备修复 ~]# head - /backup/full----\:\:.sql |grep "CHANGE MASTER"
-- CHANGE MASTER TO MASTER_LOG_FILE='maridb-bin.000014', MASTER_LOG_POS=;#找到完全备份的日志点,在mariadb-bin.000014的245 ~]# ls -l /data/binlog/
total
-rw-rw---- mysql mysql Jun : maridb-bin.
-rw-rw---- mysql mysql Jun : maridb-bin.
-rw-rw---- mysql mysql Jun : maridb-bin.
-rw-rw---- mysql mysql Jun : maridb-bin.
-rw-rw---- mysql mysql Jun : maridb-bin.
-rw-rw---- mysql mysql Jun : maridb-bin.
-rw-rw---- mysql mysql Jun : maridb-bin.
-rw-rw---- mysql mysql Jun : maridb-bin.
-rw-rw---- mysql mysql Jun : maridb-bin.
-rw-rw---- mysql mysql Jun : maridb-bin.
-rw-rw---- mysql mysql Jun : maridb-bin.
-rw-rw---- mysql mysql Jun : maridb-bin.
-rw-rw---- mysql mysql Jun : maridb-bin.
-rw-rw---- mysql mysql Jun : maridb-bin.
-rw-rw---- mysql mysql Jun : maridb-bin.
-rw-rw---- mysql mysql Jun : maridb-bin.index ~]# mysqlbinlog --start-position= /data/binlog/maridb-bin. > /backup/binlog.sq1 #将完全备份之后的二进制日志导出来 mysqlbinlog /data/binlog/maridb-bin. >> /backup/binlog.sql #导入完全备份后的二进制日志,自动执行增量备份的二进制日志 ~]# vim /backup/binlog.sql #修改导出的sql文件,把误操作的SQL语句删除 删除"DROP TABLE `testtb` /* generated by server */"这行 导入备份: ~]# rm -rf /data/mysqldb/* #先清空故障库 ~]# vim /etc/my.cnf #编辑配置文件 在[mysqld]加入skip_networking,防止用户写入数据 ~]# systemctl start mariadb #启动服务 ~]# mysql < /backup/full-2018-06-16-13\:05\:17.sql ~]# mysql < /backup/binlog.sq1 MariaDB [hellodb]> show databases; #查看一下我们的数据是否成功恢复
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 4
Current database: hellodb +--------------------+
| Database |
+--------------------+
| information_schema |
| db1 | #已恢复
| db2 | #已恢复
| hellodb |
| mysql |
| performance_schema |
| test |
+--------------------+
7 rows in set (0.00 sec) MariaDB [hellodb]> use hellodb
Database changed
MariaDB [hellodb]> select * from students; #原先hellodb表中的students表已恢复
+-------+---------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+---------------+-----+--------+---------+-----------+
| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
| 2 | Shi Potian | 22 | M | 1 | 7 |
| 3 | Xie Yanke | 53 | M | 2 | 16 |
| 4 | Ding Dian | 32 | M | 4 | 4 |
| 5 | Yu Yutong | 26 | M | 3 | 1 |
| 6 | Shi Qing | 46 | M | 5 | NULL |
| 7 | Xi Ren | 19 | F | 3 | NULL |
| 8 | Lin Daiyu | 17 | F | 7 | NULL |
| 9 | Ren Yingying | 20 | F | 6 | NULL |
| 10 | Yue Lingshan | 19 | F | 3 | NULL |
| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
| 12 | Wen Qingqing | 19 | F | 1 | NULL |
| 13 | Tian Boguang | 33 | M | 2 | NULL |
| 14 | Lu Wushuang | 17 | F | 3 | NULL |
| 15 | Duan Yu | 19 | M | 4 | NULL |
| 16 | Xu Zhu | 21 | M | 1 | NULL |
| 17 | Lin Chong | 25 | M | 4 | NULL |
| 18 | Hua Rong | 23 | M | 7 | NULL |
| 19 | Xue Baochai | 18 | F | 6 | NULL |
| 20 | Diao Chan | 19 | F | 7 | NULL |
| 21 | Huang Yueying | 22 | F | 6 | NULL |
| 22 | Xiao Qiao | 20 | F | 1 | NULL |
| 23 | Ma Chao | 23 | M | 4 | NULL |
| 24 | Xu Xian | 27 | M | NULL | NULL |
| 25 | Sun Dasheng | 100 | M | NULL | NULL |
+-------+---------------+-----+--------+---------+-----------+
25 rows in set (0.00 sec) 到现在为止,已经完成恢复,把配置文件中的skip_networking删除,重启服务,就ok!

Xtrabackup + InnoDB == 完全热备+ 增量备份

​ 1)完全备份

~]# innobackupex --user=root /backup/  #这里省略了密码

​ 2)增删数据

MariaDB [hellodb]>  INSERT INTO students(stuid,name,age,gender,classid) VALUES (,'bai',,'F',);
Query OK, row affected (0.00 sec) MariaDB [hellodb]> select * from students;
+-------+---------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+---------------+-----+--------+---------+-----------+
| | Shi Zhongyu | | M | | |
| | Shi Potian | | M | | |
| | Xie Yanke | | M | | |
| | Ding Dian | | M | | |
| | Yu Yutong | | M | | |
| | Shi Qing | | M | | NULL |
| | Xi Ren | | F | | NULL |
| | Lin Daiyu | | F | | NULL |
| | Ren Yingying | | F | | NULL |
| | Yue Lingshan | | F | | NULL |
| | Yuan Chengzhi | | M | | NULL |
| | Wen Qingqing | | F | | NULL |
| | Tian Boguang | | M | | NULL |
| | Lu Wushuang | | F | | NULL |
| | Duan Yu | | M | | NULL |
| | Xu Zhu | | M | | NULL |
| | Lin Chong | | M | | NULL |
| | Hua Rong | | M | | NULL |
| | Xue Baochai | | F | | NULL |
| | Diao Chan | | F | | NULL |
| | Huang Yueying | | F | | NULL |
| | Xiao Qiao | | F | | NULL |
| | Ma Chao | | M | | NULL |
| | Xu Xian | | M | NULL | NULL |
| | Sun Dasheng | | M | NULL | NULL |
| | bai | | F | | NULL |#此行为新增的
+-------+---------------+-----+--------+---------+-----------+
rows in set (0.00 sec)

3)增量备份

~]# mkdir /backup/inc{,}  #创建增量备份的目录
~]# innobackupex --incremental /backup/inc1/ --incremental-basedir=/backup2018--16_14--/ #指定在完全备份的基础上增量备份

​ 4)增删数据

MariaDB [(none)]> CREATE DATABASE db3;
MariaDB [(none)]> DROP TABLE school.students; #误操作删除了表
MariaDB [(none)]> use hellodb
MariaDB [hellodb]>  INSERT INTO teachers(tid,name,age,gender) VALUES (,'yuan',,'F');#后续又有人修改
Query OK, row affected (0.01 sec) MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| | Song Jiang | | M |
| | Zhang Sanfeng | | M |
| | Miejue Shitai | | F |
| | Lin Chaoying | | F |
| | yuan | | F |
+-----+---------------+-----+--------+
rows in set (0.00 sec)MariaDB [hellodb]> SELECT * FROM students; #到此出发现students表不见了,怎么办? ERROR 1146 (42S02): Table 'school.students' doesn't exist

5)故障出现

~]# rm -rf /data/mysqldb/*  #还原前清空数据目录
MariaDB [(none)]> show databases; #此时数据库已经没了
+--------------------+
| Database |
+--------------------+
| information_schema |
+--------------------+

​ 6)紧急还原

恢复完全备份和增量备份:
~]# systemctl stop mariadb #停止服务
~]# innobackupex --apply-log --redo-only /backup/--14_10--/ #整理完全备份的数据,因为需要保留没有做完的事务日志所以一定要记得加"--redo-only"选项
~]# innobackupex --apply-log --redo-only /backup/--14_10--/ --incremental-dir=/backup/inc1/--14_10--/ #在完全备份的基础上将增量备份导入到一块,这里是最新的增量备份,"--redo-only"选项可以不加,加上也可以,为了误操作我就都加了
~]# ls /data/mysqldb/ #确认一下数据库目录是否为空
~]# innobackupex --copy-back /backup/--14_10--/ #导入备份数据
~]# chown -R mysql:mysql /data/mysqldb/ #记得修改数据的所属组和所属者
~]# vim my.cnf 加入skip_networking,防止此时用户操作数据
~]# systemctl start mariadb #启动服务,此时已经恢复到了最新的备份时的状态了
依靠二进制日志,恢复最新增量备份到now的数据:
~]# cat /backup/--14_10--/xtrabackup_binlog_info #查看一下备份时的二进制日志记录点
mariadb-bin.
~]# ls - /data/binlog/ #看看我们的二进制日志文件记录到哪里了
mariadb-bin.
mariadb-bin.
mariadb-bin.
mariadb-bin.
mariadb-bin.
mariadb-bin.
mariadb-bin.
mariadb-bin.
mariadb-bin.
mariadb-bin.
mariadb-bin.
mariadb-bin.
mariadb-bin.
mariadb-bin.index
~]# mysqlbinlog --start-position= /data/binlog/mariadb-bin. > /backup/binlog.sql #将最新增量备份之后的二进制日志记录的数据导出来
~]# mysqlbinlog /data/binlog/mariadb-bin. >> /backup/binlog.sql
~]# mysqlbinlog /data/binlog/mariadb-bin. >> /backup/binlog.sql
编辑 /backup/binlog.sql 文件,将 "DROP TABLE `school`.`students` /* generated by server */" 删除,撤销误删除操作
MariaDB [(none)]> SET sql_log_bin=; #先临时关闭二进制日记记录功能
MariaDB [(none)]> source /backup/binlog.sql #导入增量备份之后的最新数据
查看确认一下数据有没有恢复完整,把my.cnf中的skip_networking删除,重启服务
到此ok!

使用Xtrabackup实现单表备份

​ 1)备份单表

~]# innobackupex --include="testdb.testlog" /backup  #备份表数据
~]# mysql -e 'SHOW CREATE TABLE testdb.testlog' > /backup/desc_testdb_testlog.sql #备份表空间
~]# mysql -e 'DROP TABLE testdb.testlog' #模拟故障,删除testlog表

​ 2)还原单表

~]# innobackupex --apply-log --export /backup/--14_17--/  #整理表数据
~]# vim /backup/desc_testdb_testlog.sql #编辑创建表空间的语句,删除以下字段
Table Create Table
testlog
~]# mysql testdb < /backup/desc_testdb_testlog.sql #导入表空间
~]# mysql testdb -e 'DESC testlog' #查看是否导入成功
+-------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+----------------+
| id | int() | NO | PRI | NULL | auto_increment |
| name | char() | YES | | NULL | |
| age | int() | YES | | | |
+-------+----------+------+-----+---------+----------------+
~]# mysql -e 'ALTER TABLE testdb.testlog DISCARD TABLESPACE' #清除表空间
~]# cd /backup/--14_17--/testdb/
testdb]# cp testlog.cfg testlog.exp testlog.ibd /var/lib/mysql/testdb/ #将表数据复制到库目录
~]# chown -R mysql:mysql /var/lib/mysql/testdb/ #修改所属者和所属组
~]# mysql -e 'ALTER TABLE testdb.testlog IMPORT TABLESPACE' #导入表空间