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
|
|
@ -197,7 +197,9 @@ static int collect_segments(const char* wal_dir, uint64_t* seg_lsns, int max)
|
|||
static void scan_segment(const char* seg_path, FILE* out,
|
||||
uint32_t* last_crc, uint64_t* prev_lsn,
|
||||
uint64_t* prev_submit_jobid, uint32_t* prev_submit_pcrc,
|
||||
waldump_stats_t* st)
|
||||
waldump_stats_t* st,
|
||||
waldump_visit_fn visit, void* visit_ctx,
|
||||
int* visit_stop)
|
||||
{
|
||||
int fd = open(seg_path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
|
|
@ -282,6 +284,25 @@ static void scan_segment(const char* seg_path, FILE* out,
|
|||
? crc32(0L, (const Bytef*)payload, hdr.payload_len)
|
||||
: 0;
|
||||
|
||||
/* Surface the CRC-valid entry to the visitor so a caller can index the
|
||||
* log by (lsn -> term, pcrc) — the single canonical decoder, no second
|
||||
* parser. */
|
||||
if (visit) {
|
||||
waldump_entry_t e = {
|
||||
.lsn = hdr.lsn,
|
||||
.term = hdr.term,
|
||||
.type = hdr.type,
|
||||
.payload_len = hdr.payload_len,
|
||||
.pcrc = pcrc,
|
||||
};
|
||||
if (visit(visit_ctx, &e) != 0) {
|
||||
if (visit_stop)
|
||||
*visit_stop = 1;
|
||||
free(payload);
|
||||
break; /* visitor asked to stop */
|
||||
}
|
||||
}
|
||||
|
||||
/* Per-entry line, with jobid/subtime for submits. */
|
||||
char info[96] = "";
|
||||
int is_dup = 0;
|
||||
|
|
@ -347,6 +368,12 @@ static void scan_segment(const char* seg_path, FILE* out,
|
|||
/* Public entry point */
|
||||
/* ------------------------------------------------------------------ */
|
||||
int waldump_path(const char* path, FILE* out, waldump_stats_t* stats)
|
||||
{
|
||||
return waldump_path_visit(path, out, stats, NULL, NULL);
|
||||
}
|
||||
|
||||
int waldump_path_visit(const char* path, FILE* out, waldump_stats_t* stats,
|
||||
waldump_visit_fn visit, void* ctx)
|
||||
{
|
||||
if (!path || !out)
|
||||
return -EINVAL;
|
||||
|
|
@ -417,12 +444,14 @@ int waldump_path(const char* path, FILE* out, waldump_stats_t* stats)
|
|||
uint64_t prev_lsn = 0;
|
||||
uint64_t prev_submit_jobid = 0;
|
||||
uint32_t prev_submit_pcrc = 0;
|
||||
for (int i = 0; i < nseg; i++) {
|
||||
int visit_stop = 0;
|
||||
for (int i = 0; i < nseg && !visit_stop; i++) {
|
||||
if (single_seg[0] == '\0')
|
||||
snprintf(seg_path, sizeof(seg_path), WAL_SEG_FMT, wal_dir,
|
||||
seg_lsns[i]);
|
||||
scan_segment(seg_path, out, &last_crc, &prev_lsn,
|
||||
&prev_submit_jobid, &prev_submit_pcrc, &st);
|
||||
&prev_submit_jobid, &prev_submit_pcrc, &st,
|
||||
visit, ctx, &visit_stop);
|
||||
}
|
||||
|
||||
fprintf(out, "-- summary --\n");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue