Snapshot
agent读取article的信息,将article的内容和脚本放置到snapshot文件夹中; 接下来distribution
agent会读取这些快照文件,传输到订阅,完成初始化操作。期间distribution
agent需要处理很多事情,例如判断快照是否可用,需要应用那些快照文件,传输过程中发生中断怎么办 等等。这些都需要distribution
agent来协调。读完本文之后您会对这些处理方式有所了解,也会帮助您更好地判断当前事务复制的状态以及进行错误排查。

 
 

在此之前,我要先简单地介绍一下distribution
agent的工作方式:

Distribution
agent包含两个进程,reader和writer。 Reader负责从distribution 数据库中读取数据,Writer负责将reader读取的数据写入到订阅数据库.

reader是通过sp_MSget_repl_commands来读取distribution数据库中(读取Msrepl_transactions表和Msrepl_Commands表)的数据

下面是sp_MSget_repl_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 

这个存储过程有6个参数,在Transactional
replication 中,只会使用前4个(并且第三个参数和第四个参数的值是固定不变的.分别为0和10000000)。下面是一个例子:

exec
sp_MSget_repl_commands 46,0x0010630F000002A900EA00000000,0,10000000

 
 

@agent_id表示distribution
agent
id,每个订阅都会有一个单独的distribution
agent来处理数据。 带入@agent_id后,就可以找到订阅对应的publication 和所有的article。

@last_xact_seqno 表示上一次传递到订阅的LSN。

大致逻辑是:Reader读取分发数据库中LSN大于@last_xact_seqno的数据。 Writer将读取到的数据写入订阅,并更新订阅的LSN.( MSreplication_subscriptions表的 transaction_timestamp列)。然后Reader会继续用新的LSN来读取后续的数据,再传递给Writer,如此往复。在sp_MSget_repl_commands 的处理过程中, Msrepl_Commands表(通过type列进行区分)的数据大致分为两种: 1快照产生的数据,2 正常更新产生的数据

 
 

现在基本知识介绍完毕,下面开始进入正题

 
 

 
 

如何判断快照是否可用

 
 

