事务复制5: Transaction and Command

简介:

事务复制使用 dbo.msrepl_transactions 和 dbo.MSrepl_commands 存储用于数据同步的Transaction和Command。在replication中,每个command只能更新(update,insert或delete)一条record;而在Publisher中,一个Trasaction能够更新Table Article的一条或多条Record,因此一个Transaction对应一个或多个command,只有当command全部执行成功,transaction才执行成功。

一, 事务和命令的存储

1,存储事务

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

默认情况下,在Publisher database中提交的一个事务,只有一个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的中语句,返回可读的文本。

sp_browsereplcmds Returns a result set in a readable version of the replicated commands stored in the distribution database。

复制代码
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高。

Latency problems are often caused when series of transactions are trying to move a large batch of commands from the Publisher to the Distributor to the Subscribers. 

使用以下脚本查看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 的cleanup

当Transaction 和 Command 已经被推送到Subscriber上之后,distribution 中的暂存的Transaction 和 Command 应该被purge,不然会导致distribution 过大,影响后续数据的推送。Replication 使用“Distribution clean up: distribution” Removes replicated transactions from the distribution database.

 

参考文档:

sp_browsereplcmds (Transact-SQL)

Determine Transactional Replication workload to help resolve data latency

 

作者悦光阴
本文版权归作者和博客园所有,欢迎转载,但未经作者同意,必须保留此段声明,且在文章页面醒目位置显示原文连接,否则保留追究法律责任的权利。
分类: Replication





本文转自悦光阴博客园博客,原文链接:http://www.cnblogs.com/ljhdo/p/5098809.html,如需转载请自行联系原作者
目录
相关文章
|
7月前
|
SQL 关系型数据库 MySQL
MySQL数据库——事务操作-begin-commit-rollback
MySQL数据库——事务操作-begin-commit-rollback
66 1
|
Java 关系型数据库 MySQL
定时任务Quzrtz:Failed to override connection auto commit/transaction isolation
定时任务Quzrtz:Failed to override connection auto commit/transaction isolation
161 0
|
缓存 Oracle 关系型数据库
Oracle中控制commit的三个参数 commit_write, commit_logging和 commit_wait
Oracle中控制commit的动作有三个参数 commit_write, commit_logging和 commit_wait,按重要性分别说明如下
316 0
SAP RETAIL 执行事务代码WRP1,报错-Transaction WRP1 cannot be executed-
SAP RETAIL 执行事务代码WRP1,报错-Transaction WRP1 cannot be executed-
SAP RETAIL 执行事务代码WRP1,报错-Transaction WRP1 cannot be executed-
|
SQL 存储 数据库
处理令人心烦的数据库事务日志 (SQL Server Transaction Log Files)
经常, 我们会被过快增长的数据库事务日志Transaction Log而困扰, 如果我们没有正确及时的处理, 可能会造成数据库交易无法进行, 服务器磁盘空间占光等问题. 在SQL Server的使用过程中, 我经常帮助用户和数据库的维护人员处理日志Transaction Log太大后造成的系统瘫痪的问题. 其实这个问题很容易避免. 今天我给大家分享下, 是什么造成了日志增长过大的问题. 和如何避免这种问题再次发生. 该文章的语句适用于SQL Server 2015 及其以后的版本 每一个数据库至少有两个文件: 一个是数据文件(Data file), 一个是事务日志文件(Transaction
829 0
|
SQL 安全
二十三:从库的SQL 线程(MTS协调线程)和sql_slave_skip_counter参数(笔记)
一、调用流程大概如下 handle_slave_sql ->是否开启了slave_preserve_commit_order和log_slave_updates参数,开启的话需要设置提交顺序管理器 if (opt_slave_preserve_commit_order && rli->op...
1060 0
|
SQL 关系型数据库
slave复制中断 ,别滥用SQL_SLAVE_SKIP_COUNTER
slave复制中断 ,别滥用SQL_SLAVE_SKIP_COUNTER 来源:http://blog.chinaunix.net/uid-26364035-id-3588217.html 【问题背景】  1、从库的复制出现中断,如主键冲突;对应的表或者库不存在;基于row复制时,操作的行不存在; 常常大家会通过使用set global SQL_SLAVE_SKIP_COUNTER=n 来跳过导致复制错误的SQL.  2、 使用sql_slave_skip_counter跳过,每一次跳过为一个Binlog event group, 也就相当于一个事务。
1798 0