@@ -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