Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(LSM): restructure Compaction to cleanup and handle concurrent IO / CPU asserts #146

Merged
merged 21 commits into from
Sep 19, 2022

Conversation

kprotty
Copy link
Contributor

@kprotty kprotty commented Aug 31, 2022

Restructured the Compaction struct to clean up control flow and get rid of various asserts being tripped regarding concurrent IO and CPU work. This is the first step to addressing the table_count_visible assertion hit in VOPR seed 545.

@jorangreef
Copy link
Member

@kprotty what is the next step to get this fixed? What can we try here?

@kprotty kprotty force-pushed the lsm-table-visibility branch 2 times, most recently from 2575c05 to b54d176 Compare September 9, 2022 03:04
@kprotty
Copy link
Contributor Author

kprotty commented Sep 12, 2022

@jorangreef I've pivoted this PR into restructuring the Compaction and addressing various asserts that were hit along the way.

@kprotty kprotty changed the title WIP - fixing table visibility assertions in LSM fix(LSM): restructure Compaction to cleanup and handle concurrent IO / CPU asserts Sep 12, 2022
@kprotty kprotty force-pushed the lsm-table-visibility branch 2 times, most recently from aa68eb8 to 61e6cf4 Compare September 15, 2022 15:54
@kprotty kprotty marked this pull request as ready for review September 15, 2022 15:54
src/lsm/compaction.zig Outdated Show resolved Hide resolved
src/lsm/compaction.zig Outdated Show resolved Hide resolved
src/lsm/compaction.zig Outdated Show resolved Hide resolved
src/lsm/compaction.zig Show resolved Hide resolved
src/lsm/compaction.zig Show resolved Hide resolved
src/lsm/compaction.zig Show resolved Hide resolved
src/lsm/grid.zig Show resolved Hide resolved
src/lsm/manifest.zig Outdated Show resolved Hide resolved
src/lsm/tree.zig Outdated Show resolved Hide resolved
src/lsm/tree.zig Show resolved Hide resolved
@kprotty kprotty force-pushed the lsm-table-visibility branch from 08e7c39 to 5804f07 Compare September 16, 2022 21:25
src/lsm/tree.zig Outdated Show resolved Hide resolved
King Butcher and others added 12 commits September 19, 2022 12:37
…nfoBuffer

The assertions were overly tight and assumed the tables reported from the iterator intersected with the key range hint.
Instead, the tables should only overlap as asserted elsewhere.

The function also implemented its own form of TableInfoBuffer() so went ahead and used the shared abstraction.
Tried to restructure the Compaction type implementation as an attempt to simplify control flow for analysis.
This currently errors out with a rogue Grid.Write having its callback triggered.
I was using `inline for` to generate the callbacks for the Compaction's BlockWrites to Grid. This had unexpected behavior where it cached the callback for the first field so the other fields used the wrong one. Moving the per-field writing to its own function solved this.

Also took the opportunity to clean up the control flow and assert orderings in the Tree compact code:
- Now, invisible tables are removed from `level_b` and happen when a compaction completes instead of when all compactions for that half measure complete.
- The `mut_table.can_commit_batch` assert was also moved after mut_table is sorted into immut_table.
Given IO is now serialized with CPU merge, we don't need the intermediary blocks for index, data, and filter. They now point directly do the Table.Builder's blocks for writing.

We also know that tables reported by the iterator_b (LevelIterator) will always be visible to the compaction snapshot so they can be queued for removal/updating.

Finally, moved around the check for a full data block to after builder.data_block_finish() was called as that's when it writes the block's vsr.Header to work correctly with the table helpers.
Since snapshots are no longer as unique as they once were (with compaction updating with snapshots from the past), the visibility asserts don't have to be as strict in their ranges.
These tables will be deleted so their Grid blocks can be re-used. It should also be safe to release their blocks in the iterator_b callback as iterator_b (LevelIterator) makes a copy of the block contents itself.
The level_a selected table and the overlapping level_b tables are merged into new tables inserted into level_b. The old input level_b tables were already being removed, so this removes the selected level_a one as well.
The manifest_log was using the superblock's free_set directly to acquire/release block addresses. This conflicts with it also using the Grid for read/write.

Grid read/writes require that the block addresses you pass in to be from its own acquire/release since those update its cache. The ManifestLog was not doing this so we address that here.
Grid read iops can be observed to have empty `read` FIFOs during Grid.read_block_callback. There, the if branch pops from the FIFO and invokes their callbacks. On the last pop, the FIFO can be empty and the callback could iterate the iops expecting their FIFO's to not be empty.
Brings back merge_done and makes MergeIterator optional to represent .idle state.
kprotty added 9 commits September 19, 2022 12:37
While scanning for invisible tables in a level, we may fill up the table buffer and flush/remove them from the level. When scanning in ascending order, this could invalidate the references from the iterator.

Instead, scan in descending order to ensure the tables we queue and potentially flush/remove have already been visited.
There's a slight change here in that snapshot_min check is now inclusive while snapshot_max remains exclusive.
The old pattern would enforce that pending blocks at a tick are written out on the next tick. This instead gathers pending blocks across multiple ticks until they either get full or there's no more values to merge.
They're allocated with the expected maximum so overflow to flush to manifest mid-enqueue should never occur.
@kprotty kprotty force-pushed the lsm-table-visibility branch from 32d2609 to 14ff227 Compare September 19, 2022 17:37
@kprotty kprotty merged commit 6debc66 into main Sep 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants