aboutsummaryrefslogtreecommitdiffstats
path: root/storage/src/tests/distributor/bucket_db_prune_elision_test.cpp
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@verizonmedia.com>2019-04-29 14:57:46 +0000
committerTor Brede Vekterli <vekterli@verizonmedia.com>2019-04-29 15:14:50 +0000
commit4a2642f2f11526ccc183e331f0644afa89bbf028 (patch)
treeba98d1b9650c075d83973601d9a470a59faf9f2f /storage/src/tests/distributor/bucket_db_prune_elision_test.cpp
parentc9f9f467df69a65fe1a403f58411259e3c0fa823 (diff)
Elide bucket DB pruning scans when possible
Only do a (potentially expensive) pruning pass over the bucket DB when the cluster state transition indicates that one or more nodes are not in the same availability-state as the currently active state. For instance, if a cluster state change is for a content node going from Maintenance to Down, no pruning action is required since that shall already have taken place during the processing of the initial Down edge (and no buckets shall have been created for it in the meantime). We do not currently attempt to elide distribution config changes, as these happen much more rarely than cluster state changes.
Diffstat (limited to 'storage/src/tests/distributor/bucket_db_prune_elision_test.cpp')
-rw-r--r--storage/src/tests/distributor/bucket_db_prune_elision_test.cpp119
1 files changed, 119 insertions, 0 deletions
diff --git a/storage/src/tests/distributor/bucket_db_prune_elision_test.cpp b/storage/src/tests/distributor/bucket_db_prune_elision_test.cpp
new file mode 100644
index 00000000000..4821d05a90c
--- /dev/null
+++ b/storage/src/tests/distributor/bucket_db_prune_elision_test.cpp
@@ -0,0 +1,119 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <vespa/storage/distributor/bucket_db_prune_elision.h>
+#include <vespa/vdslib/state/clusterstate.h>
+#include <gtest/gtest.h>
+
+using namespace ::testing;
+
+namespace storage::distributor {
+
+namespace {
+
+lib::ClusterState state_of(const char* str) {
+ return lib::ClusterState(str);
+}
+
+}
+
+TEST(IdempotentStateTransitionTest, state_differing_only_in_version_allows_elision) {
+ EXPECT_TRUE(db_pruning_may_be_elided(state_of("version:1 bits:8 distributor:3 storage:3"),
+ state_of("version:2 bits:8 distributor:3 storage:3")));
+}
+
+TEST(IdempotentStateTransitionTest, differing_cluster_state_disallows_elision) {
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("cluster:d distributor:3 storage:3"),
+ state_of("distributor:3 storage:3")));
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("distributor:3 storage:3"),
+ state_of("cluster:d distributor:3 storage:3")));
+}
+
+TEST(IdempotentStateTransitionTest, differing_distribution_bit_count_disallows_elision) {
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("bits:8 distributor:3 storage:3"),
+ state_of("bits:9 distributor:3 storage:3")));
+ // No explicit "bits:" implies 16 bits
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("bits:8 distributor:3 storage:3"),
+ state_of("distributor:3 storage:3")));
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("distributor:3 storage:3"),
+ state_of("bits:8 distributor:3 storage:3")));
+}
+
+TEST(IdempotentStateTransitionTest, same_implicit_distribution_bit_count_allows_elision) {
+ EXPECT_TRUE(db_pruning_may_be_elided(state_of("distributor:3 storage:3"),
+ state_of("bits:16 distributor:3 storage:3")));
+}
+
+TEST(IdempotentStateTransitionTest, changed_distributor_node_count_disallows_elision) {
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("distributor:3 storage:3"),
+ state_of("distributor:4 storage:3")));
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("distributor:4 storage:3"),
+ state_of("distributor:3 storage:3")));
+}
+
+TEST(IdempotentStateTransitionTest, changed_distributor_node_state_disallows_elision) {
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("distributor:3 .0.s:d storage:3"),
+ state_of("distributor:3 storage:3")));
+
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("distributor:3 storage:3"),
+ state_of("distributor:3 .0.s:d storage:3")));
+
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("distributor:3 .0.s:d storage:3"),
+ state_of("distributor:3 .0.s:u storage:3")));
+
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("distributor:3 .0.s:d storage:3"),
+ state_of("distributor:3 .1.s:d storage:3")));
+}
+
+TEST(IdempotentStateTransitionTest, changed_storage_node_count_disallows_elision) {
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("distributor:3 storage:3"),
+ state_of("distributor:3 storage:4")));
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("distributor:3 storage:4"),
+ state_of("distributor:3 storage:3")));
+}
+
+TEST(IdempotentStateTransitionTest, changed_storage_node_state_disallows_elision) {
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("distributor:3 storage:3 .0.s:d"),
+ state_of("distributor:3 storage:3")));
+
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("distributor:3 storage:3"),
+ state_of("distributor:3 storage:3 .0.s:d")));
+
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("distributor:3 storage:3 .0.s:d"),
+ state_of("distributor:3 storage:3 .0.s:u")));
+
+ EXPECT_FALSE(db_pruning_may_be_elided(state_of("distributor:3 storage:3 .0.s:d"),
+ state_of("distributor:3 storage:3 .1.s:d")));
+}
+
+TEST(IdempotentStateTransitionTest, may_elide_for_transition_between_different_effective_storage_down_states) {
+ // Maintenance -> Down edge shall already have pruned DB on Maintenance edge
+ EXPECT_TRUE(db_pruning_may_be_elided(state_of("distributor:3 storage:3 .0.s:m"),
+ state_of("distributor:3 storage:3 .0.s:d")));
+
+ // Down -> Maintenance edge shall already have pruned DB on Down edge
+ EXPECT_TRUE(db_pruning_may_be_elided(state_of("distributor:3 storage:3 .0.s:d"),
+ state_of("distributor:3 storage:3 .0.s:m")));
+}
+
+TEST(IdempotentStateTransitionTest, may_elide_for_transition_between_different_effective_storage_up_states) {
+ EXPECT_TRUE(db_pruning_may_be_elided(state_of("distributor:3 storage:3 .0.s:i"),
+ state_of("distributor:3 storage:3")));
+
+ EXPECT_TRUE(db_pruning_may_be_elided(state_of("distributor:3 storage:3 .1.s:r"),
+ state_of("distributor:3 storage:3")));
+ EXPECT_TRUE(db_pruning_may_be_elided(state_of("distributor:3 storage:3"),
+ state_of("distributor:3 storage:3 .2.s:r")));
+}
+
+// Changed startup timestamps imply that bucket info should be fetched from a node, but
+// does not imply that pruning is required.
+TEST(IdempotentStateTransitionTest, may_elide_changed_startup_timestamps) {
+ EXPECT_TRUE(db_pruning_may_be_elided(state_of("distributor:3 storage:3"),
+ state_of("distributor:3 storage:3 .0.t:123456")));
+ EXPECT_TRUE(db_pruning_may_be_elided(state_of("distributor:3 storage:3 .0.t:123456"),
+ state_of("distributor:3 storage:3")));
+ EXPECT_TRUE(db_pruning_may_be_elided(state_of("distributor:3 storage:3 .0.t:123456"),
+ state_of("distributor:3 storage:3 .0.t:654321")));
+}
+
+}