migration_manager: also reload schema on enabling digest_insensitive_to_expiry
Currently, when said feature is enabled, we recalcuate the schema digest. But this feature also influences how table versions are calculated, so it has to trigger a recalculation of all table versions, so that we can guarantee correct versions. Before, this used to happen by happy accident. Another feature -- table_digest_insensitive_to_expiry -- used to take care of this, by triggering a table version recalulation. However this feature only takes effect if digest_insensitive_to_expiry is also enabled. This used to be the case incidently, by the time the reload triggered by table_digest_insensitive_to_expiry ran, digest_insensitive_to_expiry was already enabled. But this was not guaranteed whatsoever and as we've recently seen, any change to the feature list, which changes the order in which features are enabled, can cause this intricate balance to break. This patch makes digest_insensitive_to_expiry also kick off a schema reload, to eliminate our dependence on (unguaranteed) feature order, and to guarantee that table schemas have a correct version after all features are enabled. In fact, all schema feature notification handlers now kick off a full schema reload, to ensure bugs like this don't creep in, in the future. Fixes: #16004 Closes scylladb/scylladb#16013 (cherry picked from commit22381441b0) (cherry picked from commite31f2224f5)
This commit is contained in:
committed by
Tomasz Grabiec
parent
2ea211db69
commit
c9fa077c82
@@ -86,27 +86,26 @@ future<> migration_manager::drain()
|
||||
|
||||
void migration_manager::init_messaging_service()
|
||||
{
|
||||
auto update_schema = [this] {
|
||||
//FIXME: future discarded.
|
||||
(void)with_gate(_background_tasks, [this] {
|
||||
mlogger.debug("features changed, recalculating schema version");
|
||||
return db::schema_tables::recalculate_schema_version(_sys_ks, _storage_proxy.container(), _feat);
|
||||
auto reload_schema_in_bg = [this] {
|
||||
(void) with_gate(_background_tasks, [this] {
|
||||
return reload_schema().handle_exception([] (std::exception_ptr ep) {
|
||||
// Due to features being unordered, reload might fail because
|
||||
// some tables still have the wrong version and looking up e.g.
|
||||
// the base-table of a view will fail.
|
||||
mlogger.debug("Failed to reload schema: {}", ep);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if (this_shard_id() == 0) {
|
||||
_feature_listeners.push_back(_feat.view_virtual_columns.when_enabled(update_schema));
|
||||
_feature_listeners.push_back(_feat.digest_insensitive_to_expiry.when_enabled(update_schema));
|
||||
_feature_listeners.push_back(_feat.cdc.when_enabled(update_schema));
|
||||
_feature_listeners.push_back(_feat.per_table_partitioners.when_enabled(update_schema));
|
||||
_feature_listeners.push_back(_feat.computed_columns.when_enabled(update_schema));
|
||||
_feature_listeners.push_back(_feat.view_virtual_columns.when_enabled(reload_schema_in_bg));
|
||||
_feature_listeners.push_back(_feat.digest_insensitive_to_expiry.when_enabled(reload_schema_in_bg));
|
||||
_feature_listeners.push_back(_feat.cdc.when_enabled(reload_schema_in_bg));
|
||||
_feature_listeners.push_back(_feat.per_table_partitioners.when_enabled(reload_schema_in_bg));
|
||||
_feature_listeners.push_back(_feat.computed_columns.when_enabled(reload_schema_in_bg));
|
||||
|
||||
if (!_feat.table_digest_insensitive_to_expiry) {
|
||||
_feature_listeners.push_back(_feat.table_digest_insensitive_to_expiry.when_enabled([this] {
|
||||
(void) with_gate(_background_tasks, [this] {
|
||||
return reload_schema();
|
||||
});
|
||||
}));
|
||||
_feature_listeners.push_back(_feat.table_digest_insensitive_to_expiry.when_enabled(reload_schema_in_bg));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user