Mysql 备份与还原

一、数据备份的重要性

1、备份的主要目的是灾难恢复
2、在生产环境中,数据的安全性至关重要
3、任何数据的丢失都可能产生严重的后果
4、造成数据丢失的原因
程序错误
人为操作错误
运算错误
磁盘故障
灾难 (如火灾、地震) 和盗窃

二、数据库备份类型

2.1****物理备份

数据库备份可以分为物理备份和逻辑备份。物理备份是对数据库操作系统的物理文件(如数据文件、日志文件等)的备份。这种类型的备份适用于在出现问题的时候需要快速恢复的大型重要数据库。
物理备份又可以成为冷备份(脱机备份)、热备份(连接备份)和温备份
① 冷备份**(脱机备份)**
冷备份 (脱机备份) :是在关闭数据库的时候进行的(tar)
冷备份也被称为脱机备份,它是指在数据库关闭的情况下进行的备份操作,因此也被称为全备份。这种备份方式的优点是简单全面且无需额外资源,但劣势就是必须在数据库脱机的情况下进行,这在生产环境中往往是无法接受的。
② 热备份**(联机备份)**
热备份 (联机备份) :数据库处于运行状态,依赖于数据库的日志文件(mysqlhotcopy mysqlbackup)
热备份也称为在线备份,这种备份在数据库运行(在线)状态下进行,可以提供24x7的服务,不会因为备份而影响业务的正常运行。这是一个比较复杂的过程,需要数据库的支持,并且备份过程中需要对每个数据文件申请开始和结束备份的操作,否则可能会备份到一些不一致的数据。热备份优点是可以在数据库运行过程中进行备份,备份的细粒度可以调控,对业务几乎无影响;缺点是复杂,消耗系统和数据库资源
③ 温备份
温备份 :数据库锁定表格(不可写入但可读)的状态下进行备份操作(mysqldump)
温备份介于冷备份和热备份之间。一般来讲,温备份是指数据库在非峰值时间进行的备份,这时数据库可能未关闭但流量较小。和冷备份与热备份相比,温备份的优点是可以供不停机的环境下用作备份,同时也不会像热备份那样对在线服务产生太大影响;但和热备份相比,它无法提供24x7的全天候备份服务。当然,实际应用中这个概念使用得较少,通常用冷备份和热备份来区分备份操作。

**2.**2 逻辑备份

逻辑备份是对数据库逻辑组件的备份.表示为逻辑数据库结构
这种类型的备份适用于可以编辑数据值或表结构
从数据库的备份策略角度来看,备份又可分为完全 备份、差异备份和增量备份
① 完全备份
说法一:每次对数据进行完整备份,即对整个数据库、数据库结构和文件结构的备份,保存的是备份完成时刻的数据库,是差异备份与增量备份的基础完全备份的备份与恢复操作都非常简单方便,但是数据存在大量的重复并且会占用大量的磁盘空间,备份的时间也很长
说法二:这种备份策略是最简单和最可靠的,但是需要占用大量的存储空间和时间。这种策略通常在首次备份或者数据量不大的情况下使用
总结:每次都进行完全备份,会导致备份文件占用空间巨大,并且有大量的重复数据; 恢复时,直接使用完全备份的文件即可
② 差异备份
说法一:备份那些自从上次完全备份之后被修改过的所有文件,备份的时间节点是从上次完整备份起,备份数据量会越来越大。恢复数据时只需要恢复上次的完全备份与最佳的一次差异备份
说法二:差异备份备份自上次全量备份以后的新数据。这种备份策略在存储空间和恢复时间上的需求介于全量备份和增量备份之间。
总结:每次差异备份,都会备份上一次完全备份之后的数据,可能会出现重复数据。;恢复时,先恢复完全备份的数据,再恢复差异备份的数据
③ 增量备份
说法一:只有那些在上次完全备份或者增量备份后被修改的文件才会被备份以上次完整备份或上次增量备份的时间为时间点,仅备份期间内的数据变化,因而备份的数据量小,占用空间小,备份速度快。但恢复时,需要从上一次的完整备份开始到最后一次增量备份之间的所有增量依次恢复,如中间某次的备份数据损坏,将导致数据的丢失
每次增量备份都是在备份在上一次完成全备份
说法二:增量备份只会备份自上次备份以后的新数据。这种备份策略可以节省存储空间和时间,但是恢复数据需要所有的备份。如果有一个备份丢失或者损坏,那么可能导致无法完全恢复数据。
总结:每次增量备份都是备份在上一次完全备份或者增量备份之后的数据,不会出现重复数据的情况,也不会占用额外的磁盘空间
恢复数据,需要按照次序恢复完全备份和增量备份的数据
备份方式比较
逻辑备份的策略(增、全、差异)
如何选择逻辑备份策略(频率)
合理值区间 ⭐⭐⭐
一周一次的全备,全备的时间需要在不提供业务的时间区间进行 PM 10点 AM 5:00之间进行全备
增量:3天/2天/1天一次增量备份
差异:选择特定的场景进行备份
一个处理(NFS)提供额外空间给与mysql 服务器用

