feat(ha-config-bootstrap): wire repl_wait_majority_ack into persist_wal_sync_append (task 7.6)
This commit is contained in:
parent
85c8565957
commit
684d3b6608
2 changed files with 21 additions and 8 deletions
|
|
@ -181,7 +181,7 @@ Dependency order: startup validation (D) unblocks vtaskmgr before election (A);
|
||||||
- _Requirements: 5.6, 5.7_
|
- _Requirements: 5.6, 5.7_
|
||||||
- _Boundary: Persistence Layer (persist.c, persist.h)_
|
- _Boundary: Persistence Layer (persist.c, persist.h)_
|
||||||
|
|
||||||
- [ ] 7.6 Wire majority-commit into persist_wal_sync_append()
|
- [x] 7.6 Wire majority-commit into persist_wal_sync_append()
|
||||||
- In `persist_wal_sync_append()`: after local write + fsync for `WAL_JOB_SUBMIT`, `WAL_JOB_START`, `WAL_JOB_FINISH`, `WAL_QUEUE_CHANGE` → call `repl_broadcast(c, OP_walAck, payload, len)` + `repl_wait_majority_ack(c, commit_timeout_ms, OP_walAck)` → on quorum advance `committed_lsn`
|
- In `persist_wal_sync_append()`: after local write + fsync for `WAL_JOB_SUBMIT`, `WAL_JOB_START`, `WAL_JOB_FINISH`, `WAL_QUEUE_CHANGE` → call `repl_broadcast(c, OP_walAck, payload, len)` + `repl_wait_majority_ack(c, commit_timeout_ms, OP_walAck)` → on quorum advance `committed_lsn`
|
||||||
- `WAL_HOST_STATE`, `WAL_CHECKPOINT_REF` bypass to `persist_wal_async()` (unchanged)
|
- `WAL_HOST_STATE`, `WAL_CHECKPOINT_REF` bypass to `persist_wal_async()` (unchanged)
|
||||||
- `make test` passes; integration test verifies committed WAL entries survive failover
|
- `make test` passes; integration test verifies committed WAL entries survive failover
|
||||||
|
|
|
||||||
|
|
@ -1005,21 +1005,34 @@ int persist_wal_sync_append(persist_t* p, uint32_t type,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For sync replication (WAL_JOB_SUBMIT): wait for at least one standby ACK.
|
/* Majority-commit replication (Req 5.1–5.3).
|
||||||
|
* After local fsync via persist_wal_async, wait for majority quorum ACK.
|
||||||
|
* On quorum: advance committed_lsn. On no standbys or timeout: degraded.
|
||||||
* We use current_lsn - 1 because persist_wal_async already incremented it. */
|
* We use current_lsn - 1 because persist_wal_async already incremented it. */
|
||||||
uint64_t written_lsn;
|
uint64_t written_lsn;
|
||||||
pthread_mutex_lock(&p->lock);
|
pthread_mutex_lock(&p->lock);
|
||||||
written_lsn = p->current_lsn - 1;
|
written_lsn = p->current_lsn - 1;
|
||||||
pthread_mutex_unlock(&p->lock);
|
pthread_mutex_unlock(&p->lock);
|
||||||
|
|
||||||
int sync_err = repl_wait_ack(&p->repl, written_lsn,
|
/* No standbys registered → degraded mode immediately (no quorum to wait for) */
|
||||||
p->config.sync_timeout_ms);
|
mylock_lock(&p->repl.lock);
|
||||||
if (sync_err < 0)
|
int has_standbys = (p->repl.nstandbys > 0);
|
||||||
CTRL_METRIC_INC(ctrl_repl_degraded_count);
|
mylock_unlock(&p->repl.lock);
|
||||||
|
|
||||||
|
int sync_err;
|
||||||
|
if (!has_standbys) {
|
||||||
|
sync_err = -ENODEV;
|
||||||
|
} else {
|
||||||
|
sync_err = repl_wait_majority_ack(&p->repl, p->config.sync_timeout_ms,
|
||||||
|
(uint8_t)OPCode_walAck);
|
||||||
|
if (sync_err == 0)
|
||||||
|
atomic_store_explicit(&p->committed_lsn, written_lsn, memory_order_release);
|
||||||
|
else
|
||||||
|
CTRL_METRIC_INC(ctrl_repl_degraded_count);
|
||||||
|
}
|
||||||
if (sync_rc_out)
|
if (sync_rc_out)
|
||||||
*sync_rc_out = sync_err;
|
*sync_rc_out = sync_err;
|
||||||
/* -ETIMEDOUT = degraded mode (local-only durability); -ENODEV = no standbys.
|
/* sync_err < 0 = degraded mode (local-only durability); continue operating. */
|
||||||
* Both are acceptable — primary continues operating. */
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue