【案例】主从替换之后的复制风暴

一 现象
  一套MySQL主-备-备-备数据库,其中的备库升级到主库之后,系统监控报警 Seconds_Behind_Master 瞬间为0,瞬间为数十万秒。第一感觉是遇到了复制风暴--不同于主备server_id 的log event在主备库之间无限循环复制。升级的逻辑图如下:
     

二 分析

  在双主复制结构中,主库发生数据更新,会将更新记录为含有server_id_1 的log event事件发送到备库,然后备库更新数据,将含有server_id_1的log event 事件发送给主库,因此最初主库上的log event 更新事件又传了回来,这时候MySQL就要对复制事件的server_id进行判断,发现复制事件的server_id和自己的server_id相同时,放弃执行,如果不同 则执行该log event 并记录到binlog 里面继续发送给备库。 如果该event的server_id和主备的server_id都不相同,该log event 则在主备库中无限循环执行,也就是通常所说的复制风暴。

 那为什么slave lag 为时大时小呢?首先我们要了解MySQL 对于slave lag 的计算方式(sql/slave.cc ) 

bool show_master_info(THD* thd, Master_info* mi)

{

    /*省略*/

    /*

      Seconds_Behind_Master: if SQL thread is running and I/O thread is

      connected, we can compute it otherwise show NULL (i.e. unknown).

    */

    if ((mi->slave_running == MYSQL_SLAVE_RUN_CONNECT) &&

        mi->rli.slave_running)

    {

      long time_diff= ((long)(time(0) - mi->rli.last_master_timestamp)

                       - mi->clock_diff_with_master);

      /*

        Apparently on some systems time_diff can be <0. Here are possible

        reasons related to MySQL:

        - the master is itself a slave of another master whose time is ahead.

        - somebody used an explicit SET TIMESTAMP on the master.

        Possible reason related to granularity-to-second of time functions

        (nothing to do with MySQL), which can explain a value of -1:

        assume the master's and slave's time are perfectly synchronized, and

        that at slave's connection time, when the master's timestamp is read,

        it is at the very end of second 1, and (a very short time later) when

        the slave's timestamp is read it is at the very beginning of second

        2. Then the recorded value for master is 1 and the recorded value for

        slave is 2. At SHOW SLAVE STATUS time, assume that the difference

        between timestamp of slave and rli->last_master_timestamp is 0

        (i.e. they are in the same second), then we get 0-(2-1)=-1 as a result.

        This confuses users, so we don't go below 0: hence the max().

        last_master_timestamp == 0 (an "impossible" timestamp 1970) is a

        special marker to say "consider we have caught up".

      */

      protocol->store((longlong)(mi->rli.last_master_timestamp ?

                                 max(0, time_diff) : 0));

    }

    else

    {

      protocol->store_null();

    }

    /*省略*/

}

解释如下:
long_time_diff就是seconds_behind_master
seconds_behind_master=slave系统时间 - master执行创建event的timestamp - ( slave系统时间 - master系统时间 )
(slave系统时间-master执行最新event的timestamp):得到最新event到slave执行还要多久。
(slave系统时间-master系统时间):可能存在主备系统时间差别,所以计算seconds_behind_master要减去,但实际情况,slave和master系统时间基本一致,得到结果应该接近0
所以seconds_behind_master的值是由于slave系统时间-master执行最新event的timestamp 决定的,当导致循环复制的log event创建时间越久远,slave lag 会越大,执行完 这个event,会执行真正主库执行的log event ,此时slave lag 就会变成0 。

三 解决
  
查看新主库的server_id 
  
   查看新备库的server_id
  
  主库上冲突的事务的server_id
  
 备库上冲突事务的server_id
 
老的主库的server_id
 
 解决方法
 在新的备库更改server_id为冲突数据的server_id,等数据耗完毕,server_id改为原库的server_id。 读者朋友可以思考一下为什么在备库上执行更改server_id的操作?
 
对于MySQL 本身,可以加上一层判断,在复制结构中检查 log envent的server_id是否属于 复制结构中数据库的server_id,如果不是,则判断该事物属于复制风暴事物,予以抛弃 。

四 参考资料
[1] 通过源码解析MySQL Seconds_Behind_Master  
[2] MySQL复制事件在主备之间来回传输检测   
[3] 主备备的两个备机转为双master时出现的诡异slave lag问题 

时间: 2024-12-03 15:38:55

【案例】主从替换之后的复制风暴的相关文章

案例分析:Subaru的媒体风暴

