如何通过MySQL relaylog + SQL

50次阅读
没有评论

共计 4230 个字符,预计需要花费 11 分钟才能阅读完成。

这篇文章给大家介绍如何通过 MySQL relaylog + SQL_Thread 增量恢复 binlog,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

数据回档常常是使用全量备份 +binlog 增量实现的。
而数据量很大的情况下,增量恢复 binlog 一直是一个苦恼的问题,因为恢复 binlog 速度十分慢,并且容易出错。

恢复 binlog 文件一般有两种方法:

〇 先解析成 sql 文件,再导入 MySQL

mysqlbinlog mysql-bin.000001 –start-position=n /data/add.sql

mysqlbinlog mysql-bin.000002 … mysql-bin.n /data/add.sql

mysql -u -p -S /data/add.sql

〇 直接管道到 MySQL 中

mysqlbinlog mysql-bin.000001 –start-position=n | mysql -u -p -S

mysqlbinlog mysql-bin.000002 … mysql-bin.n | mysql -u -p -S

关于这种方式的更多 info,可以参考:
https://dev.mysql.com/doc/refman/5.7/en/point-in-time-recovery.html

然而这两种方式原理都是一样的,通过 mysqlbinlog 解析成 sql 并导入到 MySQL 中。

〇 优点:
  操作方便,逻辑简单。
  无需关闭 mysqld。

〇 缺点:
  遇到 ERROR 难以定位位置,难以“断点恢复”。
  特殊字符或字符集的问题。
 max_allowed_packet 问题。
  恢复速度慢。
 

因为 relaylog 和 binlog 本质实际上是一样的,所以是否可以利用 MySQL 自身的 sql_thread 来增量 binlog 呢?

〇 处理思路:
 1)重新初始化一个实例,恢复全量备份文件。
 2)找到第一个 binlog 文件的 position,和剩下所有的 binlog。
 3)将 binlog 伪装成 relaylog,通过 sql thread 增量恢复。

这里只介绍核心部分,即伪装成 relaylog 的过程。

① 将 relay log info 的 repository 改到 file 中,并生成这个文件。

SET GLOBAL relay_log_info_repository= FILE

CHANGE MASTER TO master_host= 1 ,master_password= 1 ,master_user= 1 ,master_log_file= 1 ,master_log_pos=4;

通过 change 命令,是为了告诉 MySQL 自己为一个 slave 实例,因为无需用到 IO_Thread,故 host,password,user 等可以随意填写。
并且通过该步骤,生成 relay.info 文件。

② 关闭实例,将需要增量的 binlog 文件伪装成 relaylog。

cp mysql-bin.000003 mysql-bin.000004 mysql-bin.000005 mysql-bin.000006 mysql-bin.000007 mysql-bin.000008 mysql-bin.000009 mysql-bin.000010 $relaylogdir

cd $relaylogdir

rename mysql-bin. mysql-relay. mysql-bin.0000*

chown mysql:mysql -R .

通过 cp 命令将 binlog 移动到 $relaylogdir 里,该变量取决于实例的选项参数,默认放在 datadir 下。
再将 binlog 批量改名成 relaylog,并且给予对应的权限,否则会报错 OS error code  13:  Permission denied。

③ 修改 relay.info 文件和 relay-log.index 文件
将 relay.info 的第二三行改成需要执行的第一个 binlog(现在是 relaylog)的文件名和 position:

/data/mysql57/relaylog/mysql-relay.000003

1276895

第二三行对应 Relay_log_name 和 Relay_log_pos,等同于:
mysqlbinlog mysql-relay.000003 –start-position=1276895 | mysql -u -p -S
修改该文件是为了告诉 SQL_Thread 从哪一个文件和哪一个 position 开始执行事务

再修改 relay-log.index,清空原有信息,添加以下信息,为的是告诉 SQL_Thread 还有哪些 relaylog 是需要执行的。

/data/mysql57/relaylog/mysql-relay.000003

/data/mysql57/relaylog/mysql-relay.000004

/data/mysql57/relaylog/mysql-relay.000005

/data/mysql57/relaylog/mysql-relay.000006

/data/mysql57/relaylog/mysql-relay.000007

/data/mysql57/relaylog/mysql-relay.000008

/data/mysql57/relaylog/mysql-relay.000009

/data/mysql57/relaylog/mysql-relay.000010

④ 启动实例,开启 SQL_Thread:

START SLAVE sql_thread ;

只需要开启 SQL_Thread 即可

⑤ 检查复制状态:

mysql SHOW SLAVE STATUS\G

*************************** 1. row ***************************

Slave_IO_State:

Master_Host: 1

Master_User: 1

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: 1

Read_Master_Log_Pos: 4

Relay_Log_File: mysql-relay.000003    — 已经执行到的日志名

Relay_Log_Pos: 11529982    — 已经执行到日志的位置

Relay_Master_Log_File: 1

Slave_IO_Running: No

Slave_SQL_Running: Yes

Replicate_Do_DB:

Replicate_Ignore_DB:

Replicate_Do_Table:

Replicate_Ignore_Table:

Replicate_Wild_Do_Table:

Replicate_Wild_Ignore_Table:

Last_Errno: 0

Last_Error:

Skip_Counter: 0

Exec_Master_Log_Pos: 11529982

Relay_Log_Space: 5347038913

Until_Condition: None

Until_Log_File:

Until_Log_Pos: 0

Master_SSL_Allowed: No

Master_SSL_CA_File:

Master_SSL_CA_Path:

Master_SSL_Cert:

Master_SSL_Cipher:

Master_SSL_Key:

Seconds_Behind_Master: 274354    — 若变为 0,则表示已经增量完毕

Master_SSL_Verify_Server_Cert: No

Last_IO_Errno: 0

Last_IO_Error:

Last_SQL_Errno: 0

Last_SQL_Error:

Replicate_Ignore_Server_Ids:

Master_Server_Id: 0

Master_UUID:

Master_Info_File: /data/mysql57/master.info

SQL_Delay: 0

SQL_Remaining_Delay: NULL

Slave_SQL_Running_State: Reading event from the relay log

Master_Retry_Count: 86400

………………………………

该测试使用的版本为:MySQL 5.7.16

效果:恢复全备文件 +binlog 恢复到故障前的最后一个 position。

其他场景也适用,比如在某一时刻执行了错误的 sql,如 truncate 等操作,同样也可以通过该办法。
只需要将 START SLAVE sql_thread 后添加一个  UNTIL RELAY_LOG_FILE = log_name , RELAY_LOG_POS = log_pos 即可。
该选项用于控制 SQL_Thread 执行到的最后的 position,类似于 mysqlbinlog mysql-bin.n –stop-position=$log_pos。

除了更准确的能够恢复错误之外,还有一个最大的好处是加快了 binlog 增量的速度。

补充一个额外的测试数据
对于同一组 binlog 文件增量:
通过 mysqlbinlog 解析 + 导入的时间为 69min。
而通过 SQL_Thread 的执行时间为 41min。

并且在需要增量的 binlog 文件越大的情况下,效果越明显。

〇 优点:
    可以断点恢复,人为控制进度,比如 stop slave 或者遇到错误时,可以断点恢复。
    性能好,在大量 binlog 的情况下,可以加快恢复速度。
    在某些版本可以利用多线程复制来加快增量速度,时恢复更快。

〇 缺点:
    需要关闭 mysqld。
    手动执行过程较 mysqlbinlog 方式更为复杂。

〇  总结:
mysqlbinlog –start-position 与 通过修改 relay.info 的第三行等效:
用途都是指定开始执行的第一个 position。

mysqlbinlog –stop-position 与 通过在启动 SQL_Thread 时指定 UNTIL RELAY_LOG_FILE = log_name , RELAY_LOG_POS = log_pos 等效:
用途都是指定结束执行的最后一个 position。

关于如何通过 MySQL relaylog + SQL_Thread 增量恢复 binlog 就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-19发表,共计4230字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)