# 备份 ## 概述 通常来讲,备份分为如下类型: - Hot Backup(热备):在数据库运行的同时直接备份,同时也被称为`在线备份` - Cold Backup(冷备):在数据库停止的情况下进行备份,一般只需要复制数据库的物理文件`离线备份` - Warm Backup(温备):Warm Backup类似于Hot Backup,同样也是在数据库运行时进行备份,但是和Hot Backup相比,Warm Backup会对当前数据库的操作存在影响(`例如,在备份时添加全局的共享锁,从而保证备份数据的一致性`)、 按照备份后的文件内容,也可以对备份做出如下划分: - 逻辑备份:对mysql而言,逻辑备份代表备份后产生的文件,其文件内容是可读的,一般由文本组成,内容是`sql语句`或是`表内的实际数据` - 常用的逻辑备份有`mysqldump`和`select * into outfile`等,这种方式可以观察导出文件的内容 - 对于逻辑备份而言,其恢复过程一般耗时较长 - 裸文件备份:裸文件备份是指对数据库的物理文件进行复制,既可以在数据库运行时进行复制,也可以在数据库停止运行时复制 - 对于裸文件备份,其数据恢复的耗时一般远小于逻辑备份 若按照数据库备份的内容,即可以对备份做出如下划分: - 完全备份:完全备份是指对数据库中所有数据做一个全量备份 - 增量备份:增量备份是指在上次完全备份的基础上,对发生修改的数据进行备份 - 日志备份:对于mysql而言,日志备份主要是指对mysql数据库的binlog进行备份,其记录了`对数据库造成修改的事件`,通过对binlog进行replay,能够实现数据库的`point-in-time`恢复 - 对于mysql数据库的`replication`,其原理即是异步的将binlog传输到slave数据库,并在slave数据库对binlog的内容进行replay ### 增量备份原理 在mysql中,并没有官方的增量备份方法被提供,大多是通过binlog来完成增量备份的工作。通过binlog来实现的备份较增量备份方案来说效率较低。 `xtrabackup`工具提供了增量备份方案,其原理是通过记录每页最后的checkpoint lsn,如果大于之前全量备份时的lsn,那么就对该页进行备份,否则无需备份该页。 ### 数据一致性 在进行数据备份时,`要求数据在备份时是一致的`。例如在玩家购买道具时,其会先扣款并对道具进行增加,如果数据不一致,那么则可能发生扣款已经发生但是道具尚未被添加这类数据不一致的情况。 对于innodb而言,由于其支持mvcc,故而对保证数据一致性的备份实现比较简单。在备份时,可以先开启一个事务,然后导出一系列相关的表,然后提交。由于undo log和read view的设计,可以保证事务中读取到的数据是一致的。 对于mysqldump工具而言,可以通过添加`--single-transaction`选项来获取innodb的一致性备份,原理和上述所示的相同,备份逻辑会在一个长事务中执行。`在使用mysqldump进行备份时,务必添加--single-transaction选项`。 ## Cold Backup 对于innodb存储引擎而言,cold backup相对简单,只需要备份mysql数据库的frm文件(mysql8中没有该类型文件)、共享表空间文件、独立表空间文件、redo log文件即可。另外,建议定期备份mysql数据库的配置文件`my.cnf`,有利于恢复操作。 cold backup存在如下优点: - 备份简单,仅需复制相关文件即可 - 备份文件易于在不同操作系统、不同mysql版本上进行复制 - 恢复速度快,仅需拷贝文件即可,无需执行sql语句也无需进行索引重建 cold backup存在如下缺点: - innodb存储引擎的cold backup文件通常要比逻辑文件大很多,因为表空间中存放着很多其他数据,例如`undo log段`和`change buffer`等 - cold backup并不总是可以轻易跨平台,操作系统、mysql版本、文件大小写敏感、浮点格式都会造成问题 > change buffer也是系统表空间的一部分,故而,change buffer也存在磁盘页。在进行cold backup时,同样需要备份change buffer。 ## 逻辑备份 ### mysqldump mysqldump工具通常用于创建数据库的备份或是在不同数据库之间对数据进行移植,如从mysql低版本升级到mysql高版本,或从mysql数据库迁移到oracle、sql server等数据库。 mysqldump的语法如下所示: ```sql mysqldump [arguments] >file_name ``` 如果想用mysqldump备份所有的数据库,可以使用如下命令: ```sql mysqldump --all-databases >dump.sql ``` 如果想要备份指定的数据库,可以使用如下命令 ```sql mysqldump --databases db1 db2 db3 > dump.sql ```