现在回想当年对在线广告活动的策划,真的觉得那是一件相对简单的事情:确认客户的目标受众.选择投放网站.再加入一些电子邮件营销方式和搜索广告,事情就搞定了.很难相信,这在过去就被认为是全面的营销活动,尤其是与现在市场中所提供的全面营销活动相比,更是难以置信.现代数字广告活动的内容不但丰富,具有互动性,而且讲究战术,能够吸引大量观众.现代广告活动有多种投放方式,但也有不同的目的,使用不同的代言人.因此,如果媒体策划者和媒体买家能够在某一平台上改善其在线广告,直到其发挥作用,那么他们一定能够将这一经验推

MYSQL 批量替换之replace语法的使用详解

实际需求中,需要对某张表某字段里面的内容进行批量替换,普通的思考流程如下: SELECT出来str_replace替换UPDATE写入 实际这样极其浪费资源以及消耗资源,MYSQL内置了一个批量替换的语法复制代码 代码如下: UPDATE table SET field = replace(field,'被替换','替换成')  直接就替换了,后面也可以跟WHERE 条件语句 支持多个词同时被替换复制代码 代码如下: UPDATE table SET field = replace(field,

U盘复制文件造成蓝屏的原因

  分析原因: 1.在制作U盘系统引导盘时,格式化为FAT格式; 2.USB1.1的闪存盘读速一般为630KB,写速一般为520KB;USB2.0的读速一般为1.5MB,写速一般为1.0MB; 3.由于操作系统在操作外部磁盘的时候,会开辟一个内存缓存区,许多存取操作实际上是通过这个缓存区完成的; 4.复制的文件大于500M; 总结: 当我们的操作系统在复制大文件时,未考虑到FAT及U盘接口的写入速度,导致文件复制模块缓冲区无法容下大量的数据,且复制过程中得不到有效延迟,因此发生系统蓝屏故障. 解

mysql 5.5中的半同步复制

先来看下MYSQL异步复制的概念:   异步复制:MySQL本身支持单向的.异步的复制.异步复制意味着在把数据从一台机器拷贝到另一台机器时有一个延时 – 最重要的是这意味着当应用系统的事务提交已经确认时数据并不能在同一时刻拷贝/应用到从机.通常这个延时是由网络带宽.资源可用性和系统负载决定的.然而,使用正确的组件并且调优,复制能做到接近瞬时完成.      当主库有更新的时候,主库会把更新操作的SQL写入二进制日志(Bin log),并维护一个二进制日志文件的索引,以便于日志文件轮回(Rotat

使用正则替换变量_javascript技巧

我们使用 str.replace(/s/g,"world") 可以将字符 "s" 替换成 "world" 如果要替换一个变量呢? s = "abc" 怎样将全部 abc 替换成 "world" ? 复制代码 代码如下: str.replace(new RegExp(s,"g"),"world") s 中不要包含正则元字符 否则会产生错误

JavaScript 替换Html标签实现代码_javascript技巧

复制代码 代码如下: str = str.<br /> replace( /&(?!#?\w+;)/g , '&').<br /> replace( /undefinedundefined([^undefinedundefined]*)"/g , '"$1"' ).<br /> replace( /</g , '<' ).<br /> replace( />/g , '>' ).<b

javascript替换已有元素replaceChild()使用介绍_javascript技巧

replaceChild(a,b)是用来替换文档中的已有元素的 参数a:要插入的节点, 参数b:要替换的节点 复制代码 代码如下: var oDiv = document.getElementById("guoDiv"); var oSpan = document.createElement("span"); oSpan.innerHTML = "4"; var firsChild = oDiv.firstElementChild ? oDiv.

RabbitMQ主备复制是异步还是同步?

我们知道RabbitMQ可以配置成Queue做主从复制(按照官方的说法叫配置mirror queue),对master queue的写操作会被复制到其他slave上去(也就是复制到mirror queue上去).这对rabbitmq的这个特性,有些人会问这样的问题,rabbitmq的主从复制是同步的还是异步的? 为什么有些人会问这个问题那?主要这些人往往是将rabbitmq这个主从复制过程和mysql的主从复制做类比.我们知道mysql主从同步是支持同步.半同步.异步3种模式的.采用哪种模式,决

javascript 正则表达式触发函数进行高级替换_javascript技巧

一般情况下我们可能会用到正则表达式去替换文本: 复制代码 代码如下: var a = "abc123aXc"; a.replace(/a.c/g, 'ZZ'); 我们可以用函数来定义高级替换,而不是一个简单的字符串.比如: [/code] 执行结果为: 复制代码 代码如下: www 15bj ten [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行] 我们看到,当正则表达式每产生一次匹配时,会触发替换函数并将匹配字符串作为参数传到替换函数中.当正则表达式中定义了子匹配(subm