Distribution
agent 会使用存储过程sp_MSsubscription_status(exec sp_MSsubscription_status @agendId)去判断当前快照的状态:

  1. 当创建发布和订阅后,distribution 数据库中MSsubscriptions表的status列为1(Subscribed),
  2. 如果此时运行distribution
    agent,会抛出21075, 21076或21088错误"The initial snapshot for %%  is not yet available".  
  3. 当快照生成后,snapshot
    agent会去更新MSsubscriptions中的status列的状态。当status列的值为2(Actived)时,表示快照已经完成,这样distribution agent就可以正常运行了。不过根据不同的设置,snapshot
    agent会将status列更新为不同的值:
  4. 如果sync_method是concurrent(sql server 2005以及以后版本的默认模式),status的值会变更为3; 如果此时运行distribution agent,会出现下面的21388的错误The concurrent snapshot for publication 'PublicationName' is not available because it has not been fully generated or the Log Reader Agent is not running to activate it. If generation of the concurrent snapshot was interrupted, the Snapshot Agent for the publication. 我们必须运行一下log reader
    agent,运行后, status就被更新为2(active)了. 这样distribution agent就可以正常运行了。
  5. 如果sync_method是native,那么status的值会被直接更新为2,

     
     

    如何应用快照文件

    Snapshot会在快照文件夹或alt_snapshot_folder生成快照文件,那么distribution agent是如何找到这些文件并应用的呢?

    Snapshot agent会将一些信息写入到distribution 数据库中的MSrepl_transactions和MSrepl_commands表中,下面是snapshot产生后两张表的查询截图

    那么这些内容代表什么意义呢?我们可以通过sp_browsereplcmds来查看 ,

    use
    distribution

    go

    exec
    sp_browsereplcmds
    '0x0000001E0000008F001E','0x0000001E0000008F001E' .

    表中的内容包含了snapshot文件的名称和路径, distribution agent就会据这些信息将snapshot应用到订阅数据库中。

     
     

     
     

    如何判断是否需要应用快照

    当一个订阅数据库完成初始化之后,如何避免distribuiton agent下次运行时重复应用快照呢?
    系统表中并没有单独的字段来标记订阅数据库是否已经完成了快照。
    实际上,这些判断逻辑是包含在sp_MSget_repl_commands里的:

    当第一次初始化时,订阅数据库的LSN(MSreplication_subscriptions表的 transaction_timestamp)小于快照文件对应的LSN,这样,所有大于订阅LSN(也包含了快照)的数据都会被同步到订阅。

     
     

    接下来就有个问题了,假设发布添加了一个新的订阅数据库,新的订阅数据库需要distribution agent来帮助其完成初始化快照的步骤。于是生成了一个新的快照,这些快照的xact_seqn肯定是大于已存在的订阅的xact_seqno的。 但对于已经存在的订阅数据库,是不需要应用这些快照的.那么distribution agent是如何处理这种情况的呢?

    实际上sp_MSget_repl_commands除了会比较xact_seqno,还存在额外的判断:订阅对应的每个已发布项目在 MSsubscriptions 表中都会有一行记录。MSsubscriptions 表的subscription_seqno 列表示快照事务序列号;publisher_seqno  列表示该订阅在发布服务器上的事务序列号。如果@last_xact_seqno的值小于这两个值中的任意一个,就表示订阅需要应用快照,否则表示快照已经应用过了,只需要应用后续更新即可。

    当第一次快照生成后,这两个列的值就不会再放生变化了(除非订阅被标记为需要重新初始化),但是订阅数据库的MSreplication_subscriptions表的 transaction_timestamp是不断增加的,所以即使生成新的快照,已存在的订阅也不会受到影响。

     
     

    在应用快照过程中意外中断怎么办?

    假设一共有8个snapshot文件,distribution
    agent已经应用了3个文件,在应用第四个文件的时候OS重启了。 那重启后该如何继续呢? 是否需要全部重新开始呢? 答案是否定的。 在应用snapshot文件的过程中,distribution
    agent会向subscription数据库里的MSsnapshotdeliveryprogress系统表写入数据,每当一个文件成功应用到订阅,就会写入一条数据。如果意外重启,distribution
    agent会根据这张表来判断哪些文件已经被应用过。当所有的snapshot文件都传递到订阅后,distribution会清除表里的内容。  当下面是MSsnapshotdeliveryprogress的查询截图。

