mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Merge branch '4591-improve-ttl-based-cleaning' into 'main'
Remove expired rdataset headers from the heap Closes #4591 See merge request isc-projects/bind9!8754
This commit is contained in:
commit
7111ea3669
2 changed files with 63 additions and 10 deletions
5
CHANGES
5
CHANGES
|
|
@ -1,3 +1,8 @@
|
|||
6353. [bug] Improve the TTL-based cleaning by removing the expired
|
||||
headers from the heap, so they don't block the next
|
||||
cleaning round and clean more than a single item for
|
||||
each new addition to the RBTDB. [GL #4591]
|
||||
|
||||
6352. [bug] Revert change 6319 and decrease lock contention during
|
||||
RBTDB tree pruning by not cleaning up nodes recursively
|
||||
within a single prune_tree() call. [GL #4596]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -337,6 +345,10 @@ dns__rbtdb_setttl(dns_slabheader_t *header, dns_ttl_t newttl) {
|
|||
} else {
|
||||
isc_heap_decreased(header->heap, header->heap_index);
|
||||
}
|
||||
|
||||
if (newttl == 0) {
|
||||
isc_heap_delete(header->heap, header->heap_index);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -3160,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,
|
||||
|
|
@ -3170,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;
|
||||
|
|
@ -3342,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
|
||||
|
|
@ -4851,7 +4861,6 @@ dns__rbtdb_deletedata(dns_db_t *db ISC_ATTR_UNUSED,
|
|||
if (header->heap != NULL && header->heap_index != 0) {
|
||||
isc_heap_delete(header->heap, header->heap_index);
|
||||
}
|
||||
header->heap_index = 0;
|
||||
|
||||
if (IS_CACHE(rbtdb)) {
|
||||
update_rrsetstats(rbtdb->rrsetstats, header->type,
|
||||
|
|
@ -4876,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…
Reference in a new issue