三、常见的备份方法

3.1****物理冷备

备份时数据库处于关闭状态,直接打包数据库文件(tar)
备份速度快,恢复时也是最简单的

3.2专用备份工具mysqldumpmysqlhotcopy

mysqldump 常用的逻辑备份工具
mysqlhotcopy 仅拥有备份 MyISAM 和 ARCHIVE 表

3.3****启用二进制日志进行增量备份

进行增量备份,需要刷新二进制日志
MySQL支持增量备份,进行增量备份时必须启用二进制日志。二进制日志文件为用户提供复制,对执行备份点后进行的数据库更改所需的信息进行恢复。如果进行增量备份(包含自上次完全备份或增量备份以来发生的数据修改),需要刷新二进制日志。

3.4****第三方工具备份

免费的MySQL 热备份软件 Percona XtraBackup mysqlbackup

四、MySQL完全备份

是对整个数据库、数据库结构和文件结构的备份
保存的是备份完成时刻的数据库
是差异备份与增量备份的基础
MySQL完全备份优缺点
1、优点:
备份与恢复操作简单方便
2、缺点:
数据存在大量的重复
占用大量的备份空间
备份与恢复时间长

五、数据库完全备份分类

5.1****物理冷备份与恢复

关闭MySQL数据库
使用tar命令直接打包数据库文件夹
直接替换现有MySQL目录即可

5.2 mysqldump****备份与恢复

MySQL自带的备份工具,可方便实现对MySQL的备份
可以将指定的库、表导出为SQL 脚本
使用命令mysq|导入备份的数据

六、实战案列

环境准备:

6.1 MySQL****完全备份与恢复

InnoDB 存储引擎的数据库在磁盘上存储成三个文件: db.opt(表属性文件)、表名.frm(表结构文件)、表名.ibd(表数据文件)。

6.1.1****物理冷备份与恢复

复制代码
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| ceshi              |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> create database szsxjd;         # 创建数据库
Query OK, 1 row affected (0.02 sec)

mysql> use szsxjd;       # 使用数据库,创建表头与数据
Database changed
mysql> create table if not exists infol (id int(4) not null auto_increment, name varchar(10) not null, age char(10) not null, hobby varchar(50), primary key(id) );
Query OK, 0 rows affected (0.10 sec)

mysql> insert into infol values(1,'user1',20 ,'running');
Query OK, 1 row affected (0.01 sec)

mysql> insert into infol values(2,'user2',30 ,'singing');
Query OK, 1 row affected (0.02 sec)

# 退出,停止数据库
[root@master ~]# systemctl stop mysqld
[root@master ~]# ls /usr/local/mysql/data/
auto.cnf  ib_buffer_pool  ib_logfile0  master-bin.000001  mysql               sys
ceshi     ibdata1         ib_logfile1  master-bin.index   performance_schema  szsxjd

# 切换到/opt/ ,压缩备份
[root@master ~]# cd /opt/
[root@master opt]# tar zcvPf mysql_all_$(date +%F).tar.gz /usr/local/mysql/data/

# 把源目录移动到/opt/,解压恢复
[root@master opt]# mv /usr/local/mysql/data/ /opt/
[root@master opt]# ls
boost_1_59_0.tar.gz  mysql-5.7.17         mysql_all_2025-12-04.tar.gz
data                 mysql-5.7.17.tar.gz  rh
[root@master opt]# tar zxvPf mysql_all_2025-12-04.tar.gz /usr/local/mysql/data/

