-
Notifications
You must be signed in to change notification settings - Fork 8.8k
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
TSDB: Don't rely on integer overflow in head compaction check #13755
Conversation
Don't compact the Head block if there have not yet been any samples appended. Previously, the logic for determining if the head should be compacted relied on the default values for min and max time and integer overflow when they were checked in `Head.compactable()`. The check in `Head.compactable()` effectively did `math.MinInt64 - math.MaxInt64` which overflowed and wrapped to `1`. Since `1` is less than `1.5` times the chunk range, compaction did not happen. This was the correct behavior but relying on overflow wrapping is surprising. This change add a method for checking if the min and max time for the head is unset and uses it to short-circuit compaction in that case. It also replaces several explicit checks for the default value to determine if the head has not yet had any samples added. Signed-off-by: Nick Pillitteri <nick.pillitteri@grafana.com>
fb95d6f
to
97bcb00
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great find.
Signed-off-by: Nick Pillitteri <nick.pillitteri@grafana.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you adjust the PR title and the commit? They insinuates the compaction is currently triggered when the head isn't initialized, which isn't what you explain in the description.
How about embracing/making use of the overflow instead and just add an explicit regression test for it?
Sure.
I'm not sure what you mean. Let the check overflow but add a test that ensures |
Signed-off-by: Nick Pillitteri <nick.pillitteri@grafana.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, both approaches suit me.
Thanks.
Let's see what the others think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks sensible and makes the code more consistent. The one thing that I would like to see is a testcase in TestNoEmptyBlocks
in db_test.go
that fails with the old code - due to it not checking that the data is valid.
I'm not actually sure I can do this. The old code worked correctly, it just relied on integer overflow which was confusing. In both the old code and the new code, |
This synthetic test fails on main I think:
|
Ah, I see. I'll add something like that. Thank you! |
Signed-off-by: Nick Pillitteri <nick.pillitteri@grafana.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Signed-off-by: Nick Pillitteri <nick.pillitteri@grafana.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Don't rely on integer overflow for correct behavior in the
Head.compactable()
check.Previously, the logic for determining if the head should be compacted relied on the default values for min and max time and integer overflow when they were checked in
Head.compactable()
. The check inHead.compactable()
effectively didmath.MinInt64 - math.MaxInt64
which overflowed and wrapped to1
. Since1
is less than1.5
times the chunk range, compaction did not happen. This was the correct behavior but relying on overflow wrapping is surprising.This change adds a method for checking if the min time for the head is unset and uses it to short-circuit compaction in that case. It also replaces several explicit checks for the default value to determine if the head has not yet had any samples added.