mirror of
https://github.com/scylladb/scylladb.git
synced 2026-06-01 04:26:48 +00:00
group0_state_machine: use correct comparison for timeuuids in merger
In d2a4079bbe, `merger` was modified so
that when we merge a command, `last_group0_state_id` is taken to be the
maximum of the merged command's state_id and the current
`last_group0_state_id`. This is necessary for achieving the same
behavior as if the commands were applied individually instead of being
merged -- where we take the maximum state ID from `group0_history` table
which was applied until now (because the table is sorted using the state
IDs and we take the greatest row).
However, a subtle bug was introduced -- the `std::max` function uses the
`utils::UUID` standard comparison operator which is unfortunately not
the same as timeuuid comparison that Scylla performs when sorting the
`group0_history` table. So in rare cases it could return the *smaller*
of the two timeuuids w.r.t. the correct timeuuid ordering. This would
then lead to commands being applied which should have been turned to
no-ops due to the `prev_state_id` check -- and then, for example,
permanent schema desync or worse.
Fix it by using the correct comparison method.
Fixes: #14600
This commit is contained in:
@@ -121,7 +121,12 @@ future<> group0_state_machine::apply(std::vector<raft::command_cref> command) {
|
||||
void add(group0_command&& cmd, size_t added_size) {
|
||||
slogger.trace("add to merging set new_state_id: {}", cmd.new_state_id);
|
||||
auto m = convert_history_mutation(std::move(cmd.history_append), sm._sp.data_dictionary());
|
||||
last_group0_state_id = std::max(last_group0_state_id, cmd.new_state_id);
|
||||
// Set `last_group0_state_id` to the maximum of the current value and `cmd.new_state_id`,
|
||||
// but make sure we compare them the same way timeuuids are compared in clustering keys
|
||||
// (i.e. in the same order that the history table is sorted).
|
||||
if (utils::timeuuid_tri_compare(last_group0_state_id, cmd.new_state_id) < 0) {
|
||||
last_group0_state_id = cmd.new_state_id;
|
||||
}
|
||||
cmd_to_merge.push_back(std::move(cmd));
|
||||
size += added_size;
|
||||
if (merged_history_mutation) {
|
||||
|
||||
Reference in New Issue
Block a user