# 启动mysql,查看已恢复的库表
[root@master opt]# systemctl start mysqld
[root@master opt]# mysql -u root -p123456
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| ceshi              |
| mysql              |
| performance_schema |
| sys                |
| szsxjd             |
+--------------------+
6 rows in set (0.01 sec)

mysql> show tables in szsxjd;
+------------------+
| Tables_in_szsxjd |
+------------------+
| infol            |
+------------------+
1 row in set (0.00 sec)

mysql> select * from infol;
+----+-------+-----+---------+
| id | name  | age | hobby   |
+----+-------+-----+---------+
|  1 | user1 | 20  | running |
|  2 | user2 | 30  | singing |
+----+-------+-----+---------+
2 rows in set (0.00 sec)

6.1.2 mysqldump****备份与恢复(温备份)

复制代码
(1)、完全备份一个或多个完整的库 (包括其中所有的表)
mysqldump -u root -p[密码] --databases 库名1 [库名2] ... > /备份路径/备份文件名.sql #导出的就是数据库脚本文件

# 添加创建表info2,并添加数据
mysql> create table info2 (id int, name char(10), age int, sex char(4) );
Query OK, 0 rows affected (0.02 sec)

mysql> insert into info2 values(1, 'user1', 18, '男');
Query OK, 1 row affected (0.00 sec)

mysql> insert into info2 values(2,'user2',22,'男');
Query OK, 1 row affected (0.00 sec)

# 查看所有表,准备备份
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| ceshi              |
| mysql              |
| performance_schema |
| sys                |
| szsxjd             |
+--------------------+
6 rows in set (0.01 sec)

# 进行备份并查看
[root@master sqldump]# mysqldump -uroot -p123456 --databases ceshi > ceshi.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@master sqldump]# mysqldump -uroot -p123456 --databases ceshi szsxjd > ceshi_szsxjd.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@master sqldump]# ls
ceshi.sql  ceshi_szsxjd.sql

(2)、完全备份 MySQL 服务器中所有的库
mysqldump -u root -p[密码] --all-databases > /备份路径/备份文件名.sql
# 例
[root@master sqldump]# mysqldump -uroot -p123456 --all-databases > all.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@master sqldump]# ls
all.sql  ceshi.sql  ceshi_szsxjd.sql

(3)、完全备份指定库中的部分表
mysqldump -u root -p[密码] 库名 [表名1] [表名2] ... > /备份路径/备份文件名.sql
例:
[root@master sqldump]# mysqldump -uroot -p123456 szsxjd infol info2 > szsxjd.infol_info2.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@master sqldump]# ls
all.sql  ceshi.sql  ceshi_szsxjd.sql  szsxjd.infol_info2.sql

mysqldump -u root -p[密码] [-d] szsxjd infol  > /opt/szsxjd_infol.sql
#使用"-d"选项,说明只保存数据库的表结构
#不使用"-d"选项,说明表数据也进行备份
#做为一个表结构模板

(4)查看备份文件
[root@master sqldump]# grep -v "^--" /opt/sqldump/szsxjd.infol_info2.sql |grep -v "^/" | grep -v "^$" 
DROP TABLE IF EXISTS `infol`;
CREATE TABLE `infol` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) NOT NULL,
  `age` char(10) NOT NULL,
  `hobby` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
