mysql主从架构、备份与恢复

主从复制原理

  1. 数据库有个bin-log二进制文件,记录了所有sql语句。
  2. 我们的目标就是把主数据库的bin-log文件的sql语句复制过来。
  3. 让其在从数据的relay-log重做日志文件中再执行一次这些sql语句即可。
  4. 下面的主从配置就是围绕这个原理配置
  5. 具体需要三个线程来操作:
    1. binlog输出线程:每当有从库连接到主库的时候,主库都会创建一个线程然后发送binlog内容到从库。在从库里,当复制开始的时候,从库就会创建两个线程进行处理:
    2. 从库I/O线程:当START SLAVE语句在从库开始执行之后,从库创建一个I/O线程,该线程连接到主库并请求主库发送binlog里面的更新记录到从库上。从库I/O线程读取主库的binlog输出线程发送的更新并拷贝这些更新到本地文件,其中包括relay log文件。
    3. 从库的SQL线程:从库创建一个SQL线程,这个线程读取从库I/O线程写到relay log的更新事件并执行。

可以知道,对于每一个主从复制的连接,都有三个线程。拥有多个从库的主库为每一个连接到主库的从库创建一个binlog输出线程,每一个从库都有它自己的I/O线程和SQL线程。

image
image

步骤一:主库db的更新事件(update、insert、delete)被写到binlog

步骤二:从库发起连接,连接到主库

步骤三:此时主库创建一个binlog dump thread线程,把binlog的内容发送到从库

步骤四:从库启动之后,创建一个I/O线程,读取主库传过来的binlog内容并写入到relay log.

步骤五:还会创建一个SQL线程,从relay log里面读取内容,从Exec_Master_Log_Pos位置开始执行读取到的更新事件,将更新内容写入到slave的db.

异步复制

在异步复制中,主库执行完操作后,写入binlog日志后,就返回客户端,这一动作就结束了,并不会验证从库有没有收到,完不完整,所以这样可能会造成数据的不一致。

说到底,复制过程中数据是否一致,主要取决于Binlog日志的安全性与完整性

在MySQL中,有sync_binlog=n这一参数,他的值表示每进行n次事务提交,MySQL就将Binlog刷新到磁盘。如果这个值为1,就代表每提交一次事务(SQL),就将Binlog往磁盘刷新一次,这样一来,就算数据库宕机了,那么最多只能损失一次事务的数据。

但是,一旦多个事务并发提交时,由于受sync_binlog的限制,MySQL只能按顺序来处理这些请求,另外,高频率的刷新binlog对IO的影响也很大,进一步影响了数据库的性能,所以,一般这个值都设为0或者其他值,在数据的安全性和高并发下的性能之间取得一个平衡。

为了更加有效的保护Binlog的安全性和完整性,MySQL5 .5之后引入了半同步复制

全同步

  1. 逻辑上

指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。

  1. 技术上

当主库提交事务之后,所有的从库节点必须收到、APPLY并且提交这些事务,然后主库线程才能继续做后续操作。但缺点是,主库完成一个事务的时间会被拉长,性能降低。

  1. 原理图
image

半同步

master将每个事务写入binlog(sync_binlog=1),传递到slave刷新到磁盘(sync_relay=1),同时主库提交事务(commit)。master等待slave反馈收到relay log,只有收到ACK后master才将commit OK结果反馈给客户端。

image

传统半同步

异步复制中主库和从库的数据之间难免会存在一定的延迟,这样会有出现一种情况:当在主库上写入一个事务并提交成功,而从库尚未得到主库的binlog日志(为什么没有得到?),主库由于各种原因宕机,导致主库上该事务binlog丢失,此时从库(这是会提升为主库)就会损失这个事务,从而造成主从不一致(修复后的主库会变成从库),因此为了解决这个问题,从Mysql5.5开始,就开始引入半同步复制,半同步为了保证主库上每一个binlog事务都能够被可靠的复制到从库上,主库在每次事务成功提交后,并不及时反馈给前端应用用户,而是等待至少一个从库(rpl_semi_sync_master_wait_for_slave_count)也能接受到binlog事务成功写入中继日志,主库才返回Commit操作给客户端。

也就是说半同步复制保证事务成功提交后,至少有两份日志记录,一份在主库的binlog日志上,另一份在至少一个从库的中继日志relay_log上,从而更进一步保证了数据的完整性。

在传统的半同步复制中,主库写数据到binlog,且执行commit操作后,会一直等待从库的ACK,即从库写入relay log 后,并将数据落盘,返回给主库消息,通知主库可以返回前端

应用操作成功。但是这样会出现一个问题,就是实际上主库已经将该事务Commit到了事务引擎层,应用已经可以看到数据发生了变化,只是等待返回而已,如果此时主库宕机,

有可能从库还没能写入relay log ,就会发生主从库不一致的情况,

后果:

  1. 至少有一个从库收到binlog再返回
  2. 减少数据丢失风险
  3. 不能完全避免数据丢失

增强版半同步

增强型半同步是对半同步做了微调,即主库写数据到binlog后,就开始等待从库的应答,直到至少一个从库写入relay log 后,并将数据落盘,然后返回给主库消息,

通过主库可以执行commit操作,然后主库开始提交到事务引擎层,应用此时可以看到数据发生了变化。

image

后果:

  1. 二进制日志先写远程
  2. 可保证数据完全不丢失
  3. mysql5.7版本开始支持

半同步复制搭建需要安装插件:

