Step1:向复制伙伴发起请求

假设DC服务器A和B互为复制伙伴,在某个时间点服务器A向B发起复制请求。服务器B会把更新传输给A,这是一个单向的复制过程。没有更新从A传输到B。

除非B向A发起另一个请求开始另一个复制过程。

如果服务器A

服务器A发送的请求中包括5个重要的复制相关的元数据:

1.服务器A希望接受的更新的NC

2.可接收的最大对象数目

3.可接收的最大数量

4.服务器A的High-watermark矢量表中B的USN (方便B对照自己的USN来大概估计有没有和有多少更新,2个USN之差)

5.服务器A的Up-to-Dateness矢量表 (方便B过滤出A上已经有了的更新)

如下图:图2 Initiating replication with Server B for NC xxxx


注意:在对站点链接规划复制时间安排的时候,要考虑到这一点:当一个复制周期开始后,它会一直复制所有的更新

而不管包有多少或者需要多长时间除非网络连接完全中断。你可以指定复制什么时候开始,但是无法指定它什么时候

结束。复制会一直进行直到完成或者DC直接的物理网络连接中断。

Step2:复制伙伴找出需要发送的更新

server B首先找到自己的NC拷贝的最高USN,和A发给自己的HWMV中B的USN比较.

如果有更新,B马上就能知道了。只需比较USN之差。

但是问题是也许B上的某些更新A上已经有了(A可能从其他DC复制了这些更新),如何过滤掉这些A不需要的更新呢?

UTDV起的就是这个作用。

对于每个B将要发送给A的更新,B检查2个数据:Originating-DC-GUID和Originating-USN.

例如用户密码的修改在D上,在B的UTDV中,原始修改DC是D,原始DC相应的USN=2345.

B检查A发送的UTDV,如果发现 UTDV中server D的USN>=2345,那说明A上已经有这个更新了。


假定B已经有4个更新相对于A如下图:1个原始写和3个复制写。

A发来的HWMV(水印)中B的最高USN为1108. 所以更新应该从1109-1112.



Potential updates to be sent

Server B USN

Originating DC GUID

Originating DC USN

1109

Server E's GUID

567

1110

Server E's GUID

788

1111

Server B's GUID

1111

1112

Server D's GUID

2345

根据图2,A已经有了serverD的2345更新,因为A的UTDV中D的USN是2350.因此A和B都已经有了D上的2345更新。

所以没有必要浪费带宽去再次发送一次了。

那么具体B是如何筛选出需要发生的数据的呢?

当B收到A的请求时,它拷贝一份A发过来的的UTDV,建立一个表,然后搜索整个NC,查找所有对象的usnChanged属性值,

如果该值大于A发送的HWMV(高水印)中B的USN,就列入表中。该表按usnChanged大小升序排列

接下来,server B建立一个空的输出缓冲区用来存放将要发生给A的更新条目。

同时B也初始化一个称作Last-Object-USN-Changed的值。这个值用来表示复制过程最后发送的对象的USN.

这个值不是任何对象的属性,只是一个传输数据。serverB 接着枚举升序排列的表中的对象,使用以下算法对每个对象计算一番:

1.如果对象已经在输出缓存区,server B就设置Last-Object-USN-Changed为该对象的usnChanged属性值,然后计算下一个对象。

2.如果对象还没有加入缓冲区,server B就测试对象看是否它包含了需要被发送的更新。对于对象的每个属性,server B

检查其原始写的DC-GUID然后查找A发过来的UTDV中相应的DC所对应的USN,与属性的原始USN比较,

如果大于A的UTDV表中的USN值,那么这个属性就应该被发送,更新条目被加入到输出缓冲区。

server B设置Last-Object-USN-Changed值为当前对象的usnChanged值。之后继续下一个

如果没有更新要发送,就设置Last-Object-USN-Changed值为当前对象的usnChanged值,继续下一个。


在此过程中,如果达到A所要求的请求限制(对象更新数量或者最大值),则提前终止,一个标记

More-Data被设置为真。反之则为假。


Step3:复制伙伴传输更新给发起服务器(B到A)

B将更新发生给A,如果more-data=false,一个额外的metadata将被发送。

B发送如下信息给A

1.B的输出缓冲区的内容

2.B的Last-Object-USN-Changed值

3. More-Data 标记

4.B的up-to-date 矢量(当more-data=false时发送)

如图:

Server B sends the updates to Server A for NC xxxx


当B计算出A已经更新过了而不需要从B得到更新了,那么只有后2项发送给A.

这一般发生在如下情形:

1.B的最高USN和A发送过来的HWMV(高水印)中B的USN一样--例如没有更新发生自上次更新后

2.B的最高USN已经改变了,但是A已经从其他复制伙伴得到了所有B已知的原始更新。




If Server B calculates that Server A is already up to date and requires no updates, only the last two pieces of metadata are returned to Server A. This can occur if the highest committed USN for the NC on Server B is identical to the HWMV entry passed by Server A; i.e., no updates have occurred since the last replication cycle. This also can occur if Server B's highest committed USN for the NC has changed but Server A has already seen all of the originating updates through replication with other partners. In both cases, just the metadata is returned.




Step 4. 发起服务器处理更新 A处理更新

A逐条更新从B得到的数据,根据分配的事务号修改每个对象的usnChanged的属性。

之后A的HWMV(高水印表)中的B的值设置为Last-Object-USN-Changed--(从B得到的)

换句话说,A现在知道了它和B更新到一样的了

上个例子中,server B的USN 1112没有发生给A,因为A已经有该更新,但是

Last-Object-USN-Changed仍然是1112而不是1111.


Step5. 发起服务器检查是否达到更新状态

A检查more-Data状态,如果=ture,继续步骤1.

如果=false,所有更新应该都从B收到了。最后A的up-to-dateness矢量也会自我更新。

A逐条检查收到的UTDV表条目然后做2件事情:

1.如果一个服务器条目没有列在自己的UTDV中,则增加该条目--A知道有了新的服务器。

2.如果条目存在,并且收到的值更大,则用新的值修改现有的UTDV。

最后,A被更新了,并且有比B更好的记录。


Table 5-2. State of UTDV and HWMV for Server A before and after updates

HWMV for Server B

Server B UTDV

Server C UTDV

Server D UTDV

Server E UTDV

Before step 1

1108

1108

100

2350

540

After step 5

1112

1111

100

2350

790

总结:

1.HWMV(高水印值)矢量用于检查哪些更新需要发送

2.UTDV矢量用于筛选出发起服务器没有见过的更新。

3.每个对象上的usnChanged属性用于标识哪些对象需要被作为更新发送。


note:DC上可以强制更新


复制冲突解决:


1.对象建立时名字冲突:

版本号>时间戳>原始写DC的GUID

未赢得的对象不会丢失或者删除,而是被修改为一个已知的统一值。最终,2个对象都存在,

只是其中一个的冲突的名字改为统一值。这个统一值如下组成:objectname lineFeed CNF: objectGUID

2.同一属性修改

版本号>时间戳>GUID

所有的复制元数据的时间戳都是GMT时间

3.在一个正在删除的父容器下移动或者建立对象

父容器被删除,对象被移动到lost and found 容器。