Files
rikako-note/mysql/mysql文档/mysql_备份.md
2025-09-01 19:34:39 +08:00

145 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 备份
## 概述
通常来讲,备份分为如下类型:
- 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
```
通过`--single-transaction`可以保证备份的一致性,示例如下:
```sql
mysqldump --single-transaction test >test_backup.sql
```
上述操作针对`test`数据库创建了一个备份。
备份出的内容为表结构和表数据。
mysqldump命令用友如下较为重要的参数
#### --single-transaction
当指定了`--single-transaction`参数后,其在备份开始前会先执行`start transaction`命令,从而保证备份数据的一致性。
该参数只针对innodb存储引擎有效且在启用该参数进行备份时需要确保没有ddl语句在执行一致性读操作并不能对ddl进行隔离。
#### --lock-tables(`-l`)
在备份时会依次对表进行锁定一般用于myisam存储引擎在备份时只能对数据库执行读操作同样可以保证备份的一致性。
对于innodb存储引擎并不需要使用`-l`参数,使用`--single-transaction`参数即能够保证备份数据的一致性。
> `--single-transaction`选项和`--lock-tables`选项是互斥的,并不能够同时指定。
#### --lock-all-tables(`-x`)
在使用`-x`时,会针对数据库中所有的表都进行加锁,其能够避免`--lock-tables`不能锁住所有的表的问题。
#### --add-drop-database
`create database`之前先调用`drop database`,该选项需要和`--all-databases`/`--databases`一起使用。默认情况下,导出的备份中并不会含有`create database`语句,除非手动指定该选项。
#### --routinues
该选项用于备份存储过程和函数
#### --triggers
该选项用于备份触发器
#### --hex-blob
`binary, varbinary blog text`类型备份为16进制的格式。
### select ... into outfile
`select ... into outfile`也是一种逻辑备份方法,用于导出一张表中的数据,示例如下:
```sql
select * into outfile '/root/a.txt` from a;
```
其中,导出路径的权限必须是`mysql:mysql`否则mysql会报错没有导出权限。
如果想要导出的文件已经存在,同样也会报错。
## 逻辑备份恢复
### mysqldump
mysqldump的逻辑备份恢复比较简单只需要执行备份出的sql语句即可示例如下
```bash
mysql -uroot -p <test_backup.sql
```
除了上述方式外还可以通过source命令来对逻辑备份进行恢复示例如下
```mysql
mysql> source /home/mysql/test_backup.sql
```
### 二进制日志的备份和恢复
通过二进制日志用户可以实现point-in-time的恢复。
在备份二进制日志之前,可以通过`flush logs`命令来生成一个新的二进制日志文件,然后对之前的二进制日志文件进行备份。
可以通过`mysqlbinlog`命令对二进制日志进行恢复,示例如下:
```bash
mysqlbinlog binlog.0000001 | mysql -uroot -p test
```
如果要恢复多个二进制文件,可以按照如下方式:
```bash
mysqlbinlog binlog.[0-10]* | mysql -u root -p test
```
也可以通过`mysqlbinlog`命令导入到一个文件然后再对文件执行source。
可以通过`--start-position``--stop-position`从二进制日志的指定偏移量来进行恢复,这样可以针对某些语句进行跳过,示例如下:
```bash
mysqlbinlog --start-position=107856 binlog.0000001 | mysql -uroot -p test
```
`--start-datetime``--stop-datetime`则是可以选择从二进制日志的某个时间点来进行恢复。