I was rereading one of my posts in this blog today - Active Directory Backup? Don't rush - you'll get more time - and realized that not everyone might be aware what a Tombstone is.
As we know Active Directory is a multi-master directory: Every DC is usually able to write into the directory. Examples of single-master directories are classical DNS (only one primary server per zone, and the primary server is the one who writes updates to the zone, many secondaries are able to pull those informations and provide them to other clients/servers) or a Windows NT 4.0 Domain with one Primary Domain Controller (PDC) and multiple Backup Domain Controllers (BDC) (same thing here - only the primary is allowed to write).
One of the things to consider when designing a multi-master directory are how content will be deleted. If we would delete something completely and right away, how would another domain controller figure out that it was deleted and that he needs to delete the same object in his database?
And that's where the tombstones fit into the picture. If we delete a object it is not immediately deleted but "converted" into a tombstone. When replication occurs the other DCs note the change of the object and convert their local copies in the database into tombstones by replicating the changes of the object. So what happens to the object when it is deleted?
The object will be marked as deleted, meaning the isDeleted-Attribute is set to true. It will be also moved to the "Deleted Objects"-container. Also all Attributes which are not supposed to remain in a tombstone will be stripped from the object. So most data is not there anymore, but the most important ones like the Global Unique Identifier (GUID) and the Security Identifyer (SID) will remain. There are additional attributes being kept in the tombstone, e.g. in Windows Server 2003 there is also the SID-History kept in the tombstone. Which attributes will remain in the tombstone is defined in the schema, in the definition of the attribute. If the fourth bit in the searchflags (= decimal 8) is set the attribute will remain in the tombstones. You are able to configure additional attributes to remain in the tombstone by setting this bit as well.
Using the following command you are able to retrieve most attributes which remain in the tombstone (everything in one line):
dsquery * cn=schema,cn=configuration,dc=yourcomain,dc=com
-scope subtree -attr name
~eric reminded me that this query will not necessarily return all attributes which are preserved in a tombstone - some critical objects and changes of the list are hardcoded and will remain in the tombstone no matter what the searchflags state. SidHistory in Windows Server 2003 SP1 is one of them which won't appear in the schema unless you change it yourself, but will remain in the tombstone. The reason for this approach is to not require a update in the schema partition when installing SP1. However I wouldn't call changing the searchflags of an attribute a major change in the schema (you are able to reverse it, and especially the change of tombstone behavior has not this much of an impact), but that's another topic. I do understand why Microsoft used that approach.
To see the tombstones in your AD you can use LDP.exe in the support tools. Instructions for this are in the Windows 2000 Resource Kit in the Distributed Systems Guide: Searching for Deleted Objects
After a object is tombstoned it will remain in the directory for the tombstone-lifetime (60 or 180 days by default, see Active Directory Backup? Don't rush - you'll get more time). The tombstone-lifetime assures that the tombstone will be replicated to every DC, so that every DC knows that the object is deleted. This is the reason why you can not use a backup to restore Active Directory which is older than the tombstone-lifetime - it would reintroduce objects which have been deleted prior.
The garbage collection process one every domain controller takes care that tombstones which are older than the tombstone-lifetime are deleted permanently. The garbage-collection process runs by default every 12 hours on each DC. You can also configure other periods by modifying the garbageCollPeriod Attribute of the CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=yourdomain,DC=com Object. However this should not be necessary, and I encourage nobody to modify it.
However, the object is permanently deleted now, but the NTDS.dit-Databasefile which contains the Active Directory will not decrease it's size. Instead the new "Whitespace" will be used for new objects. The only possibility to release the Whitespace in the database is to perform a offline defragmentation using NTDSUtil in the Directory Services Restore Mode. See the Knowledgebase-Article (315131) HOW TO: Use Ntdsutil to Manage Active Directory Files from the Command Line in Windows 2000 on how to perform the offline defragmentation. However this is usually not necessary that often, but should definitely been done after upgrading a domain from Windows 2000 to Windows Server 2003. You may also want to do that after you deleted a lot of objects and the tombstone-lifetime is over.
You can check whenever the garbage collection process runs and how big the amount of whitespace in the database-file is. After you set the following registry-key on your domain controller (usually no need to set it on every DC since the size and whitespace should be about the same on every DC of the domain) you'll get events in the directory services eventlog when the garbage-collection is started, stopped and how much whitespace it detected in the NTDS.dit:
"6 Garbage Collection" = 1 (reg_dword)
Be careful with the logging-levels underneath that key, they are by default all 0, and you can increase them up to 5 to increase the logging-level. However as higher as the level is you might get performance issues and the eventlogs are flooded with a lot of informations. Keep them at 0, and only increase them slightly if you have specific reasons.
OK, that's it for now, but I'll have some follow-ups on related topics soon.