Add support for vacuuming partial deletes during CHECKPOINT #9931
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.
Fixes #109
This PR adds support for vacuuming deletes within row groups during a checkpoint. The way that this works is that adjacent row groups are merged together if possible by checking if adjacent row groups can be folded into fewer row groups. For example, consider the following row groups with the given number of non-deleted rows:
After this PR, the checkpoint will observe that row groups
#1
and#2
can be merged together into a single row group, and move the database to the following state:The row groups are re-written with only the valid rows, and the old row groups are dropped, removing the deleted rows from the system and freeing up blocks.
Merges are performed with either 1, 2 or 3 target row groups. We always prefer merging into fewer target row groups as that is cheaper from a performance perspective. That means we need to have at least 25% deletions within adjacent row group before merges are performed and rows are cleaned up automatically. If too few rows are deleted they will not be cleaned up and we will write tombstones as is currently the case.
Merge into one row group (requires >= 50% deleted)
Merge into two row groups (requires >= 33% deleted)
Merge into three row groups (requires >= 25% deleted)
Performance
This PR increases the work that is done during checkpointing significantly when partial deletes are performed. Since checkpointing is currently still single-threaded, performance of large
DELETE
statements can drop significantly. For example, in this extreme scenario performance drops by a factor of ~15:The reason for this degradation is that in the old delete code we would only write deleted markers for the deleted rows, whereas in this new extreme scenario we end up rewriting half the table (the non-deleted rows).
On the flip side, because deletes are cleaned up, performance of running queries on the table afterwards is sped up since we no longer need to scan deleted rows when executing queries. Running TPC-H Q1 on the lineitem table after the deletion has the following performance:
The more deletions we run, the worse the performance impact of leaving them around. For example, with the following chain of deletions/insertions we get the following timings:
While performance should always drop when cleaning up deletes it is especially problematic now because we are doing single-threaded checkpoints. This should be addressed in a future PR and will greatly alleviate the performance problem here.