物理备份 对数据库的二进制文件(如数据文件、日志文件等)进行备份,适用于故障快速恢复,因为它直接备份数据库的原始文件。
适用场景
描述
整个数据库恢复
当需要完全恢复数据库时,包括数据和数据库的状态,物理备份是最好的选择。
数据库规模较大
对于大型数据库,物理备份通常比逻辑备份更快速和高效。
数据库备份和恢复频繁
如果需要频繁备份和恢复数据库,物理备份可能是更有效的选择,因为它通常比逻辑备份更快。
大型数据库通常是指数据量巨大、访问频繁、复杂度高、需要高可用性和扩展性的数据库系统。虽然没有一个固定的定义来界定何为大型数据库,但通常可以通过以下几个指标来判断一个数据库是否为大型数据库:
数据量:大型数据库通常包含数十亿到数百亿条记录甚至更多,数据量通常在几十 TB 或几百 TB 以上。
并发访问量:大型数据库通常需要支持大量并发用户的高频访问,要求数据库系统能够提供高性能和高吞吐量。
复杂性:大型数据库往往包含多个表、复杂的关联和存储过程,需要复杂的查询和数据处理。
高可用性和可靠性需求:大型数据库通常需要实现高可用性和故障容忍,并且要求数据库系统能够快速恢复,以确保服务不中断。
扩展性需求:大型数据库通常需要支持水平和垂直扩展,以应对数据量和并发访问量的增长。
备份方式
描述
冷备份(脱机备份)
关闭数据库的时候进行
热备份(联机备份)
数据库处于运行状态,依赖于数据库的二进制日志文件
温备份
数据库锁定表格(不可写入但可读)的状态下进行备份操作
逻辑备份 对数据库逻辑组件(如:表数据、结构等数据库对象)的备份,适用于可以编辑数据值或表结构,备份文件大小通常比物理备份小。
适用场景
描述
数据库迁移
当需要将数据从 A
数据库迁移到 B
数据库时,逻辑备份是一个理想的选择,因为它可以在不同的数据库之间方便地导入和恢复数据。
数据库结构更改
如果需要备份和恢复数据库的结构,如表结构、存储过程、触发器等,逻辑备份是更合适的选择。
部分数据恢复
逻辑备份允许选择性地恢复数据库中的特定数据,因为备份文件中的数据以文本形式保存。
备份策略
备份方式
描述
占用空间
备份速度
恢复速度
操作复杂度
完全备份(Full Backup)
每次对整个数据库的所有数据和文件进行备份,备份文件占用大量的空间,并且存在大量的重复数据;恢复时,将文件导入即可,刚开始速度很快,随着数据增大,速度会越来越慢。
很多
刚开始快,后面会变慢
最快
简单
差异备份(Differential Backup)
备份自从上次完全备份之后被修改过的文件,可能存在重复数据,也会占用额外的空间;恢复时,先恢复完全备份的数据,再导入差异备份的数据。
中等
比完全备份快
比完全备份慢
一般
增量备份(Incremental Backup)
备份上次完整或增量之后的数据,不会出现重复的数据,不会占用额外的磁盘空间;恢复时,先要完全恢复,再依次做增量恢复。
很少
最快
最慢
复杂
操作 完全备份 物理冷备份与恢复 InnoDB 存储引擎的数据库在磁盘上存储成 3 个文件:db.opt(表属性文件)、表名.from(表结构文件)、表名.ibd(表数据文件)。
MySQL 5.7 版本数据存放路径
备份步骤
关闭 mysqld
服务
压缩迁移
1 2 3 tar zcvf data_$(data '+%Y%m%d' ).tar.gz ./* mv data_20240426.tar.gz /home
恢复步骤
关闭 mysqld
服务
解压还原
1 2 3 4 5 cd /hometar zxvf data_20240426.tar.gz -C /var/lib/mysql chown -R mysql:mysql /var/lib/mysql
开启 mysqld
服务
mysqldump 备份(温备份) 备份一个或多个完整的库(包括其中所有表) 备份数据库 1 2 3 4 5 6 7 8 mysqldump -h hostname -u username -p password dbname tablename > backupfile.sql mysqldump -h hostname -u username -p password --databases dbname1 dbname2 > backupfile.sql mysqldump -h hostname -u username -p password --all-databases > backupfile.sql
恢复数据库 1 2 3 4 5 6 mysql -h hostname -u username -p password dbname < backupfile.sql USE dbname; SOURCE backupfile.sql;
增量备份 增量备份与恢复 MySQL的增量备份通常使用二进制日志(binary log)来实现。二进制日志是MySQL的一种日志,它记录了所有对数据库的更改操作,包括插入、更新、删除等操作。
开启二进制日志功能 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 [root@localhost ~]# vi /etc/my.cnf [mysqld] log-error=/usr/local/mysql/data/mysql_error.log general_log=ON general_log_file=/usr/local/mysql/data/mysql_general.log log-bin=mysql-bin 或 log_bin=mysql-bin slow_query_log=ON slow_query_log_file=/usr/local/mysql/data/mysql_slow_query.log long_query_time=5 [root@localhost ~]# systemctl restart mysqld.service 查看日志方式: mysql> show variables like 'general%' ; mysql> show variables like 'log_bin%' ; mysql> show variables like '%slow%' ; mysql> show variables like 'long_query_time' ; mysql> set global slow_query_log=ON; [root@localhost ~]# ls /usr/local/mysql/data auto.cnf ib_logfile0 mysql mysql_error.log performance_schema ib_buffer_pool ib_logfile1 mysql-bin.000001 mysql_general.log sys ibdata1 ibtmp1 mysql-bin.index mysql_slow_query.log
二进制日志(binlog)记录格式
格式
描述
STATEMENT
(基于 SQL
语句)
记录的是 SQL
语句,日志量过大
ROW
(基于行)
记录的是每一行数据的变化,如果遇到 update
、delete
数据量会越来越大
MIXED
(推荐使用)
会根据 SQL
语句的类型来选择使用 statement
格式还是 row
格式,它的缺点是可能会因为 SQL
语句的类型而导致日志文件的大小和恢复的准确性有所不同
查看二进制日志文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 [root@localhost ~]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql-bin.000001 /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; ROLLBACK/*!*/; SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/; DELIMITER ; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; 二进制日志中需要关注的部分 at :开始的位置点 end_log_pos:结束的位置 时间戳: 240325 18:01:18 SQL语句
备份步骤
完全备份
1 mysqldump -uroot -p123456 dbname tablename > /target_file/data_$(data + '%Y%m%d' ).sql
生成新的二进制日志文件
1 2 3 mysqldump -uroot -p123456 flush-logs cp mysql-bin.000001 /target_file/
恢复步骤
一般恢复
重定向恢复
1 mysql -uroot -p123456 dbname < /target_file.sql
二进制日志恢复
1 mysqlbinlog --no-defaults /mysql-bin.000001 | mysql -uroot -p123456
断点恢复
实现目标:class 表中5条数据,1、2条记录在mysql-bin.000001日志,3-5条记录在mysql-bin.000001日志,模拟第4条数据操作故障,实现跳过第4条断点恢复。
插入3-5条数据
1 2 3 4 5 6 7 8 9 10 11 12 13 mysql> insert into class values (3,'wang'); mysql> insert into class values (4,'wu'); mysql> insert into class values (5,'zhen'); mysql> select * from class; +------+----------+ | id | name | +------+----------+ | 1 | zhangsan | | 2 | lisi | | 3 | wang | | 4 | wu | | 5 | zhen | +------+----------+
备份 mysql-bin.000002 日志
1 2 3 4 5 [root@localhost data]# ls auto.cnf ib_logfile0 mysql mysql-bin.index mysql_slow_query.log sys ib_buffer_pool ib_logfile1 mysql-bin.000001 mysql_error.log performance_schema ibdata1 ibtmp1 mysql-bin.000002 mysql_general.log school [root@localhost data]# cp mysql-bin.000002 /opt/
生成新的二进制日志,并删除 class 表
1 2 3 4 5 mysqladmin -u root -p123456 flush-logs [root@localhost data]# ls auto.cnf ib_logfile0 mysql mysql-bin.000003 mysql_general.log school ib_buffer_pool ib_logfile1 mysql-bin.000001 mysql-bin.index mysql_slow_query.log sys ibdata1 ibtmp1 mysql-bin.000002 mysql_error.log performance_schema
基于位置点恢复
1 [root@localhost data]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /opt/mysql-bin.000001
这里注意,school 库未删除,恢复从(BEGIN)操作 ID 为“384”到(end_log_pos)操作 ID 为“1097”之前的数据
1 2 3 4 5 6 7 8 9 [root@localhost ~]# mysqlbinlog --no-defaults --start-position='384' --stop-position='1097' /opt/mysql-bin.000001 | mysql -uroot -p123456 mysql> select * from class; +------+----------+ | id | name | +------+----------+ | 1 | zhangsan | | 2 | lisi | +------+----------+
查看mysql-bin.000002日志
1 [root@localhost ~]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /opt/mysql-bin.000002
这里注意,由于mysql-bin.000002存放着3-5条数据的举例,需要先恢复从(BEGIN)操作 ID 为“2832”到(end_log_pos)操作 ID 为“3100”之前的数据
1 2 3 4 5 6 7 8 9 10 [root@localhost ~]# mysqlbinlog --no-defaults --start-position='2832' --stop-position='3100' /opt/mysql-bin.000002 | mysql -uroot -p123456 mysql> select * from class; +------+----------+ | id | name | +------+----------+ | 1 | zhangsan | | 2 | lisi | | 3 | wang | +------+----------+
查看mysql-bin.000002日志
1 [root@localhost ~]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /opt/mysql-bin.000002
这里注意,由于最后一条插入记录后没有操作,直接恢复到(BEGIN)操作 ID 为“3366”之后的数据
1 2 3 4 5 6 7 8 9 10 11 [root@localhost ~]# mysqlbinlog --no-defaults --start-position='3366' /opt/mysql-bin.000002 | mysql -uroot -p123456 mysql> select * from class; +------+----------+ | id | name | +------+----------+ | 1 | zhangsan | | 2 | lisi | | 3 | wang | | 5 | zhen | +------+----------+
基于时间点恢复
时间点恢复与断点恢复同理,只需要将 at 值改为对应的时间即可。
1 2 3 4 5 6 7 8 9 10 11 mysqlbinlog [--no-defaults] --start-datetime='年-月-日 小时:分钟:秒' --stop-datetime='年-月-日小时:分钟:秒' 二进制日志 | mysql -u 用户名 -p 密码 mysqlbinlog --no-defaults --stop-datetime='2024-03-25 20:00:00' /opt/mysql-bin.000001 | mysql -uroot -p mysqlbinlog --no-defaults --start-datetime='2024-03-25 20:00:00' /opt/mysql-bin.000001 | mysql -uroot -p