事务复制中的snapshot的更多相关文章

  1. 事务复制中的msrepl_ccs

    在事务复制里,如果一个article被更新,distributionagent会调用相应的存储过程将数据更新到订阅端. 这些存储过程分别是[sp_MSins_dboTableName],[sp_MSd ...

  2. 解决服务器复制中SID冲突问题

    解决服务器复制中SID冲突问题 如果你有多部的主机需要安装,最快的方法是什么?想必就是用像GHOST之类的软件来进行硬盘的复制.当然,如果是安装在虚拟机之中,则需要复制虚拟的硬盘档案即可,以微软的VP ...

  3. MySQL主从复制中replicate-ignore-db replicate-wild-ignore-table的应用

    MySQL主从复制中replicate-ignore-db replicate-wild-ignore-table的应用 replicate-ignore-dbreplicate-wild-ignor ...

  4. Spring 下默认事务机制中@Transactional 无效的原因

    Spring中 @Transactional 注解的限制1. 同一个类中, 一个nan-transactional的方法去调用transactional的方法, 事务会失效 If you use (d ...

  5. 复制中的NOT FOR REPLICATION

    错误#1 10:51 2012-9-4sp_MSget_repl_commands 重复键插入解答#1 修改distribution库下sp_MSget_repl_commands 存储过程decla ...

  6. MySQL复制中slave延迟监控

    在MySQL复制环境中,我们通常只根据 Seconds_Behind_Master 的值来判断SLAVE的延迟.这么做大部分情况下尚可接受,但并不够准确,而应该考虑更多因素. 首先,我们先看下SLAV ...

  7. 关于MySQL主从复制中UUID的警告信息

    日期: 2014年5月23日 博客: 铁锚 最近在查看MariaDB主从复制服务器 Master 的错误日志时看到很多条警告信息,都是提示 UUID()函数不安全,可能 Slave 产生的值和 Mas ...

  8. 事务复制5: Transaction and Command

    事务复制使用 dbo.msrepl_transactions 和 dbo.MSrepl_commands 存储用于数据同步的Transaction和Command.在replication中,每个co ...

  9. SQLServer复制(二)--事务代理作业

    之前的一篇已经介绍了如何配置复制,介绍了发布者.分发者和订阅者以及事务日志运行的简单关系.其中提到了复制代理,我们这篇将详细介绍复制代理,它是什么?在事务复制的步骤中起到了什么作用? 代理和工作 首先 ...

随机推荐

  1. Linux操作系统shell与函数详解

    shell和函数的定义 1. linux  shell 函数 将一组命令集或语句形成一个可用的块, 这些语句块称为函数. 2. shell  函数的组成 函数名:函数名字,注意一个脚本中函数名要唯一, ...

  2. 微信商城系统与手机APP的优势对比!

    随着移动互联网的大势到来,手机移动应用已经成为未来的主流市场,很多企业也在投入精力和财力进行研发自己的手机APP,以便更好的迎合市场的需求. 然而当微信公众平台开放以后,新的机会出现了! 很多企业已经 ...

  3. NoteExpress 自定义参考文献输出样式

    最近在写硕士论文,样式中没有符合要求的,于是就自己来编辑下样式文件,下文是网上搜集的关于自定义参考文献的一篇教程,可以参考. 一.分隔符|和连接符*的使用 (1)连接符 * 主要作用是“建立依赖关系” ...

  4. Avizo - 高级三维可视化及分析软件

    今天从材料科学应用角度介绍Avizo的基本功能. Avizo是一款先进的三维可视化及分析应用,可用来探索从断层扫描.显微镜.核磁共振成像及更多其他技术获得的材料科学数据.从简单的可视化与测量到高级的图 ...

  5. Redis & Python/Django 简单用户登陆

    一.Redis key相关操作: 1.del key [key..] 删除一个或多个key,如果不存在则忽略 2.keys pattern keys模式匹配,符合glob风格通配符,glob风格的通配 ...

  6. HBase + Kerberos 配置示例(一)

    用过hbase的朋友可能都有过这样的疑问,我写一个java client,好像就提供了zookeeper quorum地址就连上hbase了,那么是不是存在安全问题?的确是,如何解决?hbase中引入 ...

  7. libevent 安装异常

    有homebrew的可以使用 1 brew install memcached 这个命令来安装没有homebrew的可以直接手动安装1.去官网http://memcached.org/下载最新的包,然 ...

  8. Python 内置彩蛋

    The Zen of Python, by Tim Peters Beautiful is better than ugly.Explicit is better than implicit.Simp ...

  9. 1、Orchard商城开发——开发需求

    需要开发的功能: 1.商品详情,可添加商品属性,如颜色,尺寸等. 2.商品类别,可显示该类别下的所有商品,可按品牌.颜色.尺寸等检索,并可按价格.销量等排序游览. 3.商品游览记录,收藏商品,加入购物 ...

  10. 启动和JQuery绑定--AngularJS学习笔记(二)

    上一篇简单的分析了AngularJS的项目结构,后面就开始分析具体的源代码了. 从angularFiles.js中的定义可以看出有几个文件直接位于src根目录,并不是隶属于某个模块.这几 个分别是mi ...