LOCK TABLES `infol` WRITE;
INSERT INTO `infol` VALUES (1,'user1','20','running'),(2,'user2','30','singing');
UNLOCK TABLES;
DROP TABLE IF EXISTS `info2`;
CREATE TABLE `info2` (
  `id` int(11) DEFAULT NULL,
  `name` char(10) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sex` char(4) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
LOCK TABLES `info2` WRITE;
INSERT INTO `info2` VALUES (1,'user1',18,'男'),(2,'user2',22,'男');
UNLOCK TABLES;
[root@master sqldump]#

6.1.3 Mysql****完全恢复

复制代码
#恢复数据库
1.使用mysqldump导出的文件,可使用导入的方法
source命令
mysql命令
2.使用source恢复数据库的步骤
登录到MySQL数据库,执行source备份sql脚本的路径

例
# 使用数据库,查看表,删除表,source 恢复
mysql> use szsxjd
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
mysql> show tables;
+------------------+
| Tables_in_szsxjd |
+------------------+
| info2            |
| infol            |
+------------------+
2 rows in set (0.00 sec)

mysql> drop table infol ;
Query OK, 0 rows affected (0.21 sec)

mysql> drop table info2;
Query OK, 0 rows affected (0.02 sec)

mysql> show tables;
Empty set (0.00 sec)

mysql> source /opt/sqldump/szsxjd.infol_info2.sql
Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.00 sec)
.....................

mysql> show tables;
+------------------+
| Tables_in_szsxjd |
+------------------+
| info2            |
| infol            |
+------------------+
2 rows in set (0.00 sec)

例2
# 创建备份
[root@master sqldump]# mysqldump -uroot -p123456 szsxjd infol > szsxjd.infol.sql

# 删除原库中的表
[root@master sqldump]# mysql -uroot -p123456 -e 'drop table szsxjd.infol;'

# 恢复表
[root@master sqldump]# mysqldump -uroot -p123456 szsxjd < szsxjd.infol.sql

# 查看表
[root@master sqldump]# mysql -uroot -p123456 -e 'show tables from szsxjd;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------------+
| Tables_in_szsxjd |
+------------------+
| infol            |
+------------------+


PS:mysqldump 严格来说属于温备份,会需要对表进行写入的锁定
在全量备份与恢复实验中,假设现有 szsxjd 库,szsxjd 库中有一个test表,需要注意的一点为:
① 当备份时加 --databases ,表示针对于szsxjd 库
#备份命令
mysqldump -uroot -p123456--databases szsxjd > /opt/szsxjd_01-all.sql 备份库后
#恢复命令过程为:
mysql -uroot -p123456
drop database szsxjd ;
exit
mysql -uroot -p123456 < /opt/szsxjd_01.sql
② 当备份时不加 --databases,表示针对szsxjd库下的所有表
#备份命令
mysqldump -uroot -p123456 szsxjd > /opt/szsxjd_all.sql
#恢复过程:
mysql -uroot -p123456
drop database szsxjd;
create database szsxjd;
exit
mysql -uroot -p123456 szsxjd < /opt/szsxjd_02.sql

#查看szsxjd_01.sql 和szsxjd_02.sql
主要原因在于两种方式的备份(前者会从"create databases"开始,而后者则全是针对表格进行操作)


4.在生产环境中,可以使用Shell脚本自动实现定时备份(时间频率需要确认)
0 1 * * 6 /usr/local/mysql/bin/mysqldump -uroot -p123456 szsxjd info1 > ./szsxjd_infol_$(date +%Y%m%d).sql ;/usr/local/mysql/bin/mysqladmin -u root -p flush-logs

6.2 MySQL****增量备份与恢复

6.2.1 MySQL****数据库增量恢复

① 一般恢复: 将所有备份的二进制日志内容全部恢复
② 基于位置恢复
数据库在某一时间点可能既有错误的操作也有正确的操作
可以基于精准的位置跳过错误的操作
发生错误节点之前的一个节点,上一次正确操作的位置点停止
③ 基于时间点恢复
跳过某个发生错误的时间点实现数据恢复
在错误时间点停止,在下一个正确时间点开始

6.2.2 MySQL****增量备份

① 增备实验
开启二进制日志功能

复制代码
vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin
binlog_format = MIXED #可选,指定二进制日志(binlog)的记录格式为MIXED(混合输入)
server-id = 1 #可加可不加该命令

#二进制日志(binlog)有3种不同的记录格式: STATEMENT (基于SQL语句)、ROW(基于行)、MIXED(混合模式),默认格式是STATEMENT

① STATEMENT(基于SQL语句):
每一条涉及到被修改的sql 都会记录在binlog中
缺点:日志量过大,如sleep()函数,last_insert_id()>,以及user-defined fuctions(udf)、主从复制等架构记录日志时会出现问题

总结:增删改查通过sql语句来实现记录,如果用高并发可能会出错,可能时间差异或者延迟,可能不是我们想想的恢复可能你先删除或者在修改,可能会倒过来。准确率底

② ROW(基于行)
只记录变动的记录,不记录sql的上下文环境
缺点:如果遇到update......set....where true 那么binlog的数据量会越来越大
总结:update、delete以多行数据起作用,来用行记录下来,只记录变动的记录,不记录sql的上下文环境,比如sql语句记录一行,但是ROW就可能记录10行,但是准确性高,高并发的时候由于操作量,性能变低,比较大所以记录都记下来,

③ MIXED 推荐使用
一般的语句使用statement,函数使用ROW方式存储。

systemctl restart mysqld
=====================================================================================================
mysql 增量备份 STATEMENT与ROW 通俗解释

在MySQL中,增量备份是指只备份发生变化的数据,而不是整个数据库。在增量备份中,可以使用基于语句(Statement)或基于行(Row)的方式来记录和复制这些变化。

基于语句的增量备份(Statement-Based Incremental Backup):
    通俗解释:就像记录每一步操作一样,基于语句的增量备份会记录每个SQL语句的变化,而不是具体的数据行。当备份时,只需要记录执行过的SQL语句,而不是具体的数据内容。
    适用场景:适用于简单的SQL语句操作,如INSERT、UPDATE、DELETE等,可以通过记录SQL语句来还原数据变化。

基于行的增量备份(Row-Based Incremental Backup):
    通俗解释:就像记录每个人的变化一样,基于行的增量备份会记录每个数据行的变化情况,而不是SQL语句。当备份时,只需要记录哪些数据行发生了变化,而不是具体的SQL语句。
    适用场景:适用于复杂的数据变化情况,如涉及多个表之间关联的操作,可以通过记录数据行的变化来还原数据。

    在增量备份中,选择基于语句或基于行的方式取决于您对数据变化的关注点和备份恢复的需求。基于语句的增量备份更注重SQL操作的记录,而基于行的增量备份更注重数据行的变化情况。根据具体情况选择合适的备份方式可以更有效地保护和恢复数据。
=====================================================================================================

查看二进制日志文件的内容
cp /usr/local/mysql/data/mysql-bin.000001 /opt/

① mysqlbinlog --no-defaults /opt/mysql-bin.000001

mysqlbinlog --no-defaults --base64-output=decode-rows -v /opt/mysql-bin.000001
#--base64-output=decode-rows:使用64位编码机制去解码(decode)并按行读取(rows)
#-v: 显示详细内容
#--no-defaults : 默认字符集(不加会报UTF-8的错误)
PS: 可以将解码后的文件导出为txt格式,方便查阅
mysqlbinlog --no-defaults --base64-output=decode-rows -v /opt/mysql-bin.000002 > /opt/mysql-bin.000002

例如,STATEMENT模式记录量较少,但有可能会因为没有记录下所有细节而产生问题;ROW模式可以记录下所有细节,但是记录量可能会非常大。所以在实际使用中需要根据情况选择适合的模式。

二进制日志中需要关注的部分
· at :开始的位置点
**·**end_log_pos:结束的位置
· 时间戳: 210712 11:50:30
· SQL语句
② 进行完全备份(增量备份时基于完全备份的,所以我们直接完全备份数据库)

复制代码
[root@master sqldump]# mysqldump -uroot -p123456 szsxjd infol > szsxjd.infol_$(date +%F).sql

[root@master sqldump]# mysqldump -uroot -p123456 szsxjd > szsxjd_all_$(date +%F).sql

③ 可每天进行增量备份操作,生成新的二进制日志文件(例如:mysql-bin.000003)

复制代码
mysqladmin -u root -p flush-logs


④ 插入新数据,以模拟数据的增加或变更
PS:在第一次完全备份之后刷新二进制文件,在第二个二进制文件中记载着"增量备份的数据"

复制代码
mysql> create database zxzx;
Query OK, 1 row affected (0.01 sec)

mysql> use zxzx;
Database changed
mysql> create table file1 (id int(4), name char(10));
Query OK, 0 rows affected (0.02 sec)

mysql> insert into file1 values(1, 'AAA');
Query OK, 1 row affected (0.01 sec)

mysql> insert into file1 values(2, 'ZZZ');
Query OK, 1 row affected (0.00 sec)

mysql> select * from file1;
+------+------+
| id   | name |
+------+------+
|    1 | AAA  |
|    2 | ZZZ  |
+------+------+
2 rows in set (0.00 sec)

⑤ 再次生成新的二进制日志文件(例如:mysql-bin.000004)

复制代码
mysqladmin -u root -p flush-logs
#之前的步骤4的数据库操作会保存到mysql-bin.000003文件中,之后我们测试删除szsxjd库的操作会保存
在mysql-bin.000004文件中 (以免当我们基于mysql-bin.000003日志进行恢复时,依然会删除库)

6.2.3 MySQL****增量恢复

**1.**一般恢复

复制代码
(1)、模拟丢失更改的数据的恢复步骤(直接使用恢复即可)
① 备份yjs0805库中test1表
mysqldump -uroot -p123456 zxzx file1 > /opt/sqldump/zxzx_file1.sql
② 删除yjs0805库中test1表
drop table zxzx.file1;
③ 恢复test1表
mysql -uroot -p zxzx < /opt/sqldump/zxzx_file1.sql

mysql> select * from file1;
+------+------+
| id   | name |
+------+------+
|    1 | AAA  |
|    2 | ZZZ  |
+------+------+
2 rows in set (0.00 sec)

#查看日志文件
[root@mysql data]# mysqlbinlog --no-defaults --base64-output=decode-rows -v mysql-bin.000003

(2)、模拟丢失所有数据的恢复步骤
① 模拟丢失所有数据
[root@master sqldump]# mysqldump -uroot -p123456
mysql> drop database zxzx;
Query OK, 1 row affected (0.03 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| ceshi              |
| mysql              |
| performance_schema |
| sys                |
| szsxjd             |
+--------------------+
6 rows in set (0.00 sec)
mysql>exit

② 基于mysql-bin.000003恢复
[root@master sqldump]# cp /usr/local/mysql/data/master-bin.000003 /opt/sqldump/mysql-bin.000003
[root@master sqldump]# mysqlbinlog --no-defaults /opt/sqldump/mysql-bin.000003 |mysql -uroot -p
[root@master sqldump]# mysqldump -uroot -p123456
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| ceshi              |
| mysql              |
| performance_schema |
| sys                |
| szsxjd             |
| zxzx               |
+--------------------+
7 rows in set (0.00 sec)

mysql> use zxzx;
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
mysql> show tables;
+----------------+
| Tables_in_zxzx |
+----------------+
| file1          |
+----------------+
1 row in set (0.00 sec)

mysql> select * from file1;
+------+------+
| id   | name |
+------+------+
|    1 | AAA  |
|    2 | ZZZ  |
+------+------+
2 rows in set (0.00 sec)

**2.**断点恢复

复制代码
mysqlbinlog --no-defaults --base64-output=decode-rows -v /opt/mysql-bin.000002

(1)、基于位置恢复
① 插入三条数据
mysql> use zxzx;
Database changed
mysql> select * from file1;
+------+------+
| id   | name |
+------+------+
|    1 | AAA  |
|    2 | ZZZ  |
+------+------+
2 rows in set (0.00 sec)

mysql> insert into file1 values(3,'AZX');
Query OK, 1 row affected (0.00 sec)

mysql> insert into file1 values(4,'QQQ');
Query OK, 1 row affected (0.00 sec)

mysql> insert into file1 values(5,'WWW');
Query OK, 1 row affected (0.01 sec)

mysql> select * from file1;
+------+------+
| id   | name |
+------+------+
|    1 | AAA  |
|    2 | ZZZ  |
|    3 | AZX  |
|    4 | Q    |
|    5 | W    |
+------+------+
5 rows in set (0.00 sec)

# 需求:以上id=4 的数据操作失误,需要跳过
② 确认位置点,刷新二进制日志并删除test1表
#刷新日志
mysqladmin -uroot -p123456 flush-logs

# 删除file1 表
mysql> drop table file1;

# 查看二进制日志找到对应内容
mysqlbinlog --no-defaults --base64-output=decode-rows -v /opt/mysql-bin.000004
==========================================================================================================
# at 1673
#251204 22:32:05 server id 1  end_log_pos 1780 CRC32 0x217961b2 	Query	thread_id=24	exec_time=0	error_code=0
SET TIMESTAMP=1764858725/*!*/;
insert into file1 values(3,'AZX')
/*!*/;
# at 1780
#251204 22:32:05 server id 1  end_log_pos 1811 CRC32 0x1191bce9 	Xid = 901
COMMIT/*!*/;
# at 1811
#251204 22:32:16 server id 1  end_log_pos 1876 CRC32 0x29c5d14d 	Anonymous_GTID	last_committed=8	sequence_number=9
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 1876
#251204 22:32:16 server id 1  end_log_pos 1955 CRC32 0xf55fd3eb 	Query	thread_id=24	exec_time=0	error_code=0
SET TIMESTAMP=1764858736/*!*/;
BEGIN
/*!*/;
# at 1955
#251204 22:32:16 server id 1  end_log_pos 2062 CRC32 0x8593b9ef 	Query	thread_id=24	exec_time=0	error_code=0
SET TIMESTAMP=1764858736/*!*/;
insert into file1 values(4,'Q')
/*!*/;
# at 2062
#251204 22:32:16 server id 1  end_log_pos 2093 CRC32 0x899aa45a 	Xid = 902
COMMIT/*!*/;
# at 2093
#251204 22:32:25 server id 1  end_log_pos 2158 CRC32 0xefcbf475 	Anonymous_GTID	last_committed=9	sequence_number=10
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 2158
#251204 22:32:25 server id 1  end_log_pos 2237 CRC32 0x7cfbca36 	Query	thread_id=24	exec_time=0	error_code=0
SET TIMESTAMP=1764858745/*!*/;
BEGIN
/*!*/;
# at 2237
#251204 22:32:25 server id 1  end_log_pos 2344 CRC32 0xe6a04dd4 	Query	thread_id=24	exec_time=0	error_code=0
SET TIMESTAMP=1764858745/*!*/;
insert into file1 values(5,'W')
/*!*/;
=====================================================================================================================

# ③ 基于位置点恢复
#仅恢复到操作 ID 为"1955"之前的数据,即不恢复"4"的数据
[root@master sqldump]# mysqlbinlog --no-defaults --stop-position='1955' /opt/sqldump/mysql-bin.000004 | mysql -u root -p

mysql> select * from file1;
+------+------+
| id   | name |
+------+------+
|    1 | AAA  |
|    2 | ZZZ  |
|    3 | AZX  |
+------+------+
3 rows in set (0.00 sec)

# 仅恢复"5"的数据,跳过"4"的数据恢复
[root@master sqldump]# mysqlbinlog --no-defaults --start-position='2237' /opt/sqldump/mysql-bin.000004 | mysql -u root -p

mysql> select * from file1;
+------+------+
| id   | name |
+------+------+
|    1 | AAA  |
|    2 | ZZZ  |
|    3 | AZX  |
|    5 | WWW  |
+------+------+
4 rows in set (0.00 sec)

# 恢复4 的数据
mysqlbinlog --no-defaults --start-position='1955' --stop-position='2237' /opt/sqldump/mysql-bin.000004 | mysql -uroot -p #恢复从位置为1955开始到位置为2237为止

mysql> select * from file1;
+------+------+
| id   | name |
+------+------+
|    1 | AAA  |
|    2 | ZZZ  |
|    3 | AZX  |
|    5 | WWW  |
|    4 | QQQ  |
+------+------+
5 rows in set (0.00 sec)

(2)、基于时间点恢复
mysqlbinlog [--no-defaults] --start-datetime='年-月-日 小时:分钟:秒' --stopdatetime='年-月-日小时:分钟:秒' 二进制日志 | mysql -u 用户名 -p 密码

#仅恢复到16:41:24 之前的数据,即不恢复"user4"的数据
mysqlbinlog --no-defaults --stop-datetime='25-12-04 22:32:16' /opt/sqldump/mysql-bin.000004 | mysql -uroot -p

# 恢复数据5及之后的数据
mysqlbinlog --no-defaults --start-datetime='25-12-04 22:32:25' /opt/sqldump/mysql-bin.000004 | mysql -uroot -p

# 恢复数据4
mysqlbinlog --no-defaults --start-datetime='25-12-04 22:32:16' --stop-datetime='25-12-04 22:32:25' /opt/sqldump/mysql-bin.000004 | mysql -uroot -p

如果恢复某条SQL语之前的所有数据,就stop在这个语句的位置节点或者时间点
如果恢复某条SQL语句以及之后的所有数据,就从这个语句的位置节点或者时间点start

七、mysql备份与恢复总结

7.1**、物理备份、逻辑备份**

**7.1.1物理备份:**冷备、温备、热备

1)冷备: tar,需要关闭mysql服务,或者确保mysql服务在进行tar备份时,没有客户端的写入操作
2)温备: mysqldump,这个是mysql自带的备份工具,特性,逐表备份,每备份一张表时,会先drop 删除,然后重新create 创建表结构,然后再锁表(仅锁定写的操作,但可读),进行insert语句的备份,备份完成后,进行unlock解锁,然后继续备份下一个
3)热备: xtrabackup mysqlhotcopy等热备工具(第三方),在mysql正常运行时,进行备份.

7.1.2逻辑备份:

1)全量备份: tar、 mysqldump -u -p --all-databases
2)增量备份:主要使用bin-log 二进制日志来完成备份,同时每个增量备份的文件,可以通 过:mysqladmin -u -p flush-logs来刷新生成新的增备的日志文件,同时可以结合crontab完成自动刷新
PS:再进行基于二进制文件的增备恢复时,有必要的话,需要先恢复完备的数据,再逐个恢复增备的数据,直到恢复至我们需要恢复的数据为止
3)差异备份:需要选择保存日志的格式为ROW(基于行)的备份方式日志保存的类型:
混合模式Mixed(建议使用) 两者结合,既能保证一致性,又尽量提高性能
基于行ROWS 最精确,保证一致性,但速度慢。
基于sql (默认) 速度快,但可能会导致数据不一致

7.2 mysql恢复的方式:

  1. 基于冷备(tar)形式: tar zxvf解压打包的/usr/local/mysql/data数据下的内容
    2)基于自带的温备工具:使用mysgldump进行备份后,可使用两种方式进行恢复
    ① : mysql -u -p 库名< /opt/mysql_all.sql(备份文件的路径)
    ② mysql -u -p -e 'source /opt/mysql_all.sql'直接使用source进行恢复
    3)基于日志: bin-log,首先开启二进制日志的配置log-bin=mysql-bin log_format=MiXED,
    然后在/usr/local/mysql/data MysQL工作目录下,会生成mysql-bin.00000x的二进制日志文件
    接着使用mysqlbinlog --no-defaults 二进制日志路径│ mysql -u -p 基于完整的二进制日志文件进行恢复
    基于位置点和时间点进行恢复:使用mysqlbinlog --no-defaults --base64-output=decode-rows -v二进制日志文件路径,查看正确操作和需要跳过的错误操作的at (position位置点)和datetime(时间点)来进行恢复
相关推荐
不穿格子的程序员41 分钟前
MySQL篇5:MySQL深度揭秘——MySQL 执行计划分析与 SQL 优化最佳实践
sql·mysql·sql优化
友友马42 分钟前
『MySQL - 进阶』存储过程(上):核心概念、变量体系与流程控制
android·数据库·mysql
网安老伯43 分钟前
计算机网络:网络安全(网络安全概述)
开发语言·数据库·python·计算机网络·web安全·网络安全·php
zhougl99643 分钟前
学习-深入学习SQL语句
数据库·sql·学习
TDengine (老段)43 分钟前
工业大数据平台 TDengine IDMP 让数据计算变得简单智能
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
('-')43 分钟前
《从根上理解MySQL是怎样运行的》第二十三章笔记
数据库·笔记·mysql
Mr.徐大人ゞ44 分钟前
13.MHA 常用问题
mysql
LSL666_44 分钟前
云服务器安装MySQL
运维·服务器·mysql
卿雪1 小时前
MySQL【数据类型】:CHAR 和 VARCHAR 的对比、VATCHAR(n) 和 INT(n) 里的 n 一样吗?
android·java·数据库·python·mysql·adb·golang