首页 > 数据库 >MySQL 备库可以设置 sync_binlog 非 1 吗?【转】

MySQL 备库可以设置 sync_binlog 非 1 吗?【转】

时间:2024-08-07 14:38:31浏览次数:12  
标签:Binlog 备库 log relay binlog sync 复制 GTID

众所周知,防止断电丢失 Binlog、故障恢复过程丢失数据,MySQL 主库必须设置 sync_binlog=1。那么作为备库可以例外吗?

我们的第一反应当然是不行,既然主库会丢数据,备库自然一样。但其实不然,备库丢了数据是可以重新从主库上复制的,只要这个复制的位置和备库本身数据的位置一致就 OK 了,它们能一致吗?本文将对这个问题进行讨论。

背景知识

为了更好的说明这个问题,下面赘述一下相关的知识点:

  1. InnoDB 的二阶段提交中,Prepare 阶段写 Redo Log,Commit 阶段写 Binlog,故障恢复时保证:
  2. 所有已提交事务的 Binlog 一定存在。
  3. 所有未提交事务一定不记录 Binlog。
  4. 备库设置 relay_log_info_repository = table 时,slave_relay_log_info(即备库回放位置)的更新与 Relay Log 回放的 SQL 在同一个事务中提交。
  5. GTID 持久化在 Binlog 中,备库在某些条件下启动复制时会从 Executed_Gtid_Set 开始到主库复制数据。

根据以上 3 点,备库如果设置 sync_binlog 不为 1,在做故障恢复时的就会发生以下情况。

  • 事务状态:TRX_COMMITTED_IN_MEMORY、TRX_NOT_STARTED。如果 Binlog 未落盘,事务会重做,数据将比 Binlog 多,slave_relay_log_info 表记录的复制位置也将领先 Executed_Gtid_Set。
  • 事务状态:TRX_PREPARED。 由于Binlog 未刷盘,Recovery 时会回滚事务,数据与 Binlog 是一致的,slave_relay_log_info 表记录的复制位置等于 Executed_Gtid_Set。

如果备库断电恢复后,启动复制时用的位置由 slave_relay_log_info 决定,则备库数据还是能正常复制数据,并且能与主库保持一致,只是 GTID 会出现跳号。

反之如果由 Executed_Gtid_Set 决定,则备库复制会因为重复回放事务而报错,需要进行修复。下面设计一个实验来进行验证。

实验过程

1. 设置备库参数并制造“故障”

备库参数设置如下,主库用工具并发写入数据(这里用的 mysqlslap),然后备库强制关机(reboot -f)。

sync_binlog = 1000
innodb_flush_log_at_trx_commit = 1
relay_log_info_repository = table  ##slave_relay_log_info 表为 innodb 表
relay_log_recovery = on
gtid_mode = on

2. 重启备库

备库服务器开机后重启 MySQL,查看的信息如下。

show master status 输出的 Executed_Gtid_Set 如下:
fb9b7d78-6eb5-11ec-985a-0242ac101704:1-167216 

mysql> select * from slave_relay_log_info\G
*************************** 1. row ***************************
  Number_of_lines: 7
   Relay_log_name: ./localhost-relay-bin.000004
    Relay_log_pos: 4
  Master_log_name: mysql-bin.000001
   Master_log_pos: 48159613
        Sql_delay: 0
Number_of_workers: 0
               Id: 1
     Channel_name:
1 row in set (0.00 sec)

根据输出内容可知,从库的数据确实回放到了 mysql-bin.000001:48159613,对应的 GTID 为:
fb9b7d78-6eb5-11ec-985a-0242ac101704:167222,
只是从库的 Binlog 有丢失,GTID 为:
fb9b7d78-6eb5-11ec-985a-0242ac101704:1-167216。

...
SET @@SESSION.GTID_NEXT= 'fb9b7d78-6eb5-11ec-985a-0242ac101704:167222'/*!*/;
...
### INSERT INTO `mysqlslap`.`t`
### SET
###   @1=167216 /* INT meta=0 nullable=0 is_null=0 */
# at 48159586
#220407 14:10:34 server id 123456  end_log_pos 48159613         Xid = 169239
COMMIT/*!*/;
# at 48159613
...

从库已经有 167222 事务对应的数据。

mysql> select * from t where id=167216;
+--------+
| id     |
+--------+
| 167216 |
+--------+
1 row in set (0.00 sec)

3. 备库启动复制

Error Log 显示的起始位置和 slave_relay_log_info 内容一样,从主库的 mysql-bin.000001:48159613 开始,对应 GTID 为 167222+1。

Slave I/O thread: Start asynchronous replication to master '[email protected]:3308' in log 'mysql-bin.000001' at position 48159613

但接下来 SQL 线程报错位置却是 mysql-bin.000001:48158146,比开始位置还靠前,这个位置对应的 GTID 为 167217(即167216+1):

2022-04-07T06:33:18.611181-00:00 4 [ERROR] Slave SQL for channel '': Could not execute Write_rows event on table mysqlslap.t; Duplicate entry '167212' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin.000001, end_log_pos 48158146, Error_code: 1062

而且解析从库 Relay Log(因为设置了 relay_log_recovery = on,启动复制时会丢弃旧的未 Relay Log 重新到主库取 Binlog),第一个事务也是 SET @@SESSION.GTID_NEXT= '
fb9b7d78-6eb5-11ec-985a-0242ac101704:167217'/*!*/;,而不是 167223。这说明了启动复制的位置并不是 slave_relay_log_info 记录的位置,而是从库的 GTID。

