feat(ha-term-safety): on_get_entry_term + on_truncate_from callback bodies (task 2.2)
on_get_entry_term → persist_entry_term (recorded term, 0=absent, legacy-0→1; caveat documented per 1.3 review). on_truncate_from → persist_truncate_wal_above(p, index-1) (delete LSN>=index), returns rc for library/leader retry; non-promotable fence intact; replaces the committed-boundary heuristic on the library-driven path. New truncate_term_index_locked keeps the in-memory per-LSN term index consistent on both truncate paths (under lock, cutoff-aligned) → no stale-term read after truncation. 3 tests, reviewer APPROVED, per-group 0 failures.
This commit is contained in:
parent
8f3d3ce8f4
commit
ed2443533f
5 changed files with 210 additions and 5 deletions
|
|
@ -440,6 +440,21 @@ static void record_entry_term(persist_t* p, uint64_t lsn, uint64_t term)
|
|||
p->term_index_count = lsn;
|
||||
}
|
||||
|
||||
/* Shrink the in-memory per-LSN term index so that every LSN > `keep_lsn` reads
|
||||
* back as absent (ha-term-safety task 2.2). Called from the truncate path after
|
||||
* the on-disk entries above keep_lsn are removed, keeping the term index
|
||||
* consistent with the WAL: a later persist_entry_term on a truncated LSN must
|
||||
* return 0. The backing allocation is left as-is (only the live count moves);
|
||||
* the zeroed-on-grow contract means a later re-append at those LSNs overwrites
|
||||
* cleanly. Caller must hold p->lock. */
|
||||
static void truncate_term_index_locked(persist_t* p, uint64_t keep_lsn)
|
||||
{
|
||||
if (!p)
|
||||
return;
|
||||
if (keep_lsn < p->term_index_count)
|
||||
p->term_index_count = keep_lsn;
|
||||
}
|
||||
|
||||
void persist_set_term(persist_t* p, uint64_t term)
|
||||
{
|
||||
if (!p)
|
||||
|
|
@ -2659,6 +2674,8 @@ int persist_truncate_wal_above(persist_t* p, uint64_t cutoff_lsn)
|
|||
atomic_store_explicit(&p->committed_lsn, cutoff_lsn,
|
||||
memory_order_release);
|
||||
clamp_durable_lsn_locked(p, cutoff_lsn);
|
||||
/* Keep the per-LSN term index consistent: drop terms for removed LSNs. */
|
||||
truncate_term_index_locked(p, cutoff_lsn);
|
||||
pthread_mutex_unlock(&p->lock);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2738,6 +2755,8 @@ int persist_truncate_wal_above(persist_t* p, uint64_t cutoff_lsn)
|
|||
p->last_crc = new_last_crc;
|
||||
atomic_store_explicit(&p->committed_lsn, cutoff_lsn, memory_order_release);
|
||||
clamp_durable_lsn_locked(p, cutoff_lsn);
|
||||
/* Keep the per-LSN term index consistent: drop terms for removed LSNs. */
|
||||
truncate_term_index_locked(p, cutoff_lsn);
|
||||
|
||||
pthread_mutex_unlock(&p->lock);
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue