• Replication 第二篇:转存 Transaction 和 Command


    在事务复制中distribution数据库使用 dbo.MSrepl_transactions 和 dbo.MSrepl_commands 这两个表转存发布服务器产生的的Transaction和Command。每个command只能更新(update,insert或delete)一条记录。在Publisher中,一个Trasaction能够更新Table的一条或多条记录,因此一个Transaction对应一个或多个command,只有当command全部执行成功,transaction才执行成功。

    一, 事务和命令的存储

    事务和命令被读取后,转存到分发数据库中,在分发数据库中做暂时的存储。

    1,转存事务

    在表MSrepl_transactions中存储事务,字段xact_seqno 表示事务的序号,数据类型是 varbinary(16) ,值是递增的。

    默认情况下,在Publisher数据库中提交的一个事务,只有一个xact_seqno,其值是10Bytes,只有当该事务中的所有commands都执行成功,该事务才算执行成功。如果事务被拆分成多个子事务,每个子事务都会有一个xact_seqno,由原有的xact_seqno加上子事务序号构成。例如,有一个事务:0x000B782E000057080006 被拆分成三个子事务,其子事务的序号依次是:

    • 0x000B782E000057080006,占用10B
    • 0x000B782E000057080006000000000001,占用16B
    • 0x000B782E000057080006000000000002,占用16B

    由于xact_seqno的数据类型是varbinary(16),子事务序号:0x000B782E000057080006 和 0x000B782E000057080006000000000000 在逻辑上相同,表示第一个子事务,因此,在dbo.MSdistribution_history记录的xact_seqno都是 16Bytes的。

    2,转存命令

    在表MSrepl_commands中存储命令,各个字段的含义是:

    • 字段xact_seqno 表示命令关联的事务,一个事务可能关联一个或多个Command,
    • 字段 command_id 表示在事务中每个Command的ID值;
    • 字段 command 存储SQL Server的command,数据类型是varbinary(1024);

    如果一个Command 不能存储在一个Command entry中,那么事务复制将其拆分成多个entry。如图,command_id依次增加,字段partial_command字段是1,hashkey的值都是3,表示这四个command是一个Command拆分的。

    二,查看 msrepl_commands 中的SQL语句

    使用 sp_browsereplcmds 能够解析comman的中语句,返回可读的文本。

    sys.sp_browsereplcmds [ [ @xact_seqno_start = ] 'xact_seqno_start' ]
        [ , [ @xact_seqno_end = ] 'xact_seqno_end' ] 
        [ , [ @originator_id = ] 'originator_id' ]
        [ , [ @publisher_database_id = ] 'publisher_database_id' ]
        [ , [ @article_id = ] 'article_id' ]
        [ , [ @command_id= ] command_id ]
        [ , [ @agent_id = ] agent_id ]
        [ , [ @compatibility_level = ] compatibility_level ]

    如果只是粗略地查看Transaction中的 command,可以使用如下脚本,得出的文本大概是:{CALL [sp_MSdel_dboDimUser] (?,?)},实际上,这是在Subscriber DB中执行的SP,用于删除 dbo.DimUser表中的一条数据行。

    SELECT CAST(SUBSTRING(command, 7, 8000) AS NVARCHAR(MAX)),
    FROM dbo.msrepl_commands
    WHERE xact_seqno = 0x0008E9340005C068003E;

    三,延迟问题

    延迟(Latency)问题一般是由于一个Transaction内包含的Command太多,导致Transaction从Publisher推送到distribution,再从distribution 推送到subscriber 的latency高,使用以下脚本查看Command的数量。

    select t.publisher_database_id, 
        t.xact_seqno, 
        min(t.entry_time) as EntryTime, 
        count(c.command_id) as CommandCount
    FROM dbo.MSrepl_commands c with (nolock)
    inner JOIN  dbo.msrepl_transactions t with (nolock)
          on t.publisher_database_id = c.publisher_database_id 
            and t.xact_seqno = c.xact_seqno
    where c.publisher_database_id=2
    GROUP BY t.publisher_database_id, t.xact_seqno
    order by CommandCount desc

    四,Transaction 和 Command 的清理

    当Transaction 和 Command 已经被推送到Subscriber上之后,distribution 中的暂存的Transaction 和 Command 应该被purge,不然会导致distribution 过大,影响后续数据的推送。事务复制使用一个Agent自动清理Transaction和Command。

    参考文档:

    sp_browsereplcmds (Transact-SQL)

    Determine Transactional Replication workload to help resolve data latency

  • 相关阅读:
    了解 DICOM 基本协议与其相关
    C# PropertyInfo 反射实体部分字段
    ref(引用参数) 和 out(输出参数) 区别
    Linq Where Expression<Func<T,bool>> 查询条件
    随笔规范
    C# 集合分析
    C# 几种常用的数据类型
    关于 C# 方法参数的理解
    打算开始写博客了
    有趣的算法、逻辑面试题
  • 原文地址:https://www.cnblogs.com/ljhdo/p/5098809.html
Copyright © 2020-2023  润新知