forked from lei.chen/myxce
test(ha-term-safety): cross-member walcompare divergence tool (task 5.3)
Diffs member WALs by (lsn -> term, pcrc) over the committed prefix, exits non-zero on any committed-prefix divergence with the diverging LSN + per-member entry identities. Reuses the canonical waldump decoder via a new per-entry visitor seam (no second WAL parser). Detects same-LSN/diff-term and same-LSN/diff-content divergences (the bug-851 class) that an LSN-range check would mask.
This commit is contained in:
parent
d39500ba48
commit
a166ecb45b
9 changed files with 842 additions and 5 deletions
|
|
@ -31,6 +31,24 @@ typedef struct {
|
|||
int crc_broken; /* nonzero if a CRC/chain break truncated a segment */
|
||||
} waldump_stats_t;
|
||||
|
||||
/* One physically-present, CRC-valid WAL entry, surfaced to a visitor so a
|
||||
* caller (e.g. walcompare) can index the log by `(lsn -> term, pcrc)` without
|
||||
* re-implementing the segment/CRC parse. `pcrc` is the payload-only CRC32 (0
|
||||
* for an empty payload) — the same fingerprint waldump prints, isolating the
|
||||
* blob from the header so a same-LSN content divergence is detectable. */
|
||||
typedef struct {
|
||||
uint64_t lsn;
|
||||
uint64_t term; /* raw on-disk term (legacy 0 kept verbatim) */
|
||||
uint32_t type; /* WAL entry type (wal_types.h) */
|
||||
uint32_t payload_len; /* payload byte count */
|
||||
uint32_t pcrc; /* CRC32 of payload only (0 if payload_len == 0) */
|
||||
} waldump_entry_t;
|
||||
|
||||
/* Per-entry visitor. Invoked once per CRC-valid entry in ascending scan order
|
||||
* (before the gap line is printed). Return 0 to continue, non-zero to stop the
|
||||
* scan early. `ctx` is the caller's opaque pointer. */
|
||||
typedef int (*waldump_visit_fn)(void* ctx, const waldump_entry_t* e);
|
||||
|
||||
/* Dump every WAL entry under `path` to `out` (human-readable) and fill
|
||||
* `*stats` when non-NULL. `path` may be:
|
||||
* - a single seg-*.wal file,
|
||||
|
|
@ -40,3 +58,12 @@ typedef struct {
|
|||
* path does not exist / no segments found). Gaps and CRC breaks are reported
|
||||
* through `out`/`stats`, NOT via the return code. */
|
||||
int waldump_path(const char* path, FILE* out, waldump_stats_t* stats);
|
||||
|
||||
/* Same as waldump_path, but also invokes `visit(ctx, &entry)` for every
|
||||
* CRC-valid entry so a caller can collect the `(lsn -> term, pcrc)` index.
|
||||
* `visit` may be NULL (then identical to waldump_path). `out` may be a sink
|
||||
* the caller does not care about (e.g. a /dev/null FILE) — the human dump is
|
||||
* still produced. The single canonical WAL decoder is reused; no second
|
||||
* segment parser. */
|
||||
int waldump_path_visit(const char* path, FILE* out, waldump_stats_t* stats,
|
||||
waldump_visit_fn visit, void* ctx);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue