Commit 7e59b8a4 authored by Ondřej Surý's avatar Ondřej Surý
Browse files

Pause the dbiterator when dumping the zone to the disk

When we rewrote the zone dumping to use the separate threadpool, the
dumping would acquire the read lock for the whole time the zone dumping
process is dumping the zone.

When combined with incoming IXFR that tries to acquire the write lock on
the same rwlock, we would end up blocking all the other readers.

In this commit, we pause the dbiterator every time we get next record
and before start dumping it to the disk.
parent 7fef0120
Pipeline #73647 passed with stages
in 32 minutes and 44 seconds
......@@ -254,7 +254,6 @@ struct dns_dumpctx {
isc_mutex_t lock;
isc_refcount_t references;
atomic_bool canceled;
bool first;
bool do_date;
isc_stdtime_t now;
FILE *f;
......@@ -1578,7 +1577,6 @@ dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
dctx->done = NULL;
dctx->done_arg = NULL;
dctx->task = NULL;
dctx->first = true;
atomic_init(&dctx->canceled, false);
dctx->file = NULL;
dctx->tmpfile = NULL;
......@@ -1737,7 +1735,6 @@ dumptostream(dns_dumpctx_t *dctx) {
char *bufmem;
dns_name_t *name;
dns_fixedname_t fixname;
isc_time_t start;
bufmem = isc_mem_get(dctx->mctx, initial_buffer_length);
......@@ -1745,32 +1742,24 @@ dumptostream(dns_dumpctx_t *dctx) {
name = dns_fixedname_initname(&fixname);
if (dctx->first) {
CHECK(writeheader(dctx));
CHECK(writeheader(dctx));
/*
* Fast format is not currently written incrementally,
* so we make the call to dns_db_serialize() here.
* If the database is anything other than an rbtdb,
* this should result in not implemented
*/
if (dctx->format == dns_masterformat_map) {
result = dns_db_serialize(dctx->db, dctx->version,
dctx->f);
goto cleanup;
}
result = dns_dbiterator_first(dctx->dbiter);
if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) {
goto cleanup;
}
/*
* Fast format is not currently written incrementally,
* so we make the call to dns_db_serialize() here.
* If the database is anything other than an rbtdb,
* this should result in not implemented
*/
if (dctx->format == dns_masterformat_map) {
result = dns_db_serialize(dctx->db, dctx->version, dctx->f);
goto cleanup;
}
dctx->first = false;
} else {
result = ISC_R_SUCCESS;
result = dns_dbiterator_first(dctx->dbiter);
if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) {
goto cleanup;
}
isc_time_now(&start);
while (result == ISC_R_SUCCESS) {
dns_rdatasetiter_t *rdsiter = NULL;
dns_dbnode_t *node = NULL;
......@@ -1790,6 +1779,10 @@ dumptostream(dns_dumpctx_t *dctx) {
}
dctx->tctx.neworigin = origin;
}
result = dns_dbiterator_pause(dctx->dbiter);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
result = dns_db_allrdatasets(dctx->db, node, dctx->version,
dctx->now, &rdsiter);
if (result != ISC_R_SUCCESS) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment