欢送来到 GreatSQL社区分享的MySQL技术文章,如有疑难或想学习的内容,能够在下方评论区留言,看到后会进行解答

当主库宕机后,提早从库如何能力"勾销"被动提早,以便复原服务?

问题形容

本问题来自一位群友,他遇到的状况我简略演绎一下:

  • 实例A是主库,B是提早从库(设置了提早7200秒)。
  • 当A挂掉后(已无奈连贯,或无奈启动),心愿用B晋升成主库。
  • 然而在B上执行 change master to MASTER_DELAY=0 后,B上曾经保留的7200秒的relay文件也会被革除掉,并尝试再次从A获取binlog,这样会造成7200秒的数据失落,未能达成目标。

TA想问:在这样的场景下,还有方法让B库尽快跑完这7200秒提早数据吗,或者正确的方法是什么呢?

问题解决

先答复问题:这个需要是有方法达成的(而且还不只一种办法),最正确的办法也并不麻烦/简单(看到最初),只不过有些小窍门要留神下。

办法1,批改零碎工夫

也就是批改B主机的零碎工夫,将其往后调整超过7200秒,而后重启slave线程,就能让SQL_THREAD持续利用relay log了。所有relay log利用结束后,再将零碎工夫批改回来。

# 批改零碎工夫,减少7200秒[root@greatsql]# date -s "`date --date '7200 second'`"# 重启slave线程[root@GreatSQL](none)>  STOP SLAVE; START SLAVE;

留神:这种办法(潜在)影响很大,可能对其余零碎利用有影响,或者MySQL里局部波及到日期工夫的后果也会受到影响,十分不举荐。

办法2,自行手动复原relay log/binlog

当主库(A)宕机后,查看以后slave的状态:

[root@GreatSQL](none)> SHOW SLAVE STATUS\G...              Master_Log_File: binlog.000011          Read_Master_Log_Pos: 2671               Relay_Log_File: relay-bin.000005                Relay_Log_Pos: 361        Relay_Master_Log_File: binlog.000011             Slave_IO_Running: Connecting            Slave_SQL_Running: Yes...          Exec_Master_Log_Pos: 746              Relay_Log_Space: 2704...        Seconds_Behind_Master: 387...                    SQL_Delay: 7200          SQL_Remaining_Delay: 6814      Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event

能够看到这时候有387秒的落后,被动提早7200秒,还有6814秒之后能力利用最新的relay log。尽管事务有提早,但其实slave曾经把binlog都复制过去了,在relay log里。

     Read_Master_Log_Pos: 2671  <-- 已读取到最新的binlog了,pos = 2671               Relay_Log_File: relay-bin.000005  <-- 对应的relay log                Relay_Log_Pos: 361  <-- 对应的relay log pos...          Exec_Master_Log_Pos: 746  <-- 但只apply到 pos = 746

当初,只须要手动把这两头的差别数据拿进去apply就能够了。解析relay log,找到对应master binlog pos = 746的地位,或者间接指定realy log pos = 361的地位也能够:

[root@greatsql]# ls -la relay-bin.*-rw-r----- 1 mysql mysql  418 Jun 13 13:31 relay-bin.000004-rw-r----- 1 mysql mysql 2286 Jun 13 13:33 relay-bin.000005-rw-r----- 1 mysql mysql   58 Jun 13 13:31 relay-bin.index[root@greatsql]# mysqlbinlog --base64-output=decode-rows -vvv relay-bin.000005...# at 196#700101  8:00:00 server id 5001  end_log_pos 0 CRC32 0xaf7e0f79         Rotate to binlog.000011  pos: 746# at 240#210613 11:26:08 server id 5001  end_log_pos 0 CRC32 0xfa7fd769         Start: binlog v 4, server v 8.0.22-13 created 210613 11:26:08# at 361#210613 13:33:41 server id 5001  end_log_pos 825 CRC32 0xd5161853       GTID    last_committed=1        sequence_number=3       rbr_only=yes    original_committed_timestamp=1623562421106412   immediate_commit_timestamp=1623562421106412     transaction_length=275...

确认对应的事务是存在的,接下来就能够利用relay log复原数据了。

[root@greatsql]# mysqlbinlog relay-bin.000005 --start-position=361 | mysql -S./mysql.sock -f

当然了,如果此时A主机还能够连贯,只是mysqld服务无奈启动的话,亦可间接用A主机上的binlog进行复原。

这种办法须要仔细审慎,手眼配合亲密,容易出错,因而也不举荐。

办法3,正确理解MASTER_DELAY,一键搞定

后面铺垫了那么多,看起来想要让提早从库疾速复原如同有点麻烦的样子。

事实上,只有正确理解,一键命令就搞定了。

当主库产生故障宕机后,binlog其实曾经都复制到从库并写入成relay log了。当然了,为防止误操作,倡议先备份relay log。

接下来的操作很重要,看准了,肯定不要做错:

