summaryrefslogtreecommitdiffstats
path: root/storage
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@yahooinc.com>2021-09-01 15:30:03 +0000
committerTor Brede Vekterli <vekterli@yahooinc.com>2021-09-02 13:36:58 +0000
commitd5330fe0f04a67393dae4547a81a48c260c59322 (patch)
tree68f9e49373324b1df22d93349fc5c9fb995fc0c5 /storage
parent25931432f58e53fb90068c143f61ee638dc54d69 (diff)
Port remaining legacy distributor tests to top-level test suite
Also fix a minor regression caused by the stripe cluster state change code path consulting a now unused part of the `StripeBucketDBUpdater` on whether a cluster state change implies bucket ownership change. This was used for adding a configurable safe period for client mutations to ensure distributors can't step on each others toes. The responsibility for telling stripes that state changes imply ownership changes has now been moved to the top-level DB updater and happens through the stripe guard interface instead.
Diffstat (limited to 'storage')
-rw-r--r--storage/src/tests/distributor/legacy_distributor_test.cpp12
-rw-r--r--storage/src/tests/distributor/mock_tickable_stripe.h2
-rw-r--r--storage/src/tests/distributor/simplemaintenancescannertest.cpp8
-rw-r--r--storage/src/tests/distributor/top_level_distributor_test.cpp141
-rw-r--r--storage/src/tests/distributor/top_level_distributor_test_util.cpp6
-rw-r--r--storage/src/tests/distributor/top_level_distributor_test_util.h2
-rw-r--r--storage/src/vespa/storage/distributor/bucketdbupdater.cpp8
-rw-r--r--storage/src/vespa/storage/distributor/bucketdbupdater.h3
-rw-r--r--storage/src/vespa/storage/distributor/distributor_stripe.cpp14
-rw-r--r--storage/src/vespa/storage/distributor/distributor_stripe.h3
-rw-r--r--storage/src/vespa/storage/distributor/multi_threaded_stripe_access_guard.cpp6
-rw-r--r--storage/src/vespa/storage/distributor/multi_threaded_stripe_access_guard.h3
-rw-r--r--storage/src/vespa/storage/distributor/stripe_access_guard.h3
-rw-r--r--storage/src/vespa/storage/distributor/tickable_stripe.h3
14 files changed, 188 insertions, 26 deletions
diff --git a/storage/src/tests/distributor/legacy_distributor_test.cpp b/storage/src/tests/distributor/legacy_distributor_test.cpp
index 1efe1119519..67441d5f7c0 100644
--- a/storage/src/tests/distributor/legacy_distributor_test.cpp
+++ b/storage/src/tests/distributor/legacy_distributor_test.cpp
@@ -701,7 +701,7 @@ TEST_F(LegacyDistributorTest, stats_generated_for_preempted_operations) {
}
}
-// TODO STRIPE -> distributor test
+// Migrated to TopLevelDistributorTest
TEST_F(LegacyDistributorTest, host_info_reporter_config_is_propagated_to_reporter) {
setupDistributor(Redundancy(2), NodeCount(2), "storage:2 distributor:1");
@@ -830,10 +830,7 @@ void LegacyDistributorTest::assertNoMessageBounced() {
ASSERT_EQ(0, _sender.replies().size());
}
-// TODO refactor this to set proper highest timestamp as part of bucket info
-// reply once we have the "highest timestamp across all owned buckets" feature
-// in place.
-// TODO STRIPE where does this truly belong?
+// Migrated to TopLevelDistributorTest
TEST_F(LegacyDistributorTest, configured_safe_time_point_rejection_works_end_to_end) {
setupDistributor(Redundancy(2), NodeCount(2),
"bits:1 storage:1 distributor:2");
@@ -1021,8 +1018,7 @@ void assert_invalid_stats_for_all_spaces(
}
// Migrated to DistributorStripeTest
-// TODO STRIPE must impl/test cross-stripe bucket space stats
-// TODO STRIPE cross-stripe recovery mode handling how?
+// Cross-stripe bucket stats test added in TopLevelDistributorTest::entering_recovery_mode_resets_bucket_space_stats_across_all_stripes
TEST_F(LegacyDistributorTest, entering_recovery_mode_resets_bucket_space_stats) {
// Set up a cluster state + DB contents which implies merge maintenance ops
setupDistributor(Redundancy(2), NodeCount(2), "version:1 distributor:1 storage:2");
@@ -1044,7 +1040,7 @@ TEST_F(LegacyDistributorTest, entering_recovery_mode_resets_bucket_space_stats)
assert_invalid_stats_for_all_spaces(stats, 2);
}
-// TODO: migrate to TopLevelDistributorTest
+// Migrated to TopLevelDistributorTest
TEST_F(LegacyDistributorTest, leaving_recovery_mode_immediately_sends_getnodestate_replies) {
setupDistributor(Redundancy(2), NodeCount(2), "version:1 distributor:1 storage:2");
// Should not send explicit replies during init stage
diff --git a/storage/src/tests/distributor/mock_tickable_stripe.h b/storage/src/tests/distributor/mock_tickable_stripe.h
index 532bef5e50d..17652d9cc50 100644
--- a/storage/src/tests/distributor/mock_tickable_stripe.h
+++ b/storage/src/tests/distributor/mock_tickable_stripe.h
@@ -13,7 +13,7 @@ struct MockTickableStripe : TickableStripe {
void update_distribution_config(const BucketSpaceDistributionConfigs&) override { abort(); }
void set_pending_cluster_state_bundle(const lib::ClusterStateBundle&) override { abort(); }
void clear_pending_cluster_state_bundle() override { abort(); }
- void enable_cluster_state_bundle(const lib::ClusterStateBundle&) override { abort(); }
+ void enable_cluster_state_bundle(const lib::ClusterStateBundle&, bool) override { abort(); }
void notify_distribution_change_enabled() override { abort(); }
PotentialDataLossReport remove_superfluous_buckets(document::BucketSpace, const lib::ClusterState&, bool) override {
abort();
diff --git a/storage/src/tests/distributor/simplemaintenancescannertest.cpp b/storage/src/tests/distributor/simplemaintenancescannertest.cpp
index 1bf3809b135..80b112625fb 100644
--- a/storage/src/tests/distributor/simplemaintenancescannertest.cpp
+++ b/storage/src/tests/distributor/simplemaintenancescannertest.cpp
@@ -294,4 +294,12 @@ TEST_F(SimpleMaintenanceScannerTest, merge_pending_maintenance_stats) {
EXPECT_EQ(exp.perNodeStats, result.perNodeStats);
}
+TEST_F(SimpleMaintenanceScannerTest, empty_bucket_db_is_immediately_done_by_default) {
+ auto res = _scanner->scanNext();
+ EXPECT_TRUE(res.isDone());
+ _scanner->reset();
+ res = _scanner->scanNext();
+ EXPECT_TRUE(res.isDone());
+}
+
}
diff --git a/storage/src/tests/distributor/top_level_distributor_test.cpp b/storage/src/tests/distributor/top_level_distributor_test.cpp
index 4968e8e6be3..a8ef6d990f0 100644
--- a/storage/src/tests/distributor/top_level_distributor_test.cpp
+++ b/storage/src/tests/distributor/top_level_distributor_test.cpp
@@ -90,6 +90,10 @@ struct TopLevelDistributorTest : Test, TopLevelDistributorTestUtil {
return _distributor->_threadPool;
}
+ DistributorHostInfoReporter& distributor_host_info_reporter() {
+ return _distributor->_hostInfoReporter;
+ }
+
const std::vector<std::shared_ptr<DistributorStatus>>& distributor_status_todos() {
return _distributor->_status_to_do;
}
@@ -98,6 +102,10 @@ struct TopLevelDistributorTest : Test, TopLevelDistributorTestUtil {
return _distributor->_metricUpdateHook;
}
+ BucketSpacesStatsProvider::PerNodeBucketSpacesStats distributor_bucket_spaces_stats() {
+ return _distributor->getBucketSpacesStats();
+ }
+
uint64_t db_sample_interval_sec() const noexcept {
// Sampling interval is equal across stripes, so just grab the first one and go with it.
return std::chrono::duration_cast<std::chrono::seconds>(
@@ -112,6 +120,28 @@ struct TopLevelDistributorTest : Test, TopLevelDistributorTestUtil {
return _node->getNodeStateUpdater().explicit_node_state_reply_send_invocations();
}
+ std::shared_ptr<api::RemoveCommand> make_dummy_remove_command() {
+ return std::make_shared<api::RemoveCommand>(
+ makeDocumentBucket(document::BucketId(0)),
+ document::DocumentId("id:foo:testdoctype1:n=1:foo"),
+ api::Timestamp(0));
+ }
+
+ void assert_single_reply_present_with_return_code(api::ReturnCode::Result expected_result) {
+ ASSERT_THAT(_sender.replies(), SizeIs(1)); // Single remove reply
+ ASSERT_EQ(_sender.reply(0)->getType(), api::MessageType::REMOVE_REPLY);
+ auto& reply(static_cast<api::RemoveReply&>(*_sender.reply(0)));
+ ASSERT_EQ(reply.getResult().getResult(), expected_result);
+ _sender.replies().clear();
+ }
+
+ void assert_single_bounced_remove_reply_present() {
+ assert_single_reply_present_with_return_code(api::ReturnCode::STALE_TIMESTAMP);
+ }
+
+ void assert_single_ok_remove_reply_present() {
+ assert_single_reply_present_with_return_code(api::ReturnCode::OK);
+ }
};
TopLevelDistributorTest::TopLevelDistributorTest()
@@ -141,8 +171,7 @@ TEST_F(TopLevelDistributorTest, external_operation_is_routed_to_expected_stripe)
}
TEST_F(TopLevelDistributorTest, recovery_mode_on_cluster_state_change_is_triggered_across_all_stripes) {
- setup_distributor(Redundancy(1), NodeCount(2),
- "storage:1 .0.s:d distributor:1");
+ setup_distributor(Redundancy(1), NodeCount(2), "storage:1 .0.s:d distributor:1");
enable_distributor_cluster_state("storage:1 distributor:1");
EXPECT_TRUE(all_distributor_stripes_are_in_recovery_mode());
@@ -432,4 +461,112 @@ TEST_F(TopLevelDistributorTest, non_bootstrap_host_info_send_request_delays_send
EXPECT_EQ(2, explicit_node_state_reply_send_invocations());
}
+TEST_F(TopLevelDistributorTest, host_info_reporter_config_is_propagated_to_reporter) {
+ setup_distributor(Redundancy(2), NodeCount(2), "storage:2 distributor:1");
+
+ // Default is enabled=true.
+ EXPECT_TRUE(distributor_host_info_reporter().isReportingEnabled());
+
+ auto cfg = current_distributor_config();
+ cfg.enableHostInfoReporting = false;
+ reconfigure(cfg);
+
+ EXPECT_FALSE(distributor_host_info_reporter().isReportingEnabled());
+}
+
+namespace {
+
+void assert_invalid_stats_for_all_spaces(
+ const BucketSpacesStatsProvider::PerNodeBucketSpacesStats& stats,
+ uint16_t node_index)
+{
+ auto stats_iter = stats.find(node_index);
+ ASSERT_TRUE(stats_iter != stats.cend());
+ ASSERT_EQ(2, stats_iter->second.size());
+ auto space_iter = stats_iter->second.find(document::FixedBucketSpaces::default_space_name());
+ ASSERT_TRUE(space_iter != stats_iter->second.cend());
+ ASSERT_FALSE(space_iter->second.valid());
+ space_iter = stats_iter->second.find(document::FixedBucketSpaces::global_space_name());
+ ASSERT_TRUE(space_iter != stats_iter->second.cend());
+ ASSERT_FALSE(space_iter->second.valid());
+}
+
+}
+
+TEST_F(TopLevelDistributorTest, entering_recovery_mode_resets_bucket_space_stats_across_all_stripes) {
+ // Set up a cluster state + DB contents which implies merge maintenance ops
+ setup_distributor(Redundancy(2), NodeCount(2), "version:1 distributor:1 storage:2");
+ add_nodes_to_stripe_bucket_db(document::BucketId(16, 1), "0=1/1/1/t/a");
+ add_nodes_to_stripe_bucket_db(document::BucketId(16, 2), "0=1/1/1/t/a");
+ add_nodes_to_stripe_bucket_db(document::BucketId(16, 3), "0=2/2/2/t/a");
+
+ tick_distributor_and_stripes_n_times(5); // Make sure all stripes have had ample time to update their stats
+
+ enable_distributor_cluster_state("version:2 distributor:1 storage:3 .1.s:d");
+ EXPECT_TRUE(all_distributor_stripes_are_in_recovery_mode());
+ // Bucket space stats should now be invalid per space per node, pending stats
+ // from state version 2. Exposing stats from version 1 risks reporting stale
+ // information back to the cluster controller.
+ const auto stats = distributor_bucket_spaces_stats();
+ ASSERT_EQ(2, stats.size());
+
+ assert_invalid_stats_for_all_spaces(stats, 0);
+ assert_invalid_stats_for_all_spaces(stats, 2);
+}
+
+TEST_F(TopLevelDistributorTest, leaving_recovery_mode_immediately_sends_getnodestate_replies) {
+ setup_distributor(Redundancy(2), NodeCount(2), "version:1 distributor:1 storage:2");
+ fake_clock().setAbsoluteTimeInSeconds(1000);
+ // Should not send explicit replies during init stage
+ ASSERT_EQ(0, explicit_node_state_reply_send_invocations());
+ // Add a couple of buckets so we have something to iterate over. 2 buckets
+ // map to the same stripe so we'll need 2 ticks to complete a full scan.
+ ASSERT_EQ(stripe_of_bucket(document::BucketId(16, 1)),
+ stripe_of_bucket(document::BucketId(16, 5)));
+
+ add_nodes_to_stripe_bucket_db(document::BucketId(16, 1), "0=1/1/1/t/a");
+ add_nodes_to_stripe_bucket_db(document::BucketId(16, 2), "0=1/1/1/t/a");
+ add_nodes_to_stripe_bucket_db(document::BucketId(16, 5), "0=1/1/1/t/a");
+
+ enable_distributor_cluster_state("version:2 distributor:1 storage:3 .1.s:d");
+ EXPECT_TRUE(all_distributor_stripes_are_in_recovery_mode());
+ EXPECT_EQ(0, explicit_node_state_reply_send_invocations());
+ tick_distributor_and_stripes_n_times(1); // DB round not yet complete
+ EXPECT_EQ(0, explicit_node_state_reply_send_invocations());
+ tick_distributor_and_stripes_n_times(4); // DB round complete on all stripes
+ EXPECT_EQ(1, explicit_node_state_reply_send_invocations());
+ EXPECT_FALSE(all_distributor_stripes_are_in_recovery_mode());
+ // Now out of recovery mode, subsequent round completions should not send replies
+ tick_distributor_and_stripes_n_times(10);
+ EXPECT_EQ(1, explicit_node_state_reply_send_invocations());
+}
+
+// TODO refactor this to set proper highest timestamp as part of bucket info
+// reply once we have the "highest timestamp across all owned buckets" feature
+// in place.
+TEST_F(TopLevelDistributorTest, configured_safe_time_point_rejection_works_end_to_end) {
+ setup_distributor(Redundancy(2), NodeCount(2), "storage:1 distributor:2");
+ fake_clock().setAbsoluteTimeInSeconds(1000);
+
+ auto cfg = current_distributor_config();
+ cfg.maxClusterClockSkewSec = 10;
+ reconfigure(cfg);
+
+ // State with changed bucket ownership; should enforce safe mutation time points
+ enable_distributor_cluster_state("storage:1 distributor:1", true);
+
+ handle_top_level_message(make_dummy_remove_command());
+ tick_distributor_and_stripes_n_times(1); // Process queued message
+ ASSERT_NO_FATAL_FAILURE(assert_single_bounced_remove_reply_present());
+
+ // Increment time to first whole second of clock + 10 seconds of skew.
+ // Should now not get any feed rejections.
+ fake_clock().setAbsoluteTimeInSeconds(1011);
+
+ handle_top_level_message(make_dummy_remove_command());
+ tick_distributor_and_stripes_n_times(1); // Process queued message
+ // We don't have any buckets in our DB so we'll get an OK remove reply back (nothing to remove!)
+ ASSERT_NO_FATAL_FAILURE(assert_single_ok_remove_reply_present());
+}
+
}
diff --git a/storage/src/tests/distributor/top_level_distributor_test_util.cpp b/storage/src/tests/distributor/top_level_distributor_test_util.cpp
index 657d49bbffb..3fe801ab000 100644
--- a/storage/src/tests/distributor/top_level_distributor_test_util.cpp
+++ b/storage/src/tests/distributor/top_level_distributor_test_util.cpp
@@ -305,10 +305,12 @@ TopLevelDistributorTestUtil::all_distributor_stripes_are_in_recovery_mode() cons
}
void
-TopLevelDistributorTestUtil::enable_distributor_cluster_state(vespalib::stringref state)
+TopLevelDistributorTestUtil::enable_distributor_cluster_state(vespalib::stringref state,
+ bool has_bucket_ownership_transfer)
{
bucket_db_updater().simulate_cluster_state_bundle_activation(
- lib::ClusterStateBundle(lib::ClusterState(state)));
+ lib::ClusterStateBundle(lib::ClusterState(state)),
+ has_bucket_ownership_transfer);
}
void
diff --git a/storage/src/tests/distributor/top_level_distributor_test_util.h b/storage/src/tests/distributor/top_level_distributor_test_util.h
index 9a5260bad7e..134b88b3567 100644
--- a/storage/src/tests/distributor/top_level_distributor_test_util.h
+++ b/storage/src/tests/distributor/top_level_distributor_test_util.h
@@ -128,7 +128,7 @@ protected:
MessageSenderImpl _message_sender;
uint32_t _num_distributor_stripes;
- void enable_distributor_cluster_state(vespalib::stringref state);
+ void enable_distributor_cluster_state(vespalib::stringref state, bool has_bucket_ownership_transfer = false);
void enable_distributor_cluster_state(const lib::ClusterStateBundle& state);
};
diff --git a/storage/src/vespa/storage/distributor/bucketdbupdater.cpp b/storage/src/vespa/storage/distributor/bucketdbupdater.cpp
index e407d57fd43..112b9e8fd8a 100644
--- a/storage/src/vespa/storage/distributor/bucketdbupdater.cpp
+++ b/storage/src/vespa/storage/distributor/bucketdbupdater.cpp
@@ -424,12 +424,14 @@ BucketDBUpdater::enable_current_cluster_state_bundle_in_distributor_and_stripes(
LOG(debug, "BucketDBUpdater finished processing state %s",
state.getBaselineClusterState()->toString().c_str());
- guard.enable_cluster_state_bundle(state);
+ guard.enable_cluster_state_bundle(state, _pending_cluster_state->hasBucketOwnershipTransfer());
}
-void BucketDBUpdater::simulate_cluster_state_bundle_activation(const lib::ClusterStateBundle& activated_state) {
+void BucketDBUpdater::simulate_cluster_state_bundle_activation(const lib::ClusterStateBundle& activated_state,
+ bool has_bucket_ownership_transfer)
+{
auto guard = _stripe_accessor.rendezvous_and_hold_all();
- guard->enable_cluster_state_bundle(activated_state);
+ guard->enable_cluster_state_bundle(activated_state, has_bucket_ownership_transfer);
_active_state_bundle = activated_state;
propagate_active_state_bundle_internally();
diff --git a/storage/src/vespa/storage/distributor/bucketdbupdater.h b/storage/src/vespa/storage/distributor/bucketdbupdater.h
index 0fded3e5a65..3cb87347a8f 100644
--- a/storage/src/vespa/storage/distributor/bucketdbupdater.h
+++ b/storage/src/vespa/storage/distributor/bucketdbupdater.h
@@ -78,7 +78,8 @@ private:
// Only to be used by tests that want to ensure both the BucketDBUpdater _and_ the Distributor
// components agree on the currently active cluster state bundle.
// Transitively invokes Distributor::enableClusterStateBundle
- void simulate_cluster_state_bundle_activation(const lib::ClusterStateBundle& activated_state);
+ void simulate_cluster_state_bundle_activation(const lib::ClusterStateBundle& activated_state,
+ bool has_bucket_ownership_transfer = false);
bool should_defer_state_enabling() const noexcept;
bool has_pending_cluster_state() const;
diff --git a/storage/src/vespa/storage/distributor/distributor_stripe.cpp b/storage/src/vespa/storage/distributor/distributor_stripe.cpp
index 837193a1e7c..1050f511ad6 100644
--- a/storage/src/vespa/storage/distributor/distributor_stripe.cpp
+++ b/storage/src/vespa/storage/distributor/distributor_stripe.cpp
@@ -320,7 +320,8 @@ DistributorStripe::enableClusterStateBundle(const lib::ClusterStateBundle& state
}
}
- if (_bucketDBUpdater.bucketOwnershipHasChanged()) {
+ // TODO STRIPE remove when legacy is gone; the stripe bucket DB updater does not have this info!
+ if (_use_legacy_mode && _bucketDBUpdater.bucketOwnershipHasChanged()) {
using TimePoint = OwnershipTransferSafeTimePointCalculator::TimePoint;
// Note: this assumes that std::chrono::system_clock and the framework
// system clock have the same epoch, which should be a reasonable
@@ -981,10 +982,19 @@ DistributorStripe::clear_pending_cluster_state_bundle()
}
void
-DistributorStripe::enable_cluster_state_bundle(const lib::ClusterStateBundle& new_state)
+DistributorStripe::enable_cluster_state_bundle(const lib::ClusterStateBundle& new_state,
+ bool has_bucket_ownership_change)
{
// TODO STRIPE replace legacy func
enableClusterStateBundle(new_state);
+ if (has_bucket_ownership_change) {
+ using TimePoint = OwnershipTransferSafeTimePointCalculator::TimePoint;
+ // Note: this assumes that std::chrono::system_clock and the framework
+ // system clock have the same epoch, which should be a reasonable
+ // assumption.
+ const auto now = TimePoint(std::chrono::milliseconds(_component.getClock().getTimeInMillis().getTime()));
+ _externalOperationHandler.rejectFeedBeforeTimeReached(_ownershipSafeTimeCalc->safeTimePoint(now));
+ }
}
void
diff --git a/storage/src/vespa/storage/distributor/distributor_stripe.h b/storage/src/vespa/storage/distributor/distributor_stripe.h
index 38667859cfd..e8dd4a1f3a7 100644
--- a/storage/src/vespa/storage/distributor/distributor_stripe.h
+++ b/storage/src/vespa/storage/distributor/distributor_stripe.h
@@ -273,7 +273,8 @@ private:
void update_total_distributor_config(std::shared_ptr<const DistributorConfiguration> config) override;
void set_pending_cluster_state_bundle(const lib::ClusterStateBundle& pending_state) override;
void clear_pending_cluster_state_bundle() override;
- void enable_cluster_state_bundle(const lib::ClusterStateBundle& new_state) override;
+ void enable_cluster_state_bundle(const lib::ClusterStateBundle& new_state,
+ bool has_bucket_ownership_change) override;
void notify_distribution_change_enabled() override;
PotentialDataLossReport remove_superfluous_buckets(document::BucketSpace bucket_space,
const lib::ClusterState& new_state,
diff --git a/storage/src/vespa/storage/distributor/multi_threaded_stripe_access_guard.cpp b/storage/src/vespa/storage/distributor/multi_threaded_stripe_access_guard.cpp
index 80af41e57ad..359621425b2 100644
--- a/storage/src/vespa/storage/distributor/multi_threaded_stripe_access_guard.cpp
+++ b/storage/src/vespa/storage/distributor/multi_threaded_stripe_access_guard.cpp
@@ -51,9 +51,11 @@ void MultiThreadedStripeAccessGuard::clear_pending_cluster_state_bundle() {
});
}
-void MultiThreadedStripeAccessGuard::enable_cluster_state_bundle(const lib::ClusterStateBundle& new_state) {
+void MultiThreadedStripeAccessGuard::enable_cluster_state_bundle(const lib::ClusterStateBundle& new_state,
+ bool has_bucket_ownership_change)
+{
for_each_stripe([&](TickableStripe& stripe) {
- stripe.enable_cluster_state_bundle(new_state);
+ stripe.enable_cluster_state_bundle(new_state, has_bucket_ownership_change);
});
}
diff --git a/storage/src/vespa/storage/distributor/multi_threaded_stripe_access_guard.h b/storage/src/vespa/storage/distributor/multi_threaded_stripe_access_guard.h
index da5fd8e5f37..62af21cc43f 100644
--- a/storage/src/vespa/storage/distributor/multi_threaded_stripe_access_guard.h
+++ b/storage/src/vespa/storage/distributor/multi_threaded_stripe_access_guard.h
@@ -34,7 +34,8 @@ public:
void update_distribution_config(const BucketSpaceDistributionConfigs& new_configs) override;
void set_pending_cluster_state_bundle(const lib::ClusterStateBundle& pending_state) override;
void clear_pending_cluster_state_bundle() override;
- void enable_cluster_state_bundle(const lib::ClusterStateBundle& new_state) override;
+ void enable_cluster_state_bundle(const lib::ClusterStateBundle& new_state,
+ bool has_bucket_ownership_change) override;
void notify_distribution_change_enabled() override;
PotentialDataLossReport remove_superfluous_buckets(document::BucketSpace bucket_space,
diff --git a/storage/src/vespa/storage/distributor/stripe_access_guard.h b/storage/src/vespa/storage/distributor/stripe_access_guard.h
index a1779a4eb4f..70f3ce846ea 100644
--- a/storage/src/vespa/storage/distributor/stripe_access_guard.h
+++ b/storage/src/vespa/storage/distributor/stripe_access_guard.h
@@ -37,7 +37,8 @@ public:
virtual void update_distribution_config(const BucketSpaceDistributionConfigs& new_configs) = 0;
virtual void set_pending_cluster_state_bundle(const lib::ClusterStateBundle& pending_state) = 0;
virtual void clear_pending_cluster_state_bundle() = 0;
- virtual void enable_cluster_state_bundle(const lib::ClusterStateBundle& new_state) = 0;
+ virtual void enable_cluster_state_bundle(const lib::ClusterStateBundle& new_state,
+ bool has_bucket_ownership_change) = 0;
virtual void notify_distribution_change_enabled() = 0;
virtual PotentialDataLossReport remove_superfluous_buckets(document::BucketSpace bucket_space,
diff --git a/storage/src/vespa/storage/distributor/tickable_stripe.h b/storage/src/vespa/storage/distributor/tickable_stripe.h
index 8d077455a48..ba74184313b 100644
--- a/storage/src/vespa/storage/distributor/tickable_stripe.h
+++ b/storage/src/vespa/storage/distributor/tickable_stripe.h
@@ -39,7 +39,8 @@ public:
virtual void update_distribution_config(const BucketSpaceDistributionConfigs& new_configs) = 0;
virtual void set_pending_cluster_state_bundle(const lib::ClusterStateBundle& pending_state) = 0;
virtual void clear_pending_cluster_state_bundle() = 0;
- virtual void enable_cluster_state_bundle(const lib::ClusterStateBundle& new_state) = 0;
+ virtual void enable_cluster_state_bundle(const lib::ClusterStateBundle& new_state,
+ bool has_bucket_ownership_change) = 0;
virtual void notify_distribution_change_enabled() = 0;
virtual PotentialDataLossReport remove_superfluous_buckets(document::BucketSpace bucket_space,