Commit 2c41609
perf(persistence): move WAL v3 fsync off the shard event loop (#238)
WalWriterV3::flush_sync() ran fdatasync synchronously on the shard
event-loop thread — every fsync stalled the shard (no SPSC drain, no
conn I/O, no CDC fan-out until the disk acks). GCE pd baseline
(tmp/WALV3-OFFLOOP-FSYNC.md §8, c2d-standard-16, 3 reps): the everysec
1s timer froze every connection on the shard for 10-16 ms once per
second whenever the WAL held real bytes, and appendfsync=always paid
-20% RPS / ~2x tail (p999 5.4ms -> 9.8ms) on top of the AOF cost.
Design (spec §3, Option A — fsync offload with a durable-LSN watermark):
the writer keeps encode/buffer/page-cache-write/rotate/recycle on the
shard thread; ONLY the fsync moves.
- New src/persistence/wal_v3/sync_agent.rs: per-shard WalSyncAgent
std::thread receives fd-dup'd SyncRequests over flume::bounded(8) and
publishes a monotonic durable-LSN watermark (AtomicU64 fetch_max)
after each successful fdatasync. fd-dup shares the file description,
and write_all happens-before try_clone on the shard thread, so each
fsync covers all previously written bytes; rotation stays safe because
rotate_segment already fsyncs the old segment inline before switching.
- WalWriterV3::request_sync(): non-blocking initiation. Queue-full /
dup-failure / agent-spawn-failure all fall back to inline fsync — a
durability request is never dropped. Agent spawn is lazy (first call)
and never retried after a failure (warn once, inline forever).
- WalWriterV3::wait_durable(lsn, timeout): bounded blocking wait, used
ONLY by the two checkpoint ordering invariants and shutdown:
* log-before-data (flush_dirty_pages page gate, persistence_tick)
* WAL-before-manifest (checkpoint Finalize now waits on the actual
checkpoint record LSN before manifest.commit())
Both bounded by WAIT_DURABLE_TIMEOUT (5s); failure aborts that
checkpoint step (retried next tick) so redo_lsn never advances past
durability.
- Failure policy: an fsync error POISONS the agent permanently (POSIX
post-error fsync semantics are undefined) with tracing::error!;
subsequent request_sync/wait_durable fail loudly and the checkpoint
stalls rather than silently opening a data-loss window.
- Call sites: timers::sync_wal_v3 (everysec) and both runtimes'
appendfsync=always per-drain-batch syncs use request_sync(); shutdown
paths keep inline flush_sync() (which now also publishes the
watermark, as does rotation). everysec semantics become "sync
initiated every 1s, durable typically ms later" — the same window the
AOF everysec writers provide.
Testing (red/green per tmp/WALV3-OFFLOOP-FSYNC.md §4):
- 7 unit tests in sync_agent.rs with a gated/failing injectable fsync
backend: watermark-advances-only-after-fsync, wait-blocks-then-
returns, wait-timeout, poison-fails-loud (wakes parked waiters, never
publishes, refuses new requests), backpressure-hands-request-back,
drop-drains-pending-syncs, watermark-monotonic.
- 2 writer-level tests in segment.rs: request_sync+wait_durable covers
all appends (bytes verified on disk), wait_durable fast paths.
- tests/loom_wal_sync_agent.rs: loom model of the watermark/poison
monitor (no lost wakeup: publisher takes the mutex before notify,
waiter re-checks under it) + std smoke variant when not under loom.
Gates (this worktree): fmt clean; clippy 0 warnings both feature sets
(1 pre-existing vendored-monoio warning); cargo test --lib 3864 passed
(monoio) + 3143 passed (tokio); cargo test --no-run compiles all
targets on both feature sets.
Refs: tmp/WALV3-OFFLOOP-FSYNC.md (spec + GCE baseline), stacked on
refactor/wal-v3-only (PR #236).
author: Tin Dang
Co-authored-by: Tin Dang <tindang.ht97@gmail.com>1 parent 340dbdd commit 2c41609
8 files changed
Lines changed: 854 additions & 15 deletions
File tree
- src
- persistence/wal_v3
- shard
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
9 | 34 | | |
10 | 35 | | |
11 | 36 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
124 | 124 | | |
125 | 125 | | |
126 | 126 | | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
127 | 133 | | |
128 | 134 | | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
129 | 139 | | |
130 | 140 | | |
131 | 141 | | |
| |||
158 | 168 | | |
159 | 169 | | |
160 | 170 | | |
| 171 | + | |
| 172 | + | |
161 | 173 | | |
162 | 174 | | |
163 | 175 | | |
| |||
203 | 215 | | |
204 | 216 | | |
205 | 217 | | |
206 | | - | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
207 | 221 | | |
208 | 222 | | |
209 | 223 | | |
210 | 224 | | |
211 | 225 | | |
212 | 226 | | |
213 | 227 | | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
214 | 233 | | |
215 | 234 | | |
216 | 235 | | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
217 | 323 | | |
218 | 324 | | |
219 | 325 | | |
| |||
445 | 551 | | |
446 | 552 | | |
447 | 553 | | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
448 | 561 | | |
449 | 562 | | |
450 | 563 | | |
| |||
726 | 839 | | |
727 | 840 | | |
728 | 841 | | |
| 842 | + | |
| 843 | + | |
| 844 | + | |
| 845 | + | |
| 846 | + | |
| 847 | + | |
| 848 | + | |
| 849 | + | |
| 850 | + | |
| 851 | + | |
| 852 | + | |
| 853 | + | |
| 854 | + | |
| 855 | + | |
| 856 | + | |
| 857 | + | |
| 858 | + | |
| 859 | + | |
| 860 | + | |
| 861 | + | |
| 862 | + | |
| 863 | + | |
| 864 | + | |
| 865 | + | |
| 866 | + | |
| 867 | + | |
| 868 | + | |
| 869 | + | |
| 870 | + | |
| 871 | + | |
| 872 | + | |
| 873 | + | |
| 874 | + | |
| 875 | + | |
| 876 | + | |
| 877 | + | |
| 878 | + | |
| 879 | + | |
| 880 | + | |
| 881 | + | |
| 882 | + | |
| 883 | + | |
| 884 | + | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
| 892 | + | |
| 893 | + | |
| 894 | + | |
| 895 | + | |
| 896 | + | |
| 897 | + | |
| 898 | + | |
| 899 | + | |
| 900 | + | |
729 | 901 | | |
730 | 902 | | |
731 | 903 | | |
| |||
0 commit comments