mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +00:00
Make the TTL-based cleaning more aggressive
It was discovered that the TTL-based cleaning could build up a significant backlog of the rdataset headers during the periods where the top of the TTL heap isn't expired yet. Make the TTL-based cleaning more aggressive by cleaning more headers from the heap when we are adding new header into the RBTDB.
This commit is contained in:
parent
a9383e4b95
commit
d8220ca4ca
@ -154,6 +154,14 @@
|
||||
#define DEFAULT_CACHE_NODE_LOCK_COUNT 17
|
||||
#endif /* DNS_RBTDB_CACHE_NODE_LOCK_COUNT */
|
||||
|
||||
/*
|
||||
* This defines the number of headers that we try to expire each time the
|
||||
* expire_ttl_headers() is run. The number should be small enough, so the
|
||||
* TTL-based header expiration doesn't take too long, but it should be large
|
||||
* enough, so we expire enough headers if their TTL is clustered.
|
||||
*/
|
||||
#define DNS_RBTDB_EXPIRE_TTL_COUNT 10
|
||||
|
||||
static void
|
||||
delete_callback(void *data, void *arg);
|
||||
static void
|
||||
@ -3164,6 +3172,11 @@ cleanup:
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
expire_ttl_headers(dns_rbtdb_t *rbtdb, unsigned int locknum,
|
||||
isc_rwlocktype_t *tlocktypep, isc_stdtime_t now,
|
||||
bool cache_is_overmem DNS__DB_FLARG);
|
||||
|
||||
isc_result_t
|
||||
dns__rbtdb_addrdataset(dns_db_t *db, dns_dbnode_t *node,
|
||||
dns_dbversion_t *version, isc_stdtime_t now,
|
||||
@ -3174,7 +3187,6 @@ dns__rbtdb_addrdataset(dns_db_t *db, dns_dbnode_t *node,
|
||||
dns_rbtdb_version_t *rbtversion = version;
|
||||
isc_region_t region;
|
||||
dns_slabheader_t *newheader = NULL;
|
||||
dns_slabheader_t *header = NULL;
|
||||
isc_result_t result;
|
||||
bool delegating;
|
||||
bool newnsec;
|
||||
@ -3346,14 +3358,8 @@ dns__rbtdb_addrdataset(dns_db_t *db, dns_dbnode_t *node,
|
||||
rbtnode->locknum DNS__DB_FLARG_PASS);
|
||||
}
|
||||
|
||||
header = isc_heap_element(rbtdb->heaps[rbtnode->locknum], 1);
|
||||
if (header != NULL && header->ttl + STALE_TTL(header, rbtdb) <
|
||||
now - RBTDB_VIRTUAL)
|
||||
{
|
||||
dns__cacherbt_expireheader(
|
||||
header, &tlocktype,
|
||||
dns_expire_ttl DNS__DB_FLARG_PASS);
|
||||
}
|
||||
expire_ttl_headers(rbtdb, rbtnode->locknum, &tlocktype, now,
|
||||
cache_is_overmem DNS__DB_FLARG_PASS);
|
||||
|
||||
/*
|
||||
* If we've been holding a write lock on the tree just for
|
||||
@ -4879,3 +4885,42 @@ dns__rbtdb_deletedata(dns_db_t *db ISC_ATTR_UNUSED,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Caller must be holding the node write lock.
|
||||
*/
|
||||
static void
|
||||
expire_ttl_headers(dns_rbtdb_t *rbtdb, unsigned int locknum,
|
||||
isc_rwlocktype_t *tlocktypep, isc_stdtime_t now,
|
||||
bool cache_is_overmem DNS__DB_FLARG) {
|
||||
isc_heap_t *heap = rbtdb->heaps[locknum];
|
||||
|
||||
for (size_t i = 0; i < DNS_RBTDB_EXPIRE_TTL_COUNT; i++) {
|
||||
dns_slabheader_t *header = isc_heap_element(heap, 1);
|
||||
|
||||
if (header == NULL) {
|
||||
/* No headers left on this TTL heap; exit cleaning */
|
||||
return;
|
||||
}
|
||||
|
||||
dns_ttl_t ttl = header->ttl;
|
||||
|
||||
if (!cache_is_overmem) {
|
||||
/* Only account for stale TTL if cache is not overmem */
|
||||
ttl += STALE_TTL(header, rbtdb);
|
||||
}
|
||||
|
||||
if (ttl >= now - RBTDB_VIRTUAL) {
|
||||
/*
|
||||
* The header at the top of this TTL heap is not yet
|
||||
* eligible for expiry, so none of the other headers on
|
||||
* the same heap can be eligible for expiry, either;
|
||||
* exit cleaning.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
dns__cacherbt_expireheader(header, tlocktypep,
|
||||
dns_expire_ttl DNS__DB_FLARG_PASS);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user