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

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

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

  1. mysqlbinlog mysql-bin.000001 --start-position=n > /data/add.sql
  2. mysqlbinlog mysql-bin.000002 ... mysql-bin.n >> /data/add.sql
  3. mysql -u -p -S < /data/add.sql

〇 直接管道到MySQL中

  1. mysqlbinlog mysql-bin.000001 --start-position=n | mysql -u -p -S
  2. 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中,并生成这个文件。

  1. SET GLOBAL relay_log_info_repository='FILE';
  2. 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。

  1. 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
  2. cd $relaylogdir
  3. rename mysql-bin. mysql-relay. mysql-bin.0000*
  4. 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:

  1. /data/mysql57/relaylog/mysql-relay.000003
  2. 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是需要执行的。

  1. /data/mysql57/relaylog/mysql-relay.000003
  2. /data/mysql57/relaylog/mysql-relay.000004
  3. /data/mysql57/relaylog/mysql-relay.000005
  4. /data/mysql57/relaylog/mysql-relay.000006
  5. /data/mysql57/relaylog/mysql-relay.000007
  6. /data/mysql57/relaylog/mysql-relay.000008
  7. /data/mysql57/relaylog/mysql-relay.000009
  8. /data/mysql57/relaylog/mysql-relay.000010

④ 启动实例,开启SQL_Thread:

  1. START SLAVE sql_thread ;

只需要开启SQL_Thread即可

⑤ 检查复制状态:

  1. mysql> SHOW SLAVE STATUS\G
  2. *************************** 1. row ***************************
  3. Slave_IO_State:
  4. Master_Host: 1
  5. Master_User: 1
  6. Master_Port: 3306
  7. Connect_Retry: 60
  8. Master_Log_File: 1
  9. Read_Master_Log_Pos: 4
  10. Relay_Log_File: mysql-relay.000003    -- 已经执行到的日志名
  11. Relay_Log_Pos: 11529982        -- 已经执行到日志的位置
  12. Relay_Master_Log_File: 1
  13. Slave_IO_Running: No
  14. Slave_SQL_Running: Yes
  15. Replicate_Do_DB:
  16. Replicate_Ignore_DB:
  17. Replicate_Do_Table:
  18. Replicate_Ignore_Table:
  19. Replicate_Wild_Do_Table:
  20. Replicate_Wild_Ignore_Table:
  21. Last_Errno: 0
  22. Last_Error:
  23. Skip_Counter: 0
  24. Exec_Master_Log_Pos: 11529982
  25. Relay_Log_Space: 5347038913
  26. Until_Condition: None
  27. Until_Log_File:
  28. Until_Log_Pos: 0
  29. Master_SSL_Allowed: No
  30. Master_SSL_CA_File:
  31. Master_SSL_CA_Path:
  32. Master_SSL_Cert:
  33. Master_SSL_Cipher:
  34. Master_SSL_Key:
  35. Seconds_Behind_Master: 274354        -- 若变为0,则表示已经增量完毕
  36. Master_SSL_Verify_Server_Cert: No
  37. Last_IO_Errno: 0
  38. Last_IO_Error:
  39. Last_SQL_Errno: 0
  40. Last_SQL_Error:
  41. Replicate_Ignore_Server_Ids:
  42. Master_Server_Id: 0
  43. Master_UUID:
  44. Master_Info_File: /data/mysql57/master.info
  45. SQL_Delay: 0
  46. SQL_Remaining_Delay: NULL
  47. Slave_SQL_Running_State: Reading event from the relay log
  48. Master_Retry_Count: 86400
  49. ………………………………

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

