Learn how AD prevents endless replication loops

In "Tracking AD Replication," November 2001, I explained how Active Directory (AD) uses update sequence numbers (USNs) to track changes to each domain controller's (DC's) copy of AD's contents. Each server remembers the most recent USN that the server obtained from its replication partners (i.e., the high watermark) and uses that USN to control replication. For example, DC1 might say to DC2, "Tell me what updates you've made since your USN 10,000."

When an administrator creates a new user account on DC1, that update increments DC1's USN, causing DC2 to request the AD changes associated with that update. But when DC2 incorporates that update and increments its own USN, DC2's new USN leads DC1 to request an update from DC2—including the new user account, which DC1 already knows about. Recording that update would lead to an endless cycle of rerecording the same piece of information.

To prevent changes from cycling indefinitely, AD remembers not only the local USN that generates an update but also the globally unique identifier (GUID) of the DC that originated the update. Thus, AD can differentiate between an update that an originating DC generates and one that a DC merely passes to another DC. Every DC remembers not only the latest USN received from each replication partner but also the USN associated with the most recent update originating from every other DC in the domain. The table that contains the latest originating USNs is called the up-to-date vector.

DCs use the up-to-date vector to prevent infinite update loops. Suppose that the last originating update that DC2 received from DC1 was USN 9871 and the last update that DC2 originated was USN 1500. DC2 says to DC1, "Tell me about the updates you've received since you last updated me, but skip any that originated with DC1 and had a USN of 9871 or less and any that originated with DC2 and had a USN of 1500 or less." Suppose that DC1 had one new update, with a USN of 10,001. When DC1 sends that update to DC2, DC2 saves the information as USN 1553 but also remembers that the originating USN was 10,001 and that the update originated on DC1. DC2 increases its up-to-date vector entry for DC1 to 10,001. (DC1 also modifies its up-to-date vector to show that DC1's up-to-date vector is 10,001.)

When DC1 next asks DC2 for updates, DC1 says "I know about your updates through your USN 1552, and I've seen every update that originated with DC1 through USN 10,001 and every update that originated with DC2 through USN 1500. Do you have any newer updates?" DC2 sees that it has a USN greater than 1552, but that the originating DC was DC1 and the originating DC's USN was 10,001. Because DC1's up-to-date vector includes all DC1's originating entries through USN 10,001, DC1 knows about DC2's USN 1553 and doesn't record a new update.

You can use the Repadmin /showvector command to view a DC's up-to-date vector. To dump the vector for dc1.acme.com in a domain called acme.com, you'd type

repadmin /showvector
  dc=acme,dc=com
  dc1.acme.com

Figure 1 shows some sample output. Note that the last line shows a GUID rather than a DC name: After you decommission a DC, its entries still appear in other DCs' up-to-date vectors, but the entries appear under the former DC's GUID rather than a DC name.