Repository navigation
perf(engine): append logged feed events during recovery without decoding them - #100
Merged
Merged
Conversation
…ing them Recovery decoded every Feed record in the replayed part of the WAL into a CommitEvent, and ChangeFeed.append then either dropped it (the feed already held that generation, which is the usual case after a process crash) or encoded it again. The WAL payload is already the FeedCodec bytes the feed stores, so recovery now hands it to ChangeFeed.appendEncoded, which reads the generation from the start of the payload and writes the bytes as they are. At scale 1 of the benchmark this was about a quarter of the bytes allocated while replaying the log. Recovery.recover no longer needs the FeedCodec.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Opening a crashed store replays the WAL written since the last checkpoint. Each replayed commit's
Feedrecord was decoded into aCommitEventand passed toChangeFeed.append. After a process crash the feed file usually already holds that generation, so the decoded event was thrown away. Otherwise it was encoded again into the same bytes.The WAL payload is exactly the
FeedCodecencoding the feed stores. Recovery now passes it toChangeFeed.appendEncoded, which reads the generation from the start of the payload (FeedCodec.generationOf) and writes the bytes unchanged unless the feed already has that generation.Recovery.recoverno longer takes aFeedCodec. No file format, default or setting changes.Allocation, main against this branch
Crashed copies of benchmark stores (ingest killed with SIGKILL after half the nodes were acknowledged,
asyncdurability), opened in warmed-up JVMs, two JVMs of 12 opens per variant, main and branch alternating. The first two opens of each JVM are dropped, which leaves 20 per variant. Allocation is the opening thread's allocated bytes, median per open:So about 20 MiB less per scale-1 open (18 to 19%) and 30 MiB less at scale 4 (12%). Every open recovered the same node count on both sides (26,000 and 101,000). I'm not quoting times: other builds were running and the startup checkpoint's page writes varied by an order of magnitude between runs.
Tests
FeedRecoveryTest.recoveryDecodesEachLoggedValueOnceregisters a slot whose codec counts decodes, commits 20 values, halts and reopens. Recovery decodes each value once on this branch (20) and twice on main (40).recoveryRestoresFeedEventsTheFeedLostdeletes the feed files after a crash and checks that recovery writes back the same events and the data is intact.Where the rest of a scale-1 crash open goes
This doesn't close the gap to HyperGraphDB on the
recoverworkload at scale 1, and it isn't meant to. With HyperGraphDB measured in the same window, the crashed scale-1 store opened in a median of 253 ms for HStore and 162 ms for HyperGraphDB (15 opens each), with 116,012 KiB and 80,486 KiB allocated. The difference is how much work each store left for recovery:checkpoint_wal_mb(256) and the write buffer never got past half ofwrite_buffer_mb(64), so the catalog still holds the empty initial image. The open replays all 28 commits (the whole 26,000-node load, 72 ms median), then the startup checkpoint writes every page of the store (74 ms median) and does about 35 ms of fsyncs (catalog 16.9, page sync 5.3, reference journal 5.3, WAL 3.8, applying the journal 4.0).DbPrintLog -Son a crashed HyperGraphDB copy shows two checkpoints in its 24 MB log and 749,476 bytes after the last one, with at most 9,690 records to replay. Its redo phase took 58 ms median and its own recovery checkpoint 20.5 ms.At scale 4 the HStore child does checkpoint before the kill, so the copy above replays 39 commits instead of the whole load. I didn't break down HyperGraphDB's side at scale 4.