From c2a0515d4c84060dee1b7377c98febf7d3b15945 Mon Sep 17 00:00:00 2001 From: Libor Peltan Date: Mon, 26 Jul 2021 20:22:01 +0200 Subject: [PATCH 1/2] journal: bugfix: avoid deleting zero-byte prefix... ...when deleting rootzone-related records because it also deletes global metadata --- src/knot/journal/journal_basic.c | 13 +++++++++++++ src/knot/journal/journal_basic.h | 10 ++++++++++ src/knot/journal/journal_metadata.c | 6 +++--- src/knot/journal/journal_write.c | 6 ++---- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/knot/journal/journal_basic.c b/src/knot/journal/journal_basic.c index 9874574ea..0285630ed 100644 --- a/src/knot/journal/journal_basic.c +++ b/src/knot/journal/journal_basic.c @@ -36,6 +36,19 @@ MDB_val journal_changeset_to_chunk_key(const changeset_t *ch, uint32_t chunk_id) } } +MDB_val journal_zone_prefix(const knot_dname_t *zone) +{ + return knot_lmdb_make_key("NI", zone, (uint32_t)0); +} + +void journal_del_zone(knot_lmdb_txn_t *txn, const knot_dname_t *zone) +{ + assert(txn->is_rw); + MDB_val prefix = journal_zone_prefix(zone); + knot_lmdb_del_prefix(txn, &prefix); + free(prefix.mv_data); +} + void journal_make_header(void *chunk, uint32_t ch_serial_to) { knot_lmdb_make_key_part(chunk, JOURNAL_HEADER_SIZE, "IILLL", ch_serial_to, diff --git a/src/knot/journal/journal_basic.h b/src/knot/journal/journal_basic.h index 02ca5ddf6..11e5f47f6 100644 --- a/src/knot/journal/journal_basic.h +++ b/src/knot/journal/journal_basic.h @@ -58,6 +58,16 @@ MDB_val journal_changeset_id_to_key(bool zone_in_journal, uint32_t serial, const */ MDB_val journal_changeset_to_chunk_key(const changeset_t *ch, uint32_t chunk_id); +/*! + * \brief Return a key prefix to operate with all zone-related records. + */ +MDB_val journal_zone_prefix(const knot_dname_t *zone); + +/*! + * \brief Delete all zone-related records from journal with open read-write txn. + */ +void journal_del_zone(knot_lmdb_txn_t *txn, const knot_dname_t *zone); + /*! * \brief Initialise chunk header. * diff --git a/src/knot/journal/journal_metadata.c b/src/knot/journal/journal_metadata.c index 4b468cd87..3834a1e94 100644 --- a/src/knot/journal/journal_metadata.c +++ b/src/knot/journal/journal_metadata.c @@ -295,8 +295,7 @@ int journal_scrape_with_md(zone_journal_t j, bool check_existence) knot_lmdb_begin(j.db, &txn, true); update_last_inserter(&txn, NULL); - MDB_val prefix = { knot_dname_size(j.zone), (void *)j.zone }; - knot_lmdb_del_prefix(&txn, &prefix); + journal_del_zone(&txn, j.zone); knot_lmdb_commit(&txn); return txn.ret; @@ -313,8 +312,9 @@ int journal_copy_with_md(knot_lmdb_db_t *from, knot_lmdb_db_t *to, const knot_dn knot_lmdb_begin(from, &tr, true); knot_lmdb_begin(to, &tw, true); update_last_inserter(&tr, NULL); - MDB_val prefix = { knot_dname_size(zone), (void *)zone }; + MDB_val prefix = journal_zone_prefix(zone); knot_lmdb_copy_prefix(&tr, &tw, &prefix); + free(prefix.mv_data); knot_lmdb_commit(&tw); knot_lmdb_commit(&tr); done: diff --git a/src/knot/journal/journal_write.c b/src/knot/journal/journal_write.c index 7e211c1c3..70ea20975 100644 --- a/src/knot/journal/journal_write.c +++ b/src/knot/journal/journal_write.c @@ -225,8 +225,7 @@ int journal_insert_zone(zone_journal_t j, const zone_contents_t *z) knot_lmdb_begin(j.db, &txn, true); update_last_inserter(&txn, j.zone); - MDB_val prefix = { knot_dname_size(j.zone), (void *)j.zone }; - knot_lmdb_del_prefix(&txn, &prefix); + journal_del_zone(&txn, j.zone); journal_write_zone(&txn, z); @@ -282,8 +281,7 @@ int journal_insert(zone_journal_t j, const changeset_t *ch, const changeset_t *e if (journal_contains(&txn, true, 0, j.zone)) { txn.ret = KNOT_ESEMCHECK; } else { - MDB_val prefix = { knot_dname_size(j.zone), (void *)j.zone }; - knot_lmdb_del_prefix(&txn, &prefix); + journal_del_zone(&txn, j.zone); memset(&md, 0, sizeof(md)); } } From 58b7cb4fc85a2ae550ef7a96da0c958613f69f50 Mon Sep 17 00:00:00 2001 From: Libor Peltan Date: Tue, 27 Jul 2021 13:52:27 +0200 Subject: [PATCH 2/2] journal: preserve occupation computation when purging zone while writing it --- src/knot/journal/journal_metadata.c | 8 ++++++++ src/knot/journal/journal_metadata.h | 8 ++++++++ src/knot/journal/journal_write.c | 4 ++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/knot/journal/journal_metadata.c b/src/knot/journal/journal_metadata.c index 3834a1e94..213ae510e 100644 --- a/src/knot/journal/journal_metadata.c +++ b/src/knot/journal/journal_metadata.c @@ -286,6 +286,14 @@ void journal_metadata_after_extra(journal_metadata_t *md, uint32_t serial, uint3 md->flags |= (JOURNAL_MERGED_SERIAL_VALID | JOURNAL_LAST_FLUSHED_VALID); } +void journal_del_zone_txn(knot_lmdb_txn_t *txn, const knot_dname_t *zone) +{ + uint64_t md_occupied = 0; + (void)get_metadata64(txn, zone, "occupied", &md_occupied); + journal_del_zone(txn, zone); + set_metadata(txn, zone, "occupied", &md_occupied, sizeof(md_occupied), true); +} + int journal_scrape_with_md(zone_journal_t j, bool check_existence) { if (check_existence && !journal_is_existing(j)) { diff --git a/src/knot/journal/journal_metadata.h b/src/knot/journal/journal_metadata.h index 6400b9cd7..246d89973 100644 --- a/src/knot/journal/journal_metadata.h +++ b/src/knot/journal/journal_metadata.h @@ -111,6 +111,14 @@ void journal_metadata_after_insert(journal_metadata_t *md, uint32_t serial, uint */ void journal_metadata_after_extra(journal_metadata_t *md, uint32_t serial, uint32_t serial_to); +/*! + * \brief Delete all zone records in a txn that will later write to the same zone. + * + * \note The difference against journal_del_zone(), which purges even metadata, incl "occupied". + * \note This preserves keeping track of space occupied/freed by this zone. + */ +void journal_del_zone_txn(knot_lmdb_txn_t *txn, const knot_dname_t *zone); + /*! * \brief Completely delete all journal records belonging to this zone, including metadata. * diff --git a/src/knot/journal/journal_write.c b/src/knot/journal/journal_write.c index 70ea20975..86cb281ae 100644 --- a/src/knot/journal/journal_write.c +++ b/src/knot/journal/journal_write.c @@ -225,7 +225,7 @@ int journal_insert_zone(zone_journal_t j, const zone_contents_t *z) knot_lmdb_begin(j.db, &txn, true); update_last_inserter(&txn, j.zone); - journal_del_zone(&txn, j.zone); + journal_del_zone_txn(&txn, j.zone); journal_write_zone(&txn, z); @@ -281,7 +281,7 @@ int journal_insert(zone_journal_t j, const changeset_t *ch, const changeset_t *e if (journal_contains(&txn, true, 0, j.zone)) { txn.ret = KNOT_ESEMCHECK; } else { - journal_del_zone(&txn, j.zone); + journal_del_zone_txn(&txn, j.zone); memset(&md, 0, sizeof(md)); } }