release: document gentle upgrade from 0.16.25 → 0.16.26 - #2745
Merged
Conversation
matklad
approved these changes
Feb 19, 2025
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.
Upgrade from 0.16.25 → 0.16.26 has a known bug wherein if a replica on 0.16.25 state syncs with the help of a replica on 0.16.26, it enters a crash loop when it restarts into 0.16.26. This PR documents this bug in the changelog, so that users can exercise caution while upgrading from 0.16.25 → 0.16.26.
Detailed explanation of the bug
If a lagging replica running on 0.16.25 uses a SV message from a replica running on 0.16.26 for state sync, then it is likely to hit this bug. When the lagging 0.16.25 replica accepts a SV message from a 0.16.26 replica and starts up in 0.16.26, it panics on the following assert (in assert_free_set_consistent).
This is a storage determinism bug. The main problem here is that starting 0.16.26 (as of #2600), we've changed our CheckpointState format, where we encode both the blocks_acquired and blocks_released free set bitsets in the checkpoint. Additionally, we carry over blocks_released till a checkpoint becomes durable, and then flip it (as opposed to our older logic wherein we flipped it at checkpoint).
To roll out this change, 0.16.26 contains logic to send both the old and the new CheckpointState format, so that older replicas can use this CheckpointState for state sync. However, while sending the older CheckpointState, we lose information about blocks_released, which is now non-empty in the checkpoint. So, if a 0.16.25 accepts this old Checkpoint state and restarts in 0.16.26, it starts up with an empty bitset as opposed to the actual, non-empty blocks_released (which all other replicas that went through the non-state-sync route are aware of). While the above assert did save us from an actual non deterministic storage, this is a problem regardless, because the upgrade path from 0.16.25 → 0.16.26 is broken in this case.