#加载插件
#主:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
#从:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
#查看是否加载成功:
show plugins;
#启动:
#主:
SET GLOBAL rpl_semi_sync_master_enabled = 1;
#从:
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
#重启从库上的IO线程
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;
#查看是否在运行
#主:
show status like 'Rpl_semi_sync_master_status';
##从:
show status like 'Rpl_semi_sync_slave_status';

总结

总之,mysql主从模式默认是异步复制的,而MySQL Cluster是同步复制的,只要设置为相应的模式即是在使用相应的同步策略。

从MySQL5.5开始,MySQL以插件的形式支持半同步复制。其实说明半同步复制是更好的方式,兼顾了同步和性能的问题。

GTID模式

暂时没写

并行复制

MySQL 5.6并行复制架构

诚然,MySQL 5.6版本也支持所谓的并行复制,但是其并行只是基于schema的,也就是基于库的。如果用户的MySQL数据库实例中存在多个schema,对于从机复制的速度的确可以有比较大的帮助。MySQL 5.6并行复制的架构如下所示:

image

在上图的红色框框部分就是实现并行复制的关键所在。在MySQL 5.6版本之前,Slave服务器上有两个线程I/O线程和SQL线程。I/O线程负责接收二进制日志(更准确的说是二进制日志的event),SQL线程进行回放二进制日志。如果在MySQL 5.6版本开启并行复制功能,那么SQL线程就变为了coordinator线程,coordinator线程主要负责以前两部分的内容:

  • 若判断可以并行执行,那么选择worker线程执行事务的二进制日志

  • 若判断不可以并行执行,如该操作是DDL,亦或者是事务跨schema操作,则等待所有的worker线程执行完成之后,再执行当前的日志

这意味着coordinator线程并不是仅将日志发送给worker线程,自己也可以回放日志,但是所有可以并行的操作交付由worker线程完成。coordinator线程与worker是典型的生产者与消费者模型。

上述机制实现了基于schema的并行复制存在两个问题,首先是crash safe功能不好做,因为可能之后执行的事务由于并行复制的关系先完成执行,那么当发生crash的时候,这部分的处理逻辑是比较复杂的。从代码上看,5.6这里引入了Low-Water-Mark标记来解决该问题,从设计上看(WL#5569),其是希望借助于日志的幂等性来解决该问题,不过5.6的二进制日志回放还不能实现幂等性。另一个最为关键的问题是这样设计的并行复制效果并不高,如果用户实例仅有一个库,那么就无法实现并行回放,甚至性能会比原来的单线程更差。而单库多表是比多库多表更为常见的一种情形。

MySQL 5.7并行复制原理

MySQL 5.7才可称为真正的并行复制,这其中最为主要的原因就是slave服务器的回放与主机是一致的即master服务器上是怎么并行执行的slave上就怎样进行并行回放。不再有库的并行复制限制,对于二进制日志格式也无特殊的要求(基于库的并行复制也没有要求)。

从MySQL官方来看,其并行复制的原本计划是支持表级的并行复制和行级的并行复制,行级的并行复制通过解析ROW格式的二进制日志的方式来完成,WL#4648。但是最终出现给小伙伴的确是在开发计划中称为:MTS: Prepared transactions slave parallel applier,可见:WL#6314。该并行复制的思想最早是由MariaDB的Kristain提出,并已在MariaDB 10中出现,相信很多选择MariaDB的小伙伴最为看重的功能之一就是并行复制。

MySQL 5.7并行复制的思想简单易懂,一言以蔽之:一个组提交的事务都是可以并行回放,因为这些事务都已进入到事务的prepare阶段,则说明事务之间没有任何冲突(否则就不可能提交)。

为了兼容MySQL 5.6基于库的并行复制,5.7引入了新的变量slave-parallel-type,其可以配置的值有:

  • DATABASE:默认值,基于库的并行复制方式

  • LOGICAL_CLOCK:基于组提交的并行复制方式

支持并行复制的GTID

如何知道事务是否在一组中,又是一个问题,因为原版的MySQL并没有提供这样的信息。在MySQL 5.7版本中,其设计方式是将组提交的信息存放在GTID中。那么如果用户没有开启GTID功能,即将参数gtid_mode设置为OFF呢?故MySQL 5.7又引入了称之为Anonymous_Gtid的二进制日志event类型,如:

mysql> SHOW BINLOG EVENTS in 'mysql-bin.000006';
+------------------+-----+----------------+-----------+-------------+-----------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+----------------+-----------+-------------+-----------------------------------------------+
| mysql-bin.000006 | 4 | Format_desc | 88 | 123 | Server ver: 5.7.7-rc-debug-log, Binlog ver: 4 |
| mysql-bin.000006 | 123 | Previous_gtids | 88 | 194 | f11232f7-ff07-11e4-8fbb-00ff55e152c6:1-2 |
| mysql-bin.000006 | 194 | Anonymous_Gtid | 88 | 259 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000006 | 259 | Query | 88 | 330 | BEGIN |
| mysql-bin.000006 | 330 | Table_map | 88 | 373 | table_id: 108 (aaa.t) |
| mysql-bin.000006 | 373 | Write_rows | 88 | 413 | table_id: 108 flags: STMT_END_F |
......

这意味着在MySQL 5.7版本中即使不开启GTID,每个事务开始前也是会存在一个Anonymous_Gtid,而这GTID中就存在着组提交的信息。

LOGICAL_CLOCK

然而,通过上述的SHOW BINLOG EVENTS,我们并没有发现有关组提交的任何信息。但是通过mysqlbinlog工具,用户就能发现组提交的内部信息:

root@localhost:~# mysqlbinlog mysql-bin.0000006 | grep last_committed
#150520 14:23:11 server id 88 end_log_pos 259 CRC32 0x4ead9ad6 GTID last_committed=0 sequence_number=1
#150520 14:23:11 server id 88 end_log_pos 1483 CRC32 0xdf94bc85 GTID last_committed=0 sequence_number=2
#150520 14:23:11 server id 88 end_log_pos 2708 CRC32 0x0914697b GTID last_committed=0 sequence_number=3
#150520 14:23:11 server id 88 end_log_pos 3934 CRC32 0xd9cb4a43 GTID last_committed=0 sequence_number=4
#150520 14:23:11 server id 88 end_log_pos 5159 CRC32 0x06a6f531 GTID last_committed=0 sequence_number=5
#150520 14:23:11 server id 88 end_log_pos 6386 CRC32 0xd6cae930 GTID last_committed=0 sequence_number=6
#150520 14:23:11 server id 88 end_log_pos 7610 CRC32 0xa1ea531c GTID last_committed=6 sequence_number=7
#150520 14:23:11 server id 88 end_log_pos 8834 CRC32 0x96864e6b GTID last_committed=6 sequence_number=8
#150520 14:23:11 server id 88 end_log_pos 10057 CRC32 0x2de1ae55 GTID last_committed=6 sequence_number=9
#150520 14:23:11 server id 88 end_log_pos 11280 CRC32 0x5eb13091 GTID last_committed=6 sequence_number=10
#150520 14:23:11 server id 88 end_log_pos 12504 CRC32 0x16721011 GTID last_committed=6 sequence_number=11
#150520 14:23:11 server id 88 end_log_pos 13727 CRC32 0xe2210ab6 GTID last_committed=6 sequence_number=12
#150520 14:23:11 server id 88 end_log_pos 14952 CRC32 0xf41181d3 GTID last_committed=12 sequence_number=13
...

可以发现较之原来的二进制日志内容多了last_committed和sequence_number,last_committed表示事务提交的时候,上次事务提交的编号,如果事务具有相同的last_committed,表示这些事务都在一组内,可以进行并行的回放。例如上述last_committed为0的事务有6个,表示组提交时提交了6个事务,而这6个事务在从机是可以进行并行回放的。

上述的last_committed和sequence_number代表的就是所谓的LOGICAL_CLOCK。先来看源码中对于LOGICAL_CLOCK的定义:

class Logical_clock
{
  private:
  int64 state;
  /*
  Offset is subtracted from the actual "absolute time" value at
  logging a replication event. That is the event holds logical
  timestamps in the "relative" format. They are meaningful only in
  the context of the current binlog.
  The member is updated (incremented) per binary log rotation.
  */
  int64 offset;
  ......

state是一个自增的值,offset在每次二进制日志发生rotate时更新,记录发生rotate时的state值。其实state和offset记录的是全局的计数值,而存在二进制日志中的仅是当前文件的相对值。使用LOGICAL_CLOCK的场景如下:

class MYSQL_BIN_LOG: public TC_LOG
{
  ...
  public:
  /* Committed transactions timestamp */
  Logical_clock max_committed_transaction;
  /* "Prepared" transactions timestamp */
  Logical_clock transaction_counter;
  ...

可以看到在类MYSQL_BIN_LOG中定义了两个Logical_clock的变量:

  • max_c ommitted_transaction:记录上次组提交时的logical_clock,代表上述mysqlbinlog中的last_committed

  • transaction_counter:记录当前组提交中各事务的logcial_clock,代表上述mysqlbinlog中的sequence_number

PXC高可用

暂时没写

备份及恢复

mysql备份概述

  1. 为什么要备份
  • 能够防止由于机械故障以及人为误操作带来的数据丢失,例如将数据库文件保存在其他地方。
  • 冗余:数据有多份冗余,但不等备份,只能防止机械故障还来的数据丢失,例如主备模式,数据库集群。
  1. 备份必须重试的内容
  • 备份内容 databases binlog my.cnf
  • 所有备份数据都应该放在非数据库本地,而且建议有多副本。
  • 测试环境中做日常恢复演练,恢复较备份更为重要
  1. 备份过程中必须考虑的因素
  • 数据一致性
  • 服务的可用性

备份类型

物理备份

对数据库操作系统的物理文件(如数据文件、日志文件等)的备份。物理备份又可分为脱机备份(冷备份)和联机备份(热备份)。这种类型的备份适用于出现问题需要快速恢复大型重要数据库。

  1. 热备(hot backup)
  • 在线备份,数据库处于运行状态,这种备份方法依赖于数据库的日志文件
  • 对应用基本无影响(应用程序读写不会阻塞,DansGuardian性能还是会有所下降,所以尽量不要在主上做备份,在从库做)
  1. 冷备
  • 备份数据文件需要停机,是在关闭数据库的时候进行的
  • 备份datadir目录下的所有文件
  1. 温备
  • 针对myisam的备份(myisam不支持热备),备份时候实例只读不可写,数据库锁定表格(不可写入但可读)的状态下进行的
  • 对应用影响很大
  • 通常加一个读锁

逻辑备份

对数据逻辑组件(如表等数据库对象)的备份,表示为逻辑数据库结构(create databases、create table)等语句和内容(insert语句或分割文本文件)的信息。这种类型的备份适用于可以编辑数据值或表结构较小的数据量,或者在不同机器体系结构上重新创建数据。

物理备份和逻辑备份的区别


|

|

逻辑备份

|

物理备份

|
|

备份方式

|

备份数据库逻辑内容

|

备份数据库物理文件

|
|

优点

|

备份文件相对较小,只备份表中的数据结构

|

恢复速度比较快(物理文件恢复基本已经完成恢复)

|
|

缺点

|

恢复速度较慢(需要重新建立索引,存储过程)

|

备份文件相对比较大(备份表空间,包含数据与索引,碎片)

|
|

对业务影响

|

缓冲池污染(把所有数据读一遍,读到内存中),I/O负载加大

|

I/O负载加大

|
|

代表工具

|

mysqldump

|

xtrabackup、ibbackup、mysqlbackup

|

备份方式选择

  • 从一下几个维度考虑备份方式
    • 备份速度
    • 恢复速度
    • 备份大小
    • 对业务影响

MySQL 备份策略

完全备份

每次对数据进行完整的备份,完全备份是增量备份的基础,完全备份保存的是备份完成时刻的数据库。

  • 优点:
    • 备份与恢复操作简单方便.
  • 缺点:
    • 数据存在大量的重复;占用大量的空间;备份与恢复时间长。

差异备份

备份那些自从上次完全备份之后被修改过的文件。

  • 优点:

    • 相比完全备份,降低了冗余数据,提高了空间利用率,安全性差于完全备份
  • 缺点

    • 仍旧存在冗余数据存在

增量备份

只有那些在上次完全备份或者增量备份后被修改的文件才会被备份

增量备份就是备份自上一次备份之后增加或变化的文件或者内容

  • 优点:

    • 没有冗余数据,效率最高,空间利用率最大化
  • 缺点

    • 安全性降低了

总结

image

mysql备份还原之xtrabackup

暂时没写

mysql备份还原之mysqldump

  • mysqldump 是 MySQL 自带的逻辑备份工具。可以保证数据的一致性和服务的可用性。
  • 它的备份原理是通过协议连接到 MySQL 数据库,将需要备份的数据查询出来,将查询出的数据转 换成对应的 insert 语句,当我们需要还原这些数据时,只要执行这些 insert 语句,即可将对应的 数据还原

备份命令

  1. 命令格式
mysqldump [选项] 数据库名 [表名] > 脚本名 
mysqldump [选项] --数据库名 [选项 表名] > 脚本名 
mysqldump [选项] --all-databases [选项] > 脚本名 

  1. 选项说明


|

参数名

|

缩写

|

含义

|
|

--host

|

-h

|

服务器IP地址

|
|

--port

|

-P

|

服务器端口号

|
|

--user

|

-u

|

mysql用户名

|
|

--password

|

-p

|

mysql密码

|
|

--databases

|

-B

|

指定要备份的数据库

|
|

--all-databases

|

-A

|

备份mysql服务器上的所有数据库

|
|

--compact

| |

压缩模式,产生更少的输出

|
|

--comments

| |

添加注释信息

|
|

--complete-insert

| |

输出完成的插入语句

|
|

--lock-tables

| |

备份前,锁定所有数据库表

|
|

--no-create-db/--no-create-info

| |

禁止生产创建数据库语句

|
|

--force

| |

当出现错误时仍然继续备份操作

|
|

--default-character-set

| |

指定默认字符集

|
|

--add-locks

| |

备份数据表时锁定数据库表

|
|

-single-transaction

| |

保证数据的一致性和服务可用性

|
|

--master-data=12

| |

通常等于1,记录binlog日志位置与文件名,追加至备份文件中

|
|

--flush-log

|

-F

|

备份之前刷新日志

|
|

--events

|

-E

|

备份事件调度器代码

|
|

--triggers

|

-T

|

备份触发器

|
|

--routines

|

-R

|

备份存储过程和存储函数

|

备份实例

备份所有数据库:

 mysqldump -uroot -p --all-databases > /backup/mysqldump/all.db 

备份指定数据库:

 mysqldump -uroot -p test > /backup/mysqldump/test.db 

备份指定数据库指定表(多个表以空格间隔)

 mysqldump -uroot -p mysql db event > /backup/mysqldump/2table.db 

备份指定数据库排除某些表

 mysqldump -uroot -p test --ignore-table=test.t1 --ignore-table=test.t2 > /backup/mysqldump/test2.db

还原命令

  1. 系统运行命令
mysqladmin -uroot -p create db_name 
mysql -uroot -p db_name < /backup/mysqldump/db_name.db 

  • 在导入备份数据库前,db_name如果没有,是需要创建的; 而且与db_name.db中数据库名是一 样的才可以导入。
  1. soure方法
use db_name 
source /backup/mysqldump/db_name.db

mysql恢复(二进制日志)

mysql二进制日志配置

  1. 修改配置文件
vim /etc/my.cnf
[mysqld]
server_id=1
log_bin=/var/lib/mysql/mysql-bin

  • 配置说明
    • server_id 是5.7之后开二进制日志必加的参数
    • log_bin= 打开二进制功能 /var/lib/mysql/mysql-bin 指定存放路径
    • mysql-bin 文件名前缀
  1. 重启数据库
systemctl restart mysqld

  1. 查看binlog是否开启
show variables like "%log_bin%";
+---------------------------------+--------------------------------+
| Variable_name                   | Value                          |
+---------------------------------+--------------------------------+
| log_bin                         | ON                             |
| log_bin_basename                | /var/lib/mysql/mysql-bin       |
| log_bin_index                   | /var/lib/mysql/mysql-bin.index |
| log_bin_trust_function_creators | OFF                            |
| log_bin_use_v1_row_events       | OFF                            |
| sql_log_bin                     | ON                             |
+---------------------------------+--------------------------------+
6 rows in set (0.00 sec)

  • 字段说明
    • log_bin 开启二进制日志的开关
    • log_bin_basename 位置
    • sql_log_bin 临时开启或关闭二进制日志的小开关

二进制日志工作模式

  1. 修改配置文件
vim /etc/my.cnf
[mysqld]
binlog_format='ROW'

  1. 重启数据库
systemctl restart mysqld

  1. 查看二进制日志工作模式
show variables like "%binlog%";
+--------------------------------------------+----------------------+
| Variable_name                              | Value                |
+--------------------------------------------+----------------------+
| binlog_cache_size                          | 32768                |
| binlog_checksum                            | CRC32                |
| binlog_direct_non_transactional_updates    | OFF                  |
| binlog_error_action                        | ABORT_SERVER         |
| binlog_format                              | ROW                  |
| binlog_group_commit_sync_delay             | 0                    |
| binlog_group_commit_sync_no_delay_count    | 0                    |
| binlog_gtid_simple_recovery                | ON                   |
| binlog_max_flush_queue_time                | 0                    |
| binlog_order_commits                       | ON                   |
| binlog_row_image                           | FULL                 |
| binlog_rows_query_log_events               | OFF                  |
| binlog_stmt_cache_size                     | 32768                |
| binlog_transaction_dependency_history_size | 25000                |
| binlog_transaction_dependency_tracking     | COMMIT_ORDER         |
| innodb_api_enable_binlog                   | OFF                  |
| innodb_locks_unsafe_for_binlog             | OFF                  |
| log_statements_unsafe_for_binlog           | ON                   |
| max_binlog_cache_size                      | 18446744073709547520 |
| max_binlog_size                            | 1073741824           |
| max_binlog_stmt_cache_size                 | 18446744073709547520 |
| sync_binlog                                | 1                    |
+--------------------------------------------+----------------------+
22 rows in set (0.01 sec)

查看二进制日志基本信息

  1. 打印出当前MySQL的所有二进制日志,并且显示最后使用到的 position
show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       177 |
| mysql-bin.000002 |       177 |
| mysql-bin.000003 |      1439 |
+------------------+-----------+
3 rows in set (0.00 sec)

  1. 查看当前正在使用的二进制日志
show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |     1439 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec) 

  1. 查看二进制日志的事件信息
show binlog events in 'mysql-bin.000003';
+------------------+------+----------------+-----------+-------------+-----------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+------+----------------+-----------+-------------+-----------------------------------------------------------------+
| mysql-bin.000003 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.35-log, Binlog ver: 4 |
| mysql-bin.000003 | 123 | Previous_gtids | 1 | 154 | |
| mysql-bin.000003 | 154 | Anonymous_Gtid | 1 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 219 | Query | 1 | 307 | create database dd |
| mysql-bin.000003 | 307 | Anonymous_Gtid | 1 | 372 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 372 | Query | 1 | 495 | use dd; create table t1(id int) engine=innodb charset=utf8mb4 |
| mysql-bin.000003 | 495 | Anonymous_Gtid | 1 | 560 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 560 | Query | 1 | 630 | BEGIN |
| mysql-bin.000003 | 630 | Table_map | 1 | 673 | table_id: 108 (dd.t1) |
| mysql-bin.000003 | 673 | Write_rows | 1 | 723 | table_id: 108 flags: STMT_END_F |
| mysql-bin.000003 | 723 | Xid | 1 | 754 | COMMIT /* xid=16 / |
| mysql-bin.000003 | 754 | Anonymous_Gtid | 1 | 819 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 819 | Query | 1 | 889 | BEGIN |
| mysql-bin.000003 | 889 | Table_map | 1 | 932 | table_id: 108 (dd.t1) |
| mysql-bin.000003 | 932 | Write_rows | 1 | 982 | table_id: 108 flags: STMT_END_F |
| mysql-bin.000003 | 982 | Xid | 1 | 1013 | COMMIT / xid=17 / |
| mysql-bin.000003 | 1013 | Anonymous_Gtid | 1 | 1078 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 1078 | Query | 1 | 1148 | BEGIN |
| mysql-bin.000003 | 1148 | Table_map | 1 | 1191 | table_id: 108 (dd.t1) |
| mysql-bin.000003 | 1191 | Update_rows | 1 | 1257 | table_id: 108 flags: STMT_END_F |
| mysql-bin.000003 | 1257 | Xid | 1 | 1288 | COMMIT / xid=19 */ |
| mysql-bin.000003 | 1288 | Anonymous_Gtid | 1 | 1353 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 1353 | Query | 1 | 1439 | drop database dd |
+------------------+------+----------------+-----------+-------------+-----------------------------------------------------------------+
23 rows in set (0.00 sec)

  1. 查看二进制日志的内容
mysqlbinlog --base64-output=decode-rows mysql-bin.000003

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#220111  8:34:30 server id 1  end_log_pos 123 CRC32 0xa22c6562         Start: binlog v 4, server v 5.7.35-log created 220111  8:34:30 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
# at 123
#220111  8:34:30 server id 1  end_log_pos 154 CRC32 0xd495691a         Previous-GTIDs
# [empty]
# at 154
#220111  8:38:21 server id 1  end_log_pos 219 CRC32 0x2ed37ddb         Anonymous_GTID        last_committed=0        sequence_number=1        rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 219
#220111  8:38:21 server id 1  end_log_pos 307 CRC32 0x421b49ef         Query        thread_id=2        exec_time=0        error_code=0
SET TIMESTAMP=1641890301/*!*/;
SET @@session.pseudo_thread_id=2/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1436549120/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8mb4 *//*!*/;
SET @@session.character_set_client=224,@@session.collation_connection=224,@@session.collation_server=224/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create database dd
/*!*/;
# at 307
#220111  8:40:02 server id 1  end_log_pos 372 CRC32 0xac0419aa         Anonymous_GTID        last_committed=1        sequence_number=2        rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 372
#220111  8:40:02 server id 1  end_log_pos 495 CRC32 0xe7cc4daf         Query        thread_id=3        exec_time=0        error_code=0
use `dd`/*!*/;
SET TIMESTAMP=1641890402/*!*/;
create table t1(id int) engine=innodb charset=utf8mb4
/*!*/;
# at 495
#220111  8:40:07 server id 1  end_log_pos 560 CRC32 0x9818fb3c         Anonymous_GTID        last_committed=2        sequence_number=3        rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 560
#220111  8:40:07 server id 1  end_log_pos 630 CRC32 0xfac003bc         Query        thread_id=3        exec_time=0        error_code=0
SET TIMESTAMP=1641890407/*!*/;
BEGIN
/*!*/;
# at 630
#220111  8:40:07 server id 1  end_log_pos 673 CRC32 0x417f0bd7         Table_map: `dd`.`t1` mapped to number 108
# at 673
#220111  8:40:07 server id 1  end_log_pos 723 CRC32 0x4fda72a4         Write_rows: table id 108 flags: STMT_END_F
# at 723
#220111  8:40:07 server id 1  end_log_pos 754 CRC32 0x386466de         Xid = 16
COMMIT/*!*/;
# at 754
#220111  8:40:15 server id 1  end_log_pos 819 CRC32 0x4b9638cf         Anonymous_GTID        last_committed=3        sequence_number=4        rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 819
#220111  8:40:15 server id 1  end_log_pos 889 CRC32 0x528f0486         Query        thread_id=3        exec_time=0        error_code=0
SET TIMESTAMP=1641890415/*!*/;
BEGIN
/*!*/;
# at 889
#220111  8:40:15 server id 1  end_log_pos 932 CRC32 0x30a6fc1b         Table_map: `dd`.`t1` mapped to number 108
# at 932
#220111  8:40:15 server id 1  end_log_pos 982 CRC32 0xe1bc0211         Write_rows: table id 108 flags: STMT_END_F
# at 982
#220111  8:40:15 server id 1  end_log_pos 1013 CRC32 0x8e17c38f         Xid = 17
COMMIT/*!*/;
# at 1013
#220111  8:40:26 server id 1  end_log_pos 1078 CRC32 0x94341c84         Anonymous_GTID        last_committed=4        sequence_number=5        rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 1078
#220111  8:40:26 server id 1  end_log_pos 1148 CRC32 0x3ad15ab4         Query        thread_id=3        exec_time=0        error_code=0
SET TIMESTAMP=1641890426/*!*/;
BEGIN
/*!*/;
# at 1148
#220111  8:40:26 server id 1  end_log_pos 1191 CRC32 0x90cb6111         Table_map: `dd`.`t1` mapped to number 108
# at 1191
#220111  8:40:26 server id 1  end_log_pos 1257 CRC32 0x3ee3da27         Update_rows: table id 108 flags: STMT_END_F
# at 1257
#220111  8:40:26 server id 1  end_log_pos 1288 CRC32 0xe388ec82         Xid = 19
COMMIT/*!*/;
# at 1288
#220111  8:40:57 server id 1  end_log_pos 1353 CRC32 0x3ef982db         Anonymous_GTID        last_committed=5        sequence_number=6        rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 1353
#220111  8:40:57 server id 1  end_log_pos 1439 CRC32 0x7b286939         Query        thread_id=4        exec_time=0        error_code=0
SET TIMESTAMP=1641890457/*!*/;
SET @@session.pseudo_thread_id=4/*!*/;
drop database dd
/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

二进制日志三种模式的区别

  1. 查看二进制日志模式
select @@binlog_format;
+-----------------+
| @@binlog_format |
+-----------------+
| ROW             |
+-----------------+
1 row in set (0.00 sec)

  • 配置说明

    • statement---->SBR:做什么记录什么,即SQL语句
    • row---------->RBR:记录数据行的变化(默认模式,推荐)
    • mixed-------->MBR:自动判断记录模式
  1. SBR和RBR的区别


|

区别项

|

SBR

|

RBR(默认模式,推荐)

|
|

记录内容

|

SQL语句

|

记录数据行变化

|
|

可读性

|

较强

|

|
|

日志量

|

|

|
|

日志记录准确性

|

数据误差

|

没有误差

|

  • ROW: 基于行的复制
    • 优点:所有的语句都可以复制,不记录执行的sql语句的上下文相关的信息,仅需要记录那一条记录被 修改成什么了
    • 缺点:binlog 大了很多,复杂的回滚时 binlog 中会包含大量的数据;主服务器上执行update语句时, 所有发生变化的记录都会写到 binlog 中;比如有这样一条update语句:update product set owner_member_id='d' where owner_member_id='a',执行之后,日志中记录的不是这条update语句 所对应的事件(mysql是以事件的形式来记录bin-log日志),而是这条语句所更新的每一条记录的变化情 况,这样就记录成很多条记录被更新的很多事件。自然,bin-log日志的量会很大。
  • Statement: 基于sql语句的复制
    • 优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能
    • 缺点:由于它是记录的执行语句,所以为了让这些语句在slave端也能正确执行,那么他还必须记录每 条语句在执行的时候的一些相关信息,也就是上下文信息,以保证所有语句在slave端被执行的时候能 够得到和在master端执行时候相同的结果。另外就是,由于mysql现在发展比较快,很多的新功能加入, 使mysql的复制遇到了不小的挑战,自然复制的时候涉及到越复杂的内容,bug也就越容易出现。在 statement level下,目前已经发现的就有不少情况会造成mysql的复制问题,主要是修改数据的时候使 用了某些特定的函数或者功能的时候会出现,比如sleep()在有些版本就不能正确复制。
  • mixed模式 :row 与 statement 结合 实际上就是前两种模式的结合,在mixed模式下,mysql会根据执行的每一条具体的sql语句来区分对待 记录的日志形式,也就是在statement和row之间选一种。新版本中的statement level还是和以前一 样,仅仅记录执行的语句。而新版本的mysql中对row level模式被做了优化,并不是所有的修改都会以 row level来记录,像遇到表结构变更的时候就会以statement模式来记录,如果sql语句确实就是 update或者delete 等修改数据的语句,那么还是会记录所有行的变更。

二进制日志内容

除了查询类的语句,都会记录,即所有数据库变更类的语句。

  1. 记录语句的种类
  • DDL(数据定义语言):create、drop
  • DCL(数据控制语言):grant 、revoke
  • DML(数据操作语言):insert、update、delete
  1. 不同语句的记录格式说明
  • DDL、DCL直接以语句(statement)方式记录 .
  • DML 语句有三种模式:SBR、RBR、MBR

二进制日志事件

  1. 二进制日志事件简介
  • 二进制日志内容以事件(binlog events)为最小记录单元。
  • 对于DDL和DCL,一个语句就是一个事件。
  • 对于DML(标准的事务语句),只记录已提交的事务的DML语句
begin ; 事件1 
a 事件2 
b 事件3 
commit; 事件4 

  1. 事件的构成(为了截取日志)
mysqlbinlog mysql-bin.000001 
# at 219 事件开始的位置(position) 
end_log_pos 319 事件结束的位置(position) 
#200219 14:28:12 事件发生的时间 
create database qfedu 事件内容

传统二进制日志恢复(通过posittion恢复)

  1. 查看当前使用日志
show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |     1439 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

  1. 查看当前日志事件信息
show binlog events in 'mysql-bin.000003'
+------------------+------+----------------+-----------+-------------+-----------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+------+----------------+-----------+-------------+-----------------------------------------------------------------+
| mysql-bin.000003 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.35-log, Binlog ver: 4 |
| mysql-bin.000003 | 123 | Previous_gtids | 1 | 154 | |
| mysql-bin.000003 | 154 | Anonymous_Gtid | 1 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 219 | Query | 1 | 307 | create database dd |
| mysql-bin.000003 | 307 | Anonymous_Gtid | 1 | 372 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 372 | Query | 1 | 495 | use dd; create table t1(id int) engine=innodb charset=utf8mb4 |
| mysql-bin.000003 | 495 | Anonymous_Gtid | 1 | 560 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 560 | Query | 1 | 630 | BEGIN |
| mysql-bin.000003 | 630 | Table_map | 1 | 673 | table_id: 108 (dd.t1) |
| mysql-bin.000003 | 673 | Write_rows | 1 | 723 | table_id: 108 flags: STMT_END_F |
| mysql-bin.000003 | 723 | Xid | 1 | 754 | COMMIT /* xid=16 / |
| mysql-bin.000003 | 754 | Anonymous_Gtid | 1 | 819 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 819 | Query | 1 | 889 | BEGIN |
| mysql-bin.000003 | 889 | Table_map | 1 | 932 | table_id: 108 (dd.t1) |
| mysql-bin.000003 | 932 | Write_rows | 1 | 982 | table_id: 108 flags: STMT_END_F |
| mysql-bin.000003 | 982 | Xid | 1 | 1013 | COMMIT / xid=17 / |
| mysql-bin.000003 | 1013 | Anonymous_Gtid | 1 | 1078 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 1078 | Query | 1 | 1148 | BEGIN |
| mysql-bin.000003 | 1148 | Table_map | 1 | 1191 | table_id: 108 (dd.t1) |
| mysql-bin.000003 | 1191 | Update_rows | 1 | 1257 | table_id: 108 flags: STMT_END_F |
| mysql-bin.000003 | 1257 | Xid | 1 | 1288 | COMMIT / xid=19 */ |
| mysql-bin.000003 | 1288 | Anonymous_Gtid | 1 | 1353 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 1353 | Query | 1 | 1439 | drop database dd |
+------------------+------+----------------+-----------+-------------+-----------------------------------------------------------------+
23 rows in set (0.00 sec)

由上可以看出,我们drop database时记录的pos为1353,所以我们后续截取二进制日志的最后点为1288。再看create database时记录的pos为219,所以我们后续截取二进制日志的开始点为219.

  1. 截取日志

由上可以看出,我们需要截取日志的开始点和结尾点。

mysqlbinlog --start-position=219  --stop-position=1288 mysql-bin.000003 > test.sql

  1. 查看test.sql
cat test.sql
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#220111  8:34:30 server id 1  end_log_pos 123 CRC32 0xa22c6562         Start: binlog v 4, server v 5.7.35-log created 220111  8:34:30 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG '
FkHdYQ8BAAAAdwAAAHsAAAABAAQANS43LjM1LWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAWQd1hEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
AWJlLKI=
'/*!*/;
# at 219
#220111  8:38:21 server id 1  end_log_pos 307 CRC32 0x421b49ef         Query        thread_id=2        exec_time=0        error_code=0
SET TIMESTAMP=1641890301/*!*/;
SET @@session.pseudo_thread_id=2/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1436549120/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8mb4 *//*!*/;
SET @@session.character_set_client=224,@@session.collation_connection=224,@@session.collation_server=224/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create database dd
/*!*/;
# at 307
#220111  8:40:02 server id 1  end_log_pos 372 CRC32 0xac0419aa         Anonymous_GTID        last_committed=1        sequence_number=2        rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 372
#220111  8:40:02 server id 1  end_log_pos 495 CRC32 0xe7cc4daf         Query        thread_id=3        exec_time=0        error_code=0
use `dd`/*!*/;
SET TIMESTAMP=1641890402/*!*/;
create table t1(id int) engine=innodb charset=utf8mb4
/*!*/;
# at 495
#220111  8:40:07 server id 1  end_log_pos 560 CRC32 0x9818fb3c         Anonymous_GTID        last_committed=2        sequence_number=3        rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 560
#220111  8:40:07 server id 1  end_log_pos 630 CRC32 0xfac003bc         Query        thread_id=3        exec_time=0        error_code=0
SET TIMESTAMP=1641890407/*!*/;
BEGIN
/*!*/;
# at 630
#220111  8:40:07 server id 1  end_log_pos 673 CRC32 0x417f0bd7         Table_map: `dd`.`t1` mapped to number 108
# at 673
#220111  8:40:07 server id 1  end_log_pos 723 CRC32 0x4fda72a4         Write_rows: table id 108 flags: STMT_END_F

BINLOG '
Z0LdYRMBAAAAKwAAAKECAAAAAGwAAAAAAAEAAmRkAAJ0MQABAwAB1wt/QQ==
Z0LdYR4BAAAAMgAAANMCAAAAAGwAAAAAAAEAAgAB//4BAAAA/gIAAAD+AwAAAKRy2k8=
'/*!*/;
# at 723
#220111  8:40:07 server id 1  end_log_pos 754 CRC32 0x386466de         Xid = 16
COMMIT/*!*/;
# at 754
#220111  8:40:15 server id 1  end_log_pos 819 CRC32 0x4b9638cf         Anonymous_GTID        last_committed=3        sequence_number=4        rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 819
#220111  8:40:15 server id 1  end_log_pos 889 CRC32 0x528f0486         Query        thread_id=3        exec_time=0        error_code=0
SET TIMESTAMP=1641890415/*!*/;
BEGIN
/*!*/;
# at 889
#220111  8:40:15 server id 1  end_log_pos 932 CRC32 0x30a6fc1b         Table_map: `dd`.`t1` mapped to number 108
# at 932
#220111  8:40:15 server id 1  end_log_pos 982 CRC32 0xe1bc0211         Write_rows: table id 108 flags: STMT_END_F

BINLOG '
b0LdYRMBAAAAKwAAAKQDAAAAAGwAAAAAAAEAAmRkAAJ0MQABAwABG/ymMA==
b0LdYR4BAAAAMgAAANYDAAAAAGwAAAAAAAEAAgAB//4LAAAA/gwAAAD+DQAAABECvOE=
'/*!*/;
# at 982
#220111  8:40:15 server id 1  end_log_pos 1013 CRC32 0x8e17c38f         Xid = 17
COMMIT/*!*/;
# at 1013
#220111  8:40:26 server id 1  end_log_pos 1078 CRC32 0x94341c84         Anonymous_GTID        last_committed=4        sequence_number=5        rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 1078
#220111  8:40:26 server id 1  end_log_pos 1148 CRC32 0x3ad15ab4         Query        thread_id=3        exec_time=0        error_code=0
SET TIMESTAMP=1641890426/*!*/;
BEGIN
/*!*/;
# at 1148
#220111  8:40:26 server id 1  end_log_pos 1191 CRC32 0x90cb6111         Table_map: `dd`.`t1` mapped to number 108
# at 1191
#220111  8:40:26 server id 1  end_log_pos 1257 CRC32 0x3ee3da27         Update_rows: table id 108 flags: STMT_END_F

BINLOG '
ekLdYRMBAAAAKwAAAKcEAAAAAGwAAAAAAAEAAmRkAAJ0MQABAwABEWHLkA==
ekLdYR8BAAAAQgAAAOkEAAAAAGwAAAAAAAEAAgAB///+CwAAAP4KAAAA/gwAAAD+CgAAAP4NAAAA
/goAAAAn2uM+
'/*!*/;
# at 1257
#220111  8:40:26 server id 1  end_log_pos 1288 CRC32 0xe388ec82         Xid = 19
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

  1. 恢复日志
    1. 进入数据库
    2. 刷新日志
flush logs;
Query OK, 0 rows affected (0.01 sec)

  1. 退出数据库并恢复日志
mysql -uxxx -pxxx < test.sql

传统二进制日志恢复(通过gtid恢复)

暂时没写

传统二进制日志恢复(通过time恢复)

暂时没写

你可能感兴趣的:(mysql主从架构、备份与恢复)