0N/ABIND 9 DNS database allows named rdatasets to be stored and retrieved.
0N/ADNS databases are used to store two different categories of data:
0N/Aauthoritative zone data and non-authoritative cache data. Unlike
0N/Aprevious versions of BIND which used a monolithic database, BIND 9 has
0N/Aone database per zone or cache. Certain database operations, for
0N/Aexample updates, have differing requirements and actions depending
0N/Aupon whether the database contains zone data or cache data.
0N/AA database instance either has zone semantics or cache semantics. The
0N/Asemantics are chosen when the database is created and cannot be
0N/Achanged. The differences between zone databases and cache databases
0N/Awill be discussed further below.
0N/AIt is a general principle of the BIND 9 project, and of the database
0N/AAPI, that all references returned to the caller remain valid until the
0N/Acaller discards the reference.
0N/AThe database interface also mandates that the rdata in a retrieved
0N/Ardataset shall remain unaltered while any reference to the rdataset is
0N/Aheld. Some other properties of the rdataset,
e.g. its DNSSEC
0N/Avalidation status, may change.
0N/AA master zone is updated by a Dynamic Update message. A slave zone is
0N/Aupdated by IXFR or AXFR. AXFR provides the entire contents of the new
0N/Azone version, and replaces the entire contents of the database. IXFR
0N/Aand Dynamic Update, although completely different protocols, have the
0N/Asame basic database requirements. They are differential update
0N/Aprotocols,
e.g. "add this record to the records at name 'foo'". The
0N/Aupdates are also atomic,
i.e. they must either succeed or fail.
0N/AChanges must not become visible to clients until the update has
0N/Acommitted. In short, zone updates are transactional. This
0N/Atransaction occurs at a database level; the entire database goes from
0N/Aone version to another.
0N/ACache updates are done by the server in the ordinary course of
0N/Ahandling client requests. Unlike zone databases, there's no need (and
0N/Aindeed, no ability) to ensure that data in the cache is consistent.
0N/AFor example, the cache may hold rdatasets from different versions of a
0N/Agiven zone. A typical cache update involves looking at the existing
0N/Acache contents for the given name and type (if any), deciding if the
0N/Aproposed replacement is better, and if so, doing the replacement.
0N/AConcurrent update attempts to the same node and rdataset type must
0N/Aappear to have been executed in some order; there must be no merging
0N/Aof data from multiple updates. Caches are not globally versioned like
0N/Azones are. There is no need to group changes to multiple rdatasets
0N/Ainto a cache transaction.
0N/ADatabase Concurrency and Locking
0N/AA principal goal of the BIND 9 project is multiprocessor scalabilty.
0N/AThe amount of concurrency in database accesses is an important factor
0N/Ain achieving scalability. Consider a heavily used database,
e.g. the
0N/Acache database serving some mail hubs, or ".com". If access to these
0N/Adatabases is not parallalized, then adding another CPU will not help
0N/Athe server's performance for the portion of the runtime spent in
0N/ASupport for multiple concurrent readers certainly helps both cache
0N/Adatabases and zone databases. Zones are typically read much more than
0N/Athey are written, though less so than in prior years because dynamic
0N/ADNS support is now widely available. Caches are frequently read and
0N/Afrequently written; a non-scientific survey of caching statistics on a
0N/Afew busy caching nameservers showed the ratio of cache hits to misses
0N/AAs mentioned above, zone updates must be serialized, but cache updates
0N/Acan often go in parallel.
0N/AA simple approach to these concurrency goals would be to have a single
read-write lock on the database. This would allow for multiple
concurrent readers, and would provide the serialization of updates
that zone updates require. This approach also has significant
limitations. Readers cannot run while an update is running. For a
short-lived transaction like a Dynamic Update, this may be acceptable,
but an IXFR can take a long time (even hours) to complete. Preventing
read access for such a long time is unacceptable. Another problem is
that it forces updates to be serialized, even for cache databases.
There are problems on the reader side of the lock too. If the entire
database is protected by one lock, then any data retrieved from the
database must either be used while the lock is held, or it must be
copied, because the data in the database can change when the lock
isn't held. Copying is expensive, and the server would like to be
able to hold a reference to database data for a long time. The most
significant long-running reader problem is outbound AXFR, which could
potentially block updates for a long time (hours).
A finer-grained locking scheme,
e.g. one lock per node, helps
parallelize cache updates, but doesn't help with the long-lived reader
or long-lived writer problems. These problems are solved by zone
database versioning, described below.
The BIND 9 Database interface does not mandate any particular locking
scheme. Database implementations are strongly encouraged to provide
as much concurrency as possible without violating the database
Versioning is not available in cache databases.
A zone database has a "current version" which is the version most recently
committed. A database has a set of versions open for reading (the
"open versions"). This set is always non-empty, since the current
version is always open. The openversion method opens a read-only
handle to the current version. All retrievals using the handle will
see the database as it was at the time the version was opened,
regardless of subsequent changes to the database. It is not possible
to open a specific version; only the current version may be opened.
This helps limit the number of prior versions which must be kept in
Each zone update transaction is assigned a new version. Only one such
"future version" may be open at any time. It is the caller's
responsibility to serialize and handle the blocking and awakening of
multiple update requests. The future version may be committed or
rolled back by the caller. If the future version commits, its version
becomes the current version of the database.