4. 重复以上测试

在启动从库复制前执行 change master to master_auto_position=0; 这回不报错,是从 167223 这个 GTID 开始复制数据,从库 GTID 会出现跳号。

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                                           |
+------------------+----------+--------------+------------------+-------------------------------------------------------------+
| mysql-bin.000006 |  9976340 |              |                  | fb9b7d78-6eb5-11ec-985a-0242ac101704:1-167216:167223-200670 |
+------------------+----------+--------------+------------------+-------------------------------------------------------------+
1 row in set (0.01 sec)

结论

从库 sync_binlog 设置不为 1,发生断电会丢失 Binlog,因为 GTID 持久化在 Binlog 中,因此也会丢失 GTID。但是数据和 slave_relay_log_info 表中保存的 SQL 线程回放位置一致。

此时:

  • 如果 master_auto_position=0,则从库重启复制时可以从正确的位置开始复制数据,从而与主库数据一致。不过从库会产生 GTID 跳号。
  • 如果 master_auto_position=1,则从库重启复制时会从 GTID 处开始复制数据,由于 GTID 有丢失,所以会重复回放事务,产生报错。

转自

MySQL 备库可以设置 sync_binlog 非 1 吗?-今日头条
https://www.toutiao.com/article/7397351436743246351/?log_from=3e7c681c8f92f_1723000169039

标签:Binlog,备库,log,relay,binlog,sync,复制,GTID
From: https://www.cnblogs.com/paul8339/p/18347000

相关文章

  • 【vulhub靶场之rsync关】
    一、使用nmap模块查看该ip地址有没有Rsync未授权访问漏洞nmap-p873--scriptrsync-list-modules加IP地址查看到是有漏洞的模块的二、使用rsync命令连接并读取文件查看src目录里面的信息。三、对系统中的敏感文件进行下载——/etc/passwd执行命令:rsyncrsync:/......
  • 串行通信协议--UART(Universal Asynchronous Receiver/Transmitter,通用异步收发传输器
    一、UART简介  UART广泛应用于微控制器和计算机之间的数据通信,如GPS模块、蓝牙模块、GSM模块等。UART是一种通用串行数据总线,用于异步通信,该总线双向通信,可以实现全双工传输和接收。在嵌入式设计中,UART用于主机与辅助设备通信UART通常被集成于其他通讯接口的连结上。UA......
  • 问:@Async和@Transaction可以一起使用吗?
     在Java中,@Async和@Transaction注解是可以一起使用的,但需要注意一些细节和潜在问题。 1.@Async和@Transactions注解@Async注解:用于异步执行方法。使用此注解的方法会在单独线程中执行,而不会阻塞调用线程。在需要执行耗时操作而不希望阻塞主线程时非常有用。......
  • Java并发—synchronized关键字的应用
    目录1、synchronized适用场景2、synchronized的原理3、synchronized的锁升级4、synchronized的注意事项5、总结synchronized是Java中用于实现线程同步的关键字。它可以在方法级别或代码块级别使用,以确保同一时刻只有一个线程可以访问被同步的代码段。synchronized通......
  • 文件服务器rsync
    服务器配置echo"cc:cc2023">/etc/rsync.passwordchmod600/etc/rsync.passwordvi/etc/rsyncd.confuid=rootgid=rootusechroot=nomaxconnections=40pidfile=/var/run/rsyncd.pidlogfile=/var/log/rsyncd.logexclude=lost+found/tran......
  • synchronized介绍
    synchronized原理:从JVM规范中可以看到Synchonized在JVM里的实现原理,JVM基于进入和退出Monitor对象来实现方法同步和代码块同步,但两者的实现细节不一样。代码块同步是使用monitorenter和monitorexit指令实现的,而方法同步是使用另外一种方式实现的,通过编译之后,同步方法与普......
  • 一文讲清楚synchronized原理---每周一更系列
    synchronized是Java提供的原子性内置锁,这种内置的并且使用者看不到的锁也被称为监视器锁。synchronized通过在代码块前后加上monitorenter和monitorexit字节码指令用于实现进入和退出。如果是同步方法,则是打上标记,隐式的使用monitorenter和monitorexit字节码指令。在jdk1.5之前......
  • obsidian群晖同步方案-Möbius Sync
    概述采用MöbiusSync的原因,主要有两点原因使用obsidian的remotesave在移动端同步后,obsidian经常卡死,无法查看;remotesave配置过程种,ios设备配置的服务地址需要https,但是家用没有ssl证书导致配置失败;群晖-obsidian-各设备之间的同步方案nas配置MöbiusSync1.nas......
  • 一文搞定:Syncthing多平台文件同步工具安装全攻略
    简介Syncthing是一款开源的文件同步工具,可以通过本地网络或互联网实现多台设备之间的文件同步。与其他同步工具不同,Syncthing强调隐私和安全,确保用户的数据始终处于用户的控制之下。功能与特点开源软件:Syncthing是完全开源的,源代码托管在GitHub上,任何人都可以查看、审查和......
  • 利用 Oracle 19c 新特性 from service 修复备库 GAP
    转发自:https://mp.weixin.qq.com/s/Jz8lEQ6QAnjoTeErbX0q_g前 言相信我们DBA在OracleDataGuard环境中遇到过因主库归档空间有限,归档日志又没有备份,空间满的时候直接删除了归档,导致丢失归档日志,而备库还没有及时接收到这个归档,导致备库出现了GAP现象。因为日志的中断,备......