feat(ha-commit-durability): gate standby ACK on fdatasync success + persist-before-ACK regression test (task 2.3)

This commit is contained in:
Rongsong Shen 2026-06-18 06:45:21 +00:00
parent c41edc515e
commit e4c4968331
4 changed files with 155 additions and 3 deletions

View file

@ -117,6 +117,14 @@ struct persist_s {
* must NOT advance and the failure is logged loudly. Compiled out of
* production (xce_controller is built without -DXCE_TESTING). */
atomic_int test_force_fsync_fail;
/* fdatasync observability counter (ha-commit-durability task 2.3):
* incremented at the standby-path inline sync in
* persist_wal_write_replicated, BEFORE that function returns (and thus
* before the caller can ACK). A persist-before-ACK regression test reads
* this to prove a durable sync ran inside the call — page-cache re-reads
* cannot distinguish fsync'd from cache-only, so a direct sync signal is
* required. Compiled out of production. */
atomic_uint test_replicated_fdatasync_count;
#endif
pthread_t fsync_thread;
pthread_mutex_t fsync_mutex; /* guards the fsync timer wait */
@ -265,6 +273,14 @@ uint64_t persist_test_durable_lsn_on_disk(persist_t* p);
* Lock-free atomic write; safe to flip from a test thread at any time.
* Compiled out of production (xce_controller links without it). */
void persist_test_set_force_fsync_fail(persist_t* p, int fail);
/* Read the standby-path fdatasync counter (task 2.3, persist-before-ACK
* regression). Counts the inline fdatasync calls made by
* persist_wal_write_replicated. A test snapshots this before the call and
* asserts it incremented after the call returns — proving the durable sync
* ran inside the persist primitive, BEFORE the caller can send its WalAck.
* Lock-free atomic read; compiled out of production. */
unsigned persist_test_replicated_fdatasync_count(persist_t* p);
#endif /* XCE_TESTING */
/* Checkpoint */