场景:可用于恢复将innodb_force_recovery设置为6仍然无法启动实例等case
效果:恢复全备文件+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复制线程SQL_Thread加快增量恢复binlog的更多相关文章

  1. MySQL 5.7 基于复制线程SQL_Thread加快恢复的尝试

    1. MySQL 数据恢复常用办法 MySQL恢复的方法一般有三种: 1. 官方推荐的基于全备+binlog , 通常做法是先恢复最近一次的全备,然后通过mysqlbiinlog --start-po ...

  2. MySQL复制(二)--基于二进制日志文件(binlog)配置复制

    基础环境:   主库 从库 服务器IP地址 192.168.10.11 192.168.10.12 版本 5.7.24 5.7.24 已存在的数据库 mysql> show databases; ...

  3. MySQL复制线程状态转变

    一.主库线程状态(State)值 以下列表显示了主从复制中主服务器的Binlog Dump线程的State列中可能看到的最常见状态(SHOW PROCESSLIST).如果Binlog Dump线程在 ...

  4. MySQL复制相关参数详解

    MySQL复制相关参数详解 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.复制相关系统变量 1>.server_id 是必须设置在master和每个slave上的唯一标 ...

  5. MYSQL 复制详解

    MySql 复制介绍 MySQL复制允许将主实例(master)上的数据同步到一个或多个从实例(slave)上,默认情况 下复制是异步进行的,从库也不需要一直连接到主库来同步数据 MySQL复制的数据 ...

  6. MySQL Replication--多线程复制MTS

    多线程复制 多线程复制MTS(Mult-Threaded Slave Applier)指使用多个线程来并发应用二进制日志.在MYSQL5.6版本中,多线程复制基于schema来实现,将多个数据库下的事 ...

  7. 深入MySQL复制(一)

    本文非常详细地介绍MySQL复制相关的内容,包括基本概念.复制原理.如何配置不同类型的复制(传统复制)等等.在此文章之后,还有几篇文章分别介绍GTID复制.半同步复制.实现MySQL的动静分离,以及M ...

  8. MySQL 复制介绍及搭建

    MySQL复制介绍 MySQL复制就是一台MySQL服务器(slave)从另一台MySQL服务器(master)进行日志的复制然后再解析日志并应用到自身,类似Oracle中的Data Guard. M ...

  9. MySQL复制进阶

    Ⅰ.背景 搭建MySQL复制环境非常简单 你的系统是否也是像我之前那么搭建的呢? 那么,你的复制系统是否出现过以下的情况呢? 复制报错,例如:1062,1032 主从数据不一致 Ⅱ.真正高可靠复制环境 ...

随机推荐

  1. C语言的内存四区模型和函数调用模型

    首先是操作系统将代码程序加载到内存中 然后将内存分为4个区 栈区,程序的局部变量区,函数传递的参数,由编译器自动进行内存资源的释放. 堆区,动态内存申请,如果不手动释放内存,则这块内存不会进行析构. ...

  2. less语言特性

    作为CSS的一种扩展,LESSCSS不仅向下兼容CSS的语法,而且连新增的特性也是使用CSS的语法.这样的设计使得学习LESS很轻松,而且你可以在任何时候回退到CSS. 变量 很容易理解: @nice ...

  3. k8s-创建node节点kubeconfig配置文件

    Kubeconfig 需要配置如下 TLS Bootstrapping Token kubelet kubeconfig kube-proxy kubeconfig 下载kubectl kubectl ...

  4. 面向对象——final关键字

    继承的弊端:打破了封装性 解决方式:final final关键字的特点: 1.final是一个修饰符,即可以修饰类,也可以修饰方法,还可以修饰变量 2.final修饰的类不可以被继承 3.final修 ...

  5. 面向对象(this关键字)

    package com_package2; public class Person3 { private int age; private String name; public int getAge ...

  6. jQuery 防止相同的事件快速重复触发

    重复触发就是防止用户重复点击提交数据了,我们一般都是点击之后没反应会再次点击了,这个不但要从用户体验上来做好,还在要js或php程序脚本上做好,让用户知道点击是己提交服务器正在处理,下面我就整理从脚本 ...

  7. 关于ajaxfileupload的使用方法以及一些问题

    使用问题: 1.ajax-fileupload.js handleError 异常 由于本来handleError方法是jquery的方法,但jquery到了某个版本这个方法就去掉了没有了 所以最简单 ...

  8. [转]对 td 使用 overflow:hidden; 无效的几点错误认识

    转载:http://www.cftea.com/c/2010/12/UVBUCD0J888L2XPQ.asp 一.是 td 的原因. 其实这关 td 什么事呢?div 也是一样的,看示例: <d ...

  9. vim跳转到文件的指定偏移位置

    :goto 偏移量 例如:偏移到文件的第100个字节处 :goto 100

  10. NOIP2014提高组 联合权值(距离为2的树形dp)

    联合权值 题目描述 无向连通图 GG 有 nn 个点,n-1n−1 条边.点从 11 到 nn 依次编号,编号为 ii 的点的权值为 W_iWi​,每条边的长度均为 11.图上两点 (u, v)(u, ...