Distribution1:Distribution Reader

在transactional replication中,在publication中执行了一个更新,例如:update table set col=? Where ?,如果table中含有大量的数据行,那么该操作会产生大量数据更新操作。在subscription端,这个更新操作会分解成多条command(默认情况下产生一个Transaction,每个数据行产生一个Command)。Distribution Agent包含两个子进程,Reader和Writer。 Reader负责从 Distribution 数据库中读取数据,Writer负责将reader读取的数据写入到订阅数据库。Reader是通过 sys.sp_MSget_repl_commands 来读取Distribution数据库中(读取Msrepl_transactions表和Msrepl_Commands表)的数据。

CREATE PROCEDURE sys.sp_MSget_repl_commands
(
@agent_id int,
@last_xact_seqno varbinary(16),
@get_count tinyint = 0,  -- 0 = no count, 1 = cmd and tran (legacy), 2 = cmd only
@compatibility_level int = 7000000,
@subdb_version int = 0,
@read_query_size int = -1
)

1,在Distribution Agent同步数据到Subscriber中时,发现Subscriber中有很多Session处于 ASYNC_NETWORK_IO,说明该Session返回的数据集太大,导致Writer不能及时将Command读取,使用Distribution Latency增加,该Session正在执行的sp是:sys.sp_MSget_repl_commands,正在执行的语句如下,这条查询用于返回Distribution Agent读取的Commands。

select rc.xact_seqno, rc.partial_command, rc.type,
        rc.command_id, rc.command, rc.hashkey,
        -- extra columns for the PeerToPeer resultset
        -- originator_id, srvname, dbname, originator_publication_id, originator_db_version, originator_lsn
        NULL, NULL, NULL, NULL, NULL, NULL, rc.article_id
        from
            MSrepl_commands rc with (nolock, INDEX(ucMSrepl_commands))
            JOIN dbo.MSsubscriptions s with (INDEX(ucMSsubscriptions))
            -- At end, we use the FASTFIRSTROW option which tends to force
            -- a nested inner loop join driven from MSrepl_commands
            ON (rc.article_id = s.article_id)
        where
        s.agent_id = @agent_id and
        rc.publisher_database_id = @publisher_database_id and
        rc.xact_seqno > @last_xact_seqno and
        rc.xact_seqno <= @max_xact_seqno and
        (rc.type & @snapshot_bit) <> @snapshot_bit and
        (rc.type & ~@snapshot_bit) not in ( 37, 38 )
        and (@compatibility_level >= 9000000
                or (rc.type & ~@postcmd_bit) not in (47))
        order by rc.xact_seqno, rc.command_id asc
        OPTION (FAST 1)

通过SQL Server Profile抓取当前正在执行的SQL,从抓取的大量语句中发现,一般只会用到前四个参数,第三个和第四个参数的值是固定不变的,分别是0和10000000。

exec sp_MSget_repl_commands 74,0x0008ECE200307E10014C00000000,0,10000000

2,Distribution Agent 读取的Commnd数量

sys.sp_MSget_repl_commands 返回的Result Set的大小跟变量 @max_xact_seqno 有关

rc.xact_seqno > @last_xact_seqno and rc.xact_seqno <= @max_xact_seqno

对变量 @max_xact_seqno 的赋值,是由 @read_query_size 参数控制的,在调用该sp时,其值是默认值-1。下面代码表示 将 dbo.MSrepl_commands 最大的 xact_seqno 赋值给变量@max_xact_seqno,那么Distribution Agent 每次都会读取所有的Command。

--Note4: The max_xact_seqno is calculated based on the @read_query_size parameter ---       this parameter limit the number of commands retrieved by this call.     if(@read_query_size <= 0)
    begin
        select @max_xact_seqno = max(xact_seqno) from MSrepl_commands with (READPAST)
          where
             publisher_database_id = @publisher_database_id and
             command_id = 1 and
             type <> -2147483611
    end
    else
    begin
         -- calculate the @max_xact_seqno from the next @read_query_size commands.
         declare @GetMaxCommand nvarchar(1024)
         select @GetMaxCommand = N‘select top ‘ + convert(nvarchar(1024),@read_query_size)+
         N‘ @max_xact_seqno = xact_seqno from MSrepl_commands with (READPAST)
         where
             publisher_database_id = @publisher_database_id and
             type <> -2147483611 and
             xact_seqno > @last_xact_seqno
             order by xact_seqno, command_id asc‘ 

             exec sys.sp_executesql
                     @GetMaxCommand,
                     N‘@max_xact_seqno varbinary(16) output ,@last_xact_seqno varbinary(16),@publisher_database_id int‘,
                     @publisher_database_id = @publisher_database_id,
                     @max_xact_seqno = @max_xact_seqno output,
                     @last_xact_seqno=@last_xact_seqno         

             if(@max_xact_seqno is null)
                select @max_xact_seqno = @last_xact_seqno
    end

3,为@read_query_size传递一个参数值,而不是使用默认值 -1,由于该sp是system stored procedure,不能直接修改,而Distribution Agent profile中也没有参数能够控制Reader读取的Command数量。

