zoukankan      html  css  js  c++  java
  • Replication的犄角旮旯(七)-- 一个DDL引发的血案(下)(聊聊logreader的延迟)

    《Replication的犄角旮旯》系列导读

    Replication的犄角旮旯(一)--变更订阅端表名的应用场景

    Replication的犄角旮旯(二)--寻找订阅端丢失的记录

    Replication的犄角旮旯(三)--聊聊@bitmap

    Replication的犄角旮旯(四)--关于事务复制的监控

    Replication的犄角旮旯(五)--关于复制identity列

    Replication的犄角旮旯(六)-- 一个DDL引发的血案(上)(如何近似估算DDL操作进度)

    Replication的犄角旮旯(七)-- 一个DDL引发的血案(下)(聊聊logreader的延迟)

    Replication的犄角旮旯(八)-- 订阅与发布异构的问题

    Replication的犄角旮旯(九)-- sp_setsubscriptionxactseqno,赋予订阅活力的工具

    ---------------------------------------华丽丽的分割线--------------------------------------------

    前言:这是昨天刚刚发生的案例,尽管事件的起因只是一个简单的DDL操作,但影响面和影响时间可以说是大大超出了预期;我们将在描述本案例的前因后果之后,聊聊如何近似估算DDL的操作进度,以及关于logreader延迟的问题;

    前一篇文章《Replication的犄角旮旯(六)-- 一个DDL引发的血案(上)(如何近似估算DDL操作进度)》

    http://www.cnblogs.com/diabloxl/p/3844205.html

    前因简述:

    一个复制节点(即使上级的订阅,又是下级的分发)需要对一个表进行DDL操作,由于需要修改主键,因此将这个表从publication中删除,然后就开始了漫长的DDL操作……

    本来需要进行DDL操作的表已经从replication中摘除了,以为不会影响到其他article的复制,结果惨剧还是发生了,原因依旧是VLF对logreader的影响,但这次的问题和以往又有些不同……

    =====================华丽丽的分割线=====================

    先说说之前遇到的logreader延迟的情况:

    1、发布表的写操作

      这里又分为两种情况

      a)大量并发写操作:指大量的小DML操作,特点是事务小、并发多

      b)大事务写操作:指有单个大事务操作,特点是事务大、并发少

    2、非发布表的写操作

      指有写操作的表并不是需要复制的表,这里将上述a两种情况合并在一起说,这次遇到的是b这个类型;

    检查logreader的延迟的利器——sp_replcounters

    MSDN上关于这个存储过程的解释:

    http://msdn.microsoft.com/zh-cn/LIBRARY/ms190486

    无论对于上述哪种情况,如果Replicated transactions持续增加,那就是logreader延迟了,初步的现象就是这个发布下所有的订阅都在延迟;

    那上述3种情况的差异呢?

      对于1a) 

      Replicated transactions快速增加,replbiginlsn和replnextlsn都会较慢速度的变化;(这里的慢速是相对与正常速度而言,受实际业务环境影响,下同)

      这是由于大量的小DML操作都会快速的提交,但由于大量的日志写入,导致存在大量的活动VLF,因而日志不能被截断;同时,尽管logreader根据replnextlsn去定位下一个要复制的lsn,但由于效率下降,且后面涌入的新事务也在增长,导致恶性循环,从而引起logreader的延迟;

      对于1b)

      Replicated transactions慢速增加,replbiginlsn不变、replnextlsn不变;

      虽然事务并发量很小,但由于单个提交的事务很大,仍然导致大量的活动VLF,从而引起logreader效率下降;

      对于2

      Replicated transactions快速增加,replbiginlsn不变、replnextlsn慢速变化;

      由于非复制的表也需要写日志,且占用了大量VLF,因此logreader需要从大量的VLF中获取需要复制的日志信息,这也同样影响到它的执行效率;

    那我们该如何应对呢?

      硬件当然是最有效的手段之一,升级内存、磁盘换成IO卡等可以解决根本问题,但这又不是绝对,一个SQL跑死服务器的情况也绝非不可能;

      1、对于1a的情况,建议有频繁写操作的表,还是能分就分,或者分到多个库中,或者分到多个实例下,原则就是不要让logreader干太多活,毕竟的是个单线程的任务,穿少了也cool,喝多了也吐。

      2、对于1b的情况,本身单个大事务就不是OLTP环境中提倡的,不光是复制延迟,光一堆锁估计机器也受不了;建议拆成多个事务来跑;

      3、对于2来说,尽管要搞的表和复制没有任何关系,但不能忽略VLF对logreader的影响,既然在一个库中,公用日志序列,还是小心为妙;如果是大表的DDL的操作,还是通过停写、建新表、导数据的方法实现,bulk insert的方式或许是对日志影响最小的;

      但bulk insert的方式一般要求停写,而受业务的制约,可能不允许长时间的停写,这该怎么破?

      可以看看我之前的文章《Replication的犄角旮旯(一)--变更订阅端表名的应用场景》,复制回路可以说是为这种需求量身定做的~

  • 相关阅读:
    C语言I博客作业02
    第一次作业
    C语言I博客作业07
    C语言I博客作业06
    C语言I博客作业05
    C语言I博客作业04
    C语言I博客作业03
    C语言I博客作业02
    课程目标
    具体方面
  • 原文地址:https://www.cnblogs.com/diabloxl/p/3844504.html
Copyright © 2011-2022 走看看