Skip to content

Commit afdbcc0

Browse files
authored
Introduce SuperSnapshot (#292)
Summary: SuperSnapshot is a combination of a snapshot and a super-version. They fulfill the same goal as snapshots, i.e. provide a consistent view of the database. However, unlike snapshots, they also pin the current super-version (memtable, immutable memtable list and file LSM tree). In that way they are similar to iterators, which also pin the current super-version for the duration of their lifetime. Test Plan: Added a basic unit test. Reviewers:
1 parent 016ce15 commit afdbcc0

File tree

7 files changed

+306
-18
lines changed

7 files changed

+306
-18
lines changed

cloud/replication_test.cc

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,6 @@ size_t ReplicationTest::catchUpFollower(
467467
},
468468
allow_new_manifest_writes, &info, flags);
469469
assert(s.ok());
470-
assert(info.mismatched_epoch_num == 0);
471470
++ret;
472471
}
473472
if (info.has_new_manifest_writes) {
@@ -1279,6 +1278,86 @@ TEST_F(ReplicationTest, EpochNumberSimple) {
12791278
verifyEqual();
12801279
}
12811280

1281+
TEST_F(ReplicationTest, SuperSnapshot) {
1282+
auto options = leaderOptions();
1283+
options.disable_auto_compactions = true;
1284+
auto leader = openLeader();
1285+
auto follower = openFollower();
1286+
1287+
createColumnFamily("cf1");
1288+
1289+
ASSERT_OK(leader->Put(wo(), "k1", "v1"));
1290+
ASSERT_OK(leader->Put(wo(), leaderCF("cf1"), "cf1k1", "cf1v1"));
1291+
ASSERT_OK(leader->Flush({}));
1292+
catchUpFollower();
1293+
1294+
std::vector<ColumnFamilyHandle*> cf;
1295+
cf.push_back(follower->DefaultColumnFamily());
1296+
cf.push_back(followerCF("cf1"));
1297+
std::vector<const Snapshot*> snapshots;
1298+
ASSERT_OK(follower->GetSuperSnapshots(cf, &snapshots));
1299+
1300+
ASSERT_OK(leader->Put(wo(), "k1", "v2"));
1301+
ASSERT_OK(leader->Put(wo(), leaderCF("cf1"), "cf1k1", "cf1v2"));
1302+
ASSERT_OK(leader->Flush({}));
1303+
auto leaderFull = static_cast_with_check<DBImpl>(leader);
1304+
ASSERT_OK(leaderFull->TEST_CompactRange(0, nullptr, nullptr, nullptr, true));
1305+
ASSERT_OK(leaderFull->TEST_CompactRange(0, nullptr, nullptr, leaderCF("cf1"),
1306+
true));
1307+
1308+
catchUpFollower();
1309+
1310+
ReadOptions ro;
1311+
std::string val;
1312+
ASSERT_OK(follower->Get(ro, "k1", &val));
1313+
EXPECT_EQ(val, "v2");
1314+
ro.snapshot = snapshots[0];
1315+
ASSERT_OK(follower->Get(ro, "k1", &val));
1316+
EXPECT_EQ(val, "v1");
1317+
1318+
auto iter = follower->NewIterator(ro, follower->DefaultColumnFamily());
1319+
iter->SeekToFirst();
1320+
EXPECT_TRUE(iter->Valid());
1321+
EXPECT_EQ(iter->key(), "k1");
1322+
EXPECT_EQ(iter->value(), "v1");
1323+
iter->Next();
1324+
EXPECT_FALSE(iter->Valid());
1325+
1326+
ro.snapshot = nullptr;
1327+
ASSERT_OK(follower->Get(ro, followerCF("cf1"), "cf1k1", &val));
1328+
EXPECT_EQ(val, "cf1v2");
1329+
ro.snapshot = snapshots[1];
1330+
ASSERT_OK(follower->Get(ro, followerCF("cf1"), "cf1k1", &val));
1331+
EXPECT_EQ(val, "cf1v1");
1332+
1333+
// Test MultiGet
1334+
std::vector<Slice> keys;
1335+
keys.push_back("cf1k1");
1336+
keys.push_back("missing");
1337+
std::vector<ColumnFamilyHandle*> cfs;
1338+
cfs.push_back(followerCF("cf1"));
1339+
cfs.push_back(followerCF("cf1"));
1340+
std::vector<std::string> vals;
1341+
1342+
auto statuses = follower->MultiGet(ro, cfs, keys, &vals);
1343+
ASSERT_OK(statuses[0]);
1344+
ASSERT_TRUE(statuses[1].IsNotFound());
1345+
ASSERT_EQ(vals[0], "cf1v1");
1346+
1347+
ro.snapshot = nullptr;
1348+
statuses = follower->MultiGet(ro, cfs, keys, &vals);
1349+
ASSERT_OK(statuses[0]);
1350+
ASSERT_TRUE(statuses[1].IsNotFound());
1351+
ASSERT_EQ(vals[0], "cf1v2");
1352+
1353+
// Column family <-> snapshot mismatch
1354+
ro.snapshot = snapshots[0];
1355+
ASSERT_FALSE(follower->Get(ro, followerCF("cf1"), "cf1k1", &val).ok());
1356+
1357+
follower->ReleaseSnapshot(snapshots[0]);
1358+
follower->ReleaseSnapshot(snapshots[1]);
1359+
}
1360+
12821361
} // namespace ROCKSDB_NAMESPACE
12831362

12841363
// A black-box test for the cloud wrapper around rocksdb

0 commit comments

Comments
 (0)