参考文档:

SQL Server复制系列4 – Transactional replication中如何跳过一个事务

发布订阅延迟故障排查案例:分发读进程延迟

时间: 2024-10-13 13:36:33

Distribution1:Distribution Reader的相关文章

Distribution2:Distribution Writer

Distribution Writer 调用Statement Delivery 存储过程,将Publication的改变同步到Subscriber中.查看Publication Properties->Ariticle Properties->Statement Delivery 属性,Distribution Writer调用Insert,Update 或 Delete 存储过程,实现数据的同步. Distribution Writer不是每一个Command单独提交,而是根据Commit

简单的Windows Webcam应用:Barcode Reader

原文:简单的Windows Webcam应用:Barcode Reader 在Windows上用WinForm创建一个Webcam应用需要用到DirectShow.DirectShow没有提供C#的接口.如果要用C#开发,需要创建一个桥接DLL.Touchless SDK是一个免费开源的.NET库,对DirectShow进行了简单的封装.使用Touchless可以很方便的在WinForm应用中调用camera.这里分享下如何创建一个调用webcam的barcode reader. 参考原文:Wi

2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest D:Distribution in Metagonia(构造)

http://codeforces.com/gym/100801/attachments 题意:给出一个数n(1 <= n <= 1e18),将 n 拆成 m 个整数,其中 m 必须是 2^x * 3^y 的形式,并且 x 和 y 不能被彼此整除, 输出 m 并将这些整数输出. 思路:Inspired by http://blog.csdn.net/snowy_smile/article/details/49852091 . 第一步:因为要求的 m 是 2^x * 3^y 的形式,所以如果 n

镜像切换Logreader Agent报错:分发数据库中可能存在不一致的状态

软件环境:Windows Server 2008 R2 sp1    SQL Server 2008 R2 sp2 架构:ServerA(主体)+ServerB(镜像)+ServerSub(订阅)+ServerDist(分发) 特别注意:ServerDist分发服务器为单机,故开启了Sync_With_Backup选项. 关于Sync_With_Backup: 初衷:简单来说,开启该选项,使得单机分发库在宕机时,利用最近的系统数据库和用户数据库备份,还原到一台新的服务器上,即可使复制继续工作成为

sqlserver distribution分发alwayson搭建

SqlServer的复制订阅组建中,分发服务器是一个关键的隐患点,现在将分发distribution变成alwayson高可用模式. 发布:TEST125 distribution1 : TEST177 distribution2 : TEST178 订阅:TEST129 TEST177/178 建立分发,过程略. 添加发布服务器,过程略. TEST125配置分发TEST177并建立发布test  -- (过程)--TEST177 job TEST125-test-1 --logreader T

【程序员眼中的统计学(7)】正态分布的运用:正态之美

正态分布的运用:正态之美 作者 白宁超 2015年10月15日18:30:07 摘要:程序员眼中的统计学系列是作者和团队共同学习笔记的整理.首先提到统计学,很多人认为是经济学或者数学的专利,与计算机并没有交集.诚然在传统学科中,其在以上学科发挥作用很大.然而随着科学技术的发展和机器智能的普及,统计学在机器智能中的作用越来越重要.本系列统计学的学习基于<深入浅出统计学>一书(偏向代码实现,需要读者有一定基础,可以参见后面PPT学习).正如(吴军)先生在<数学之美>一书中阐述的,基于统

[JAVA设计模式]第三部分:结构模式

声明:原创作品,转载时请注明文章来自SAP师太博客,并以超链接形式标明文章原始出处,否则将追究法律责任! 结构模式... 52 适配(Adapter)器模式... 52 类适配器模式结构... 52 对象适配器结构... 53 从Iterator到Enumeration的适配... 54 从Enumeration到Iterator的适配... 54 缺省适配(Default Adapter)器模式... 55 模式结构... 56 与适配器模式区别... 56 J2EE中的缺省适配模式... 5

常用输入字符流Reader

Reader是用于输入字符数据的,它所根据的 方法跟InputStream基本一样.它是所有输入字符流的抽象父类,因此不能直接构建Reader的实例,必须通过它的子类来构建.以下是几个常用的子类: 1.字符数组作为输入源--CharArrayReader CharArrayReader包含一个内部缓冲区,该缓冲区包括从流中读取的字符数组.所谓内存缓存区,就是对应了内存中存在的字符数组,因此可以根据字符数组来创建该类的实例.它有以下两个构造函数: CharArrayReader(char[] bu

5. IO流:★★★★★

IO流:★★★★★,用于处理设备上数据. 流:可以理解数据的流动,就是一个数据流.IO流最终要以对象来体现,对象都存在IO包中. 流也进行分类: 1:输入流(读)和输出流(写). 2:因为处理的数据不同,分为字节流和字符流. 字节流:处理字节数据的流对象.设备上的数据无论是图片或者dvd,文字,它们都以二进制存储的.二进制的最终都是以一个8位为数据单元进行体现,所以计算机中的最小数据单元就是字节.意味着,字节流可以处理设备上的所有数据,所以字节流一样可以处理字符数据. 那么为什么要有字符流呢?因