# 只敞开SQL_THREAD,而不是间接敞开整个SLAVE服务[root@GreatSQL](none)> STOP SLAVE SQL_THREAD;# 批改MASTER_DELAY,使之不再提早[root@GreatSQL](none)> CHANGE MASTER TO MASTER_DELAY=0;# 再次启动SQL_THREAD[root@GreatSQL](none)> START SLAVE SQL_THREAD;

主库尽管宕机了,但从库上只有IO_THREAD会报告连贯谬误,SQL_THREAD还是能够失常工作的。

上述操作的关键点在于,批改 MASTER_DELAY 时并没有先停掉 IO_THREAD,否则会清空所有的relay log,尝试去主库再次拉取。

再次启动 SQL_THREAD 之后,从库就会持续利用relay log,待到全副利用结束后,实现必要的数据校验,即可提成成为新的主库,对外提供服务了。

看,真的挺简略的吧。

当初来验证下:齐全停掉SLAVE服务后批改MASTER_DELAY值,再启动SLAVE服务,此时会清空重置relay log。

# 主库宕机后,查看SLAVE状态[root@GreatSQL](none)> SHOW SLAVE STATUS\G...              Master_Log_File: binlog.000017          Read_Master_Log_Pos: 471               Relay_Log_File: relay-bin.000002                Relay_Log_Pos: 321        Relay_Master_Log_File: binlog.000017             Slave_IO_Running: Connecting            Slave_SQL_Running: Yes...          Exec_Master_Log_Pos: 196...        Seconds_Behind_Master: 69...                    SQL_Delay: 7200          SQL_Remaining_Delay: 7132      Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event...# 查看relay log状态[root@greatsql]# ls -la relay-bin.*-rw-r----- 1 mysql mysql 213 Jun 13 15:11 relay-bin.000001-rw-r----- 1 mysql mysql 596 Jun 13 15:11 relay-bin.000002-rw-r----- 1 mysql mysql  58 Jun 13 15:11 relay-bin.index# 敞开SLAVE服务,批改MASTER_DELAY,再启动SLAVE服务[root@GreatSQL](none)> STOP SLAVE; CHANGE MASTER TO MASTER_DELAY=0; START SLAVE;# 再次查看relay log,发现被清空重置了[root@greatsql]# ls -la relay-bin.*-rw-r----- 1 mysql mysql 156 Jun 13 15:18 relay-bin.000001-rw-r----- 1 mysql mysql  29 Jun 13 15:18 relay-bin.index

所以,请记住了,当提早从库要批改提早设置时,只需重启SQL_THREAD,千万别图省事重启整个SLAVE服务,这样relay log就不会被清空重置了,也就能实现疾速复原并晋升为主库。为以防万一,也请务必备份好relay log。

因为relay log是由 IO_THREAD 负责的,所以只有 IO_THREAD 不重启,就不会清空重置。看下MySQL文档中对于relay log的阐明:

#原文出处 https://dev.mysql.com/doc/refman/8.0/en/replica-logs.htmlThe replica's relay log, which is written by the replication I/O thread, contains the transactions read from the replication source server's binary log. The transactions in the relay log are applied on the replica by the replication SQL thread. For information about the relay log, see Section 17.2.4.1, “The Relay Log”.

P.S,本文应用的GreatSQL 8.0.22-13,对于这个版本的阐明详见 GreatSQL,打造更好的MGR生态。

延长浏览

  • 13.4.2.1 CHANGE MASTER TO Statement, https://dev.mysql.com/doc/ref...
  • 18.17.2.4 Relay Log and Replication Metadata Repositories, https://dev.mysql.com/doc/ref...
  • 18.17.4.11 Delayed Replication, https://dev.mysql.com/doc/ref...

Enjoy GreatSQL :)

文章举荐:

技术分享 | MGR最佳实际(MGR Best Practice)
https://mp.weixin.qq.com/s/66...

技术分享 | 万里数据库MGR Bug修复之路
https://mp.weixin.qq.com/s/Ia...

Macos零碎编译percona及局部函数在Macos零碎上运算差别
https://mp.weixin.qq.com/s/jA...

技术分享 | 利用systemd治理MySQL单机多实例
https://mp.weixin.qq.com/s/iJ...

产品 | GreatSQL,打造更好的MGR生态
https://mp.weixin.qq.com/s/By...

产品 | GreatSQL MGR优化参考
https://mp.weixin.qq.com/s/5m...

对于 GreatSQL

GreatSQL是由万里数据库保护的MySQL分支,专一于晋升MGR可靠性及性能,反对InnoDB并行查问个性,是实用于金融级利用的MySQL分支版本。

Gitee:
https://gitee.com/GreatSQL/Gr...

GitHub:
https://github.com/GreatSQL/G...

微信&QQ群:

可扫码增加GreatSQL社区助手微信好友,发送验证信息“加群”退出GreatSQL/MGR交换微信群,亦可间接扫码退出GreatSQL/MGR交换QQ群。

本文由博客一文多发平台 OpenWrite 公布!