5. Update Sequence Numbers
Version numbers have siblings, called update sequence numbers
(USNs), which measure the increments of every change to every attribute
of every object within Active Directory. That is to say, whenever any
change is made within Active Directory, a domain controller increments
its current USN by 1. For example, if you have a pristine domain
controller and you add a user with an initial password (update 1),
change his password (update 2), add another user (update 3), create a
new group (update 4), and put the first user in that group (update 5),
the USN for that domain controller would be 5. Keep in mind that version
numbers coexist with USNs; let's look at the information in Table 1
to see how USNs and version numbers interact in the preceding example.
(Note that the table assumes we're talking about a domain with only one
domain controller; it gets a bit more complicated when you add more
domain controllers, and I'll discuss that later in this section.)
Table 1. Examining version numbers and USNs in Active Directory
Action | Attribute version number | Update sequence number (USN) |
---|
Create New User | All attributes are 1 because the operation is seen as one cohesive change. | 0 |
Change Password | Password attribute for that user is 2. | 1 |
Create New User | All attributes are 1. | 2 |
Create New Group | All attributes are 1. | 3 |
Add User to Group | Group membership attribute is 2. | 4 |
From this table, you
can glean that version numbers are incremented only when attributes
change. We changed the password for our first user, so the version
number for that attribute became 2, and we added that user to our newly
created group, so the version number for the attribute containing the
member list for that group increased to 2. But all the while, the USNs
were incrementing because USNs measure every individual change. Our USNs
went from 0 to 4 because (a) USNs start at 0, not 1, and (b) five
individual changes were made.
Note that earlier I said
this scenario revolved around a single domain controller. Let's change
that now: if we were to add a domain controller to this example domain,
the domain controllers would attempt to replicate with each other. Let's
assume that once a domain controller is added, our two accounts and one
group are transmitted immediately. The version numbers and USNs, as
seen on the new domain controller, would shape up as shown in Table 2.
Table 2. Examining version numbers and USNs with two domain controllers
Object | Attribute version number | Update sequence number (USN) |
---|
User 1 | All attributes are 1 except for the Password attribute, which is 2. | 0 |
User 2 | All attributes are 1. | 1 |
Group | All attributes are 1 except for the membership list attribute, which is 2. | 2 |
We learn two things from this table:
Version numbers
of attributes are retained across replications, so around the directory,
no matter which domain controller you access, version numbers for
attributes are the same. This is critical to the functioning of
replication in Active Directory.
USNs
are independent to each domain controller. In our first example, there
were five changes because we were adding and changing things
individually on that first domain controller. Because the second domain
controller was brand new, it created the user accounts and group from
the up-to-date and already changed information on the first domain
controller, so it needed to denote only three changes (the creation of
each account and the creation of the group).
USNs really act as "signatures"
showing the timeliness of information in each domain controller's copy
of the directory, and essentially guide a domain controller's
replication partners as to exactly how much updating is needed to fully
replicate. Each domain controller tells its replication partners the
USNs it has assigned to each piece of data, and the partner domain
controllers keep track of this. The partners then know that the last
piece of data they received—for example, from domain controller X—had a
USN of 6093, and they can then tell domain controller X upon the next
replication to start transmitting data with a USN of 6094 (one number
higher than the last USN) or more. There is no need to send USNs 1–6093
again, as they already possess that data. If the USNs haven't changed on
domain controllers during the regular five-minute breaks from
replication, domain controllers assume that no new information is
available, and they go back to "sleep" for another five minutes. On the
other hand, if domain controller X's replication partners contact domain
controller X and ask for its highest USN, and it replies with 7000, the
partners know they need the last six pieces of information, and those
will then be replicated. Then the partners would make a note that domain
controller X's highest USN is now 7000, and everyone is secure in the
knowledge that they have the most current directory possible for at
least the next five minutes.
So, let's return to the example and see where we are with version numbers and USNs. Table 3 will sum that up.
Table 3. USNs and version numbers
Domain Controller 1 | Domain Controller 2 |
---|
Object | Attribute version numbers | Highest USN | Object | Attribute version numbers | Highest USN |
---|
User 1 | All attributes are 1 except for the Password attribute, which is 2. | 4 | User 1 | All attributes are 1 except for the Password attribute, which is 2. | 2 |
User 2 | All attributes are 1. | | User 2 | All attributes are 1. | |
Group | All attributes are 1 except for the Membership List attribute, which is 2. | | Group | All attributes are 1 except for the Membership List attribute, which is 2. | |
Now consider
this scenario: an administrator changes the password for User 2, and
that administrator is currently using domain controller 1. That change
would be assigned USN 5 because it's the sixth change that domain
controller has seen. Five minutes later, replication is initiated, and
domain controller 2 queries domain controller 1 for its highest USN,
which it tells domain controller 2 is 5. Because domain controller 2
thinks the highest USN for domain controller 1 is 4, it knows it has
missed a change, so it asks for the new information. The new password is
pushed along, and the change on domain controller 2 is assigned a USN
of 3 (it is a
unique change, after all). Then domain controller 2 makes a note of
domain controller 1's new highest USN, domain controller 2 is up to
date, and everyone is happy.
They're happy,
that is, until a few minutes later, when domain controller 1 asks domain
controller 2 what its highest USN is. Domain controller 2 will
faithfully reply that it is 3, and domain controller 1 will know that
figure is higher than its recorded high USN for domain controller 2
(which is 2, as shown in Table 5-4).
However, that change is the original change pushed through from domain
controller 1 to domain controller 2. The domain controllers don't know
that, however, just from looking at USNs, so they push through the
replication, and domain controller 1's highest USN now becomes 6 because
of this "change." Five minutes later, the entire process starts again,
with this one change being propagated over and over and over again, in
an infinite loop.
5.1. Breaking the loop: originating USNs and UTD vectors
How does one cure this? Microsoft identified this problem and introduced two other values to the mix, called originating USNs and up-to-date vectors,
specifically to prevent this situation from occurring. Originating USNs
simply keep track of the domain controller from which a change was
initially transmitted, and the USN on that domain controller. So, when
we first introduced the brand-new domain controller into our example
domain and a copy of the directory was first replicated, more
information was transmitted than I discussed earlier. Table 5-5 contains a more detailed representation of the results of that replication than Table 3 does because it includes originating USNs.
Table 4. Examining version numbers, USNs, and originating USNs
Object | Attribute version number | Update sequence number (USN) | Originating domain controller | Originating domain controller's USN |
---|
User 1 | All attributes are 1 except for the Password attribute, which is 2. | 0 | Domain controller 1 | All attributes except for Password 0; Password 1. |
User 2 | All attributes are 1. | 1 | Domain controller 1 | All attributes 2. |
Group | All attributes are 1 except for the Membership List attribute, which is 2. | 2 | Domain controller 1 | All attributes except for membership list 3; membership list 4. |
In essence,
originating USNs tell all domain controllers where information first
came from and what USN that first domain controller assigned to each
piece of data. But just as domain controllers keep track of the highest
USNs for their replication partners, they also keep track of the highest
originating USN they have ever come across from any and all domain
controllers. This table of maximum originating USNs is known as the
up-to-date vectors. Let's look at this more closely.
Our situation now is shown in Table 5.
Table 5. Example USNs, originating USNs, and UTD vectors
| | | Up-to-date vectors |
---|
Domain controller | Highest USN | Partner's highest USN | Self | Partner |
---|
1 | 4 | 2 | 4 (from domain controller 1) | 2 (from domain controller 2) |
2 | 2 | 4 | 2 (from domain controller 2) | 4 (from domain controller 1) |
I just formulated the up-to-date vectors shown in Table 5-6
in my mind; all they represent is the latest originating USN that each
domain controller knows from the other domain controller. Now, flip back
a couple of pages and refresh yourself on the scenario that previously
would have created an infinite loop: a change of User 2's password, made
by an administrator attached to domain controller 1. Domain controller 1
gives this change a USN of 5, and consequently domain controller 1
updates its table of up-to-date vectors with the highest originating USN
that it knows from itself—so, it changes from 1 (our arbitrary first
number) to 5.
Replication is
initiated once again, and domain controller 2 asks domain controller 1
if it has any new information higher than USN 4, which it knows is its
partner's highest USN, and
whether the originating USNs are higher than 1 for domain controller 1,
and 1 for domain controller 2. Domain controller 1 checks its copy of
the directory and finds the password change, and then sees that it
originated the change itself, with an originating USN of 5. However,
domain controller 2 asked for any information from domain controller 1
with an originating USN higher than 1, so now domain controller 1 knows
that domain controller 2 has no idea of this new information and it
passes it along. Domain controller 2 records the change and assigns a
USN of 3, and then makes a note that its partner's highest USN is 5 and
the highest originating USN it has seen from domain controller 1 is 5.
Our values, after that process, are shown in Table 6.
Table 6. Example USNs, originating USNs, and UTD vectors after example replication
| | | Up-to-date vectors |
---|
Domain controller | Highest USN | Partner's highest USN | Self | Partner |
---|
1 | 5 | 2 | 5 (from domain controller 1) | 2 (from domain controller 2) |
2 | 3 | 5 | 3 (from domain controller 2) | 5 (from domain controller 1) |
Let's go a bit
further. Replication kicks off again, and this time domain controller 1
contacts domain controller 2 and asks if it has any new information
higher than USN 2, which it knows is its partner's highest USN, and
whether the originating USNs are higher than 5 for domain controller 1
and 2 for domain controller 2. Domain controller 2 checks its copy of
the directory and sees that it has a change to which it assigned a USN
of 3, but it also checks to see where that change came from—and it sees
that the change came from domain controller 1 and that domain controller
1 assigned a USN of 5 to it. Domain controller 2 decides that even
though the change was new to itself, domain controller 1 clearly already
knows about it and therefore doesn't need that change replicated.
Domain controller 2 tells domain controller 1 about its currently
highest USN (3), and domain controller 1 makes a note of that. What does
this entire process accomplish? It ensures that a change is replicated
only between partners because each partner can figure out who knows
about what changes and when they were made by looking at USNs and
up-to-date vectors. So, now everyone is happy—really, this time—as shown
in Table 7.
Table 7. Final replication results
| | | Up-to-date vectors |
---|
Domain controller | Highest USN | Partner's highest USN | Self | Partner |
---|
1 | 5 | 3 | 5 (from domain controller 1) | 2 (from domain controller 2) |
2 | 3 | 5 | 3 (from domain controller 2) | 5 (from domain controller 1) |
In
summary, domain controllers use this up-to-date vector table and the
originating USN data fundamentally to construct a more specific
replication request. So, instead of simply asking a replication partner
for any data higher than the highest USN a requestor knows, it asks for
any data higher than the highest USN it knows is also higher than the
ones for each domain controller in its up-to-date vector table.