mirror of
https://github.com/facebook/rocksdb.git
synced 2025-04-20 03:20:00 +08:00
Write failure can be permanently fatal and break WriteBatch atomicity (#13428)
Summary: This adds a test that attempts DeleteRange() with PlainTable (not supported) and shows that it not only puts the DB in failed write mode, it (a) breaks WriteBatch atomicity for readers, because they can see just part of a failed WriteBatch, and (b) makes the DB not recoverable (without manual intervention) if using WAL. Note: WriteBatch atomicity is not clearly documented but indicated at the top of write_batch.h and the wiki page for Transactions, even without Transactions. Pull Request resolved: https://github.com/facebook/rocksdb/pull/13428 Test Plan: this is the test Reviewed By: anand1976 Differential Revision: D70332226 Pulled By: pdillinger fbshipit-source-id: 67bc4de68833a80578e48baa9d3a4f23f1600f3c
This commit is contained in:
parent
d1f383b8eb
commit
ebaeb03648
@ -1338,6 +1338,50 @@ TEST_P(PlainTableDBTest, AdaptiveTable) {
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(PlainTableDBTest, PlainTableDBTest, ::testing::Bool());
|
||||
|
||||
TEST_P(PlainTableDBTest, DeleteRangeNotSupported) {
|
||||
// XXX: After attempting DeleteRange with PlainTable, Writes will permanently
|
||||
// fail. Even if re-opening the DB, if WAL is used, the WAL is not recoverable
|
||||
// (without manual intervention). Furthermore, a partial write batch can
|
||||
// be exposed to readers, breaking WriteBatch atomicity.
|
||||
for (bool use_write_batch : {/*false, */ true}) {
|
||||
DestroyAndReopen();
|
||||
|
||||
ASSERT_OK(Put("a0001111", "1"));
|
||||
ASSERT_OK(Put("b0001111", "2"));
|
||||
ASSERT_OK(Put("c0001111", "3"));
|
||||
if (use_write_batch) {
|
||||
WriteBatch wb;
|
||||
ASSERT_OK(wb.Put("d0001111", "4"));
|
||||
ASSERT_OK(wb.DeleteRange("a", "b"));
|
||||
ASSERT_OK(wb.Put("e0001111", "5"));
|
||||
ASSERT_EQ(dbfull()->Write({}, &wb).code(), Status::Code::kNotSupported);
|
||||
} else {
|
||||
ASSERT_EQ(dbfull()->DeleteRange({}, "az", "bz").code(),
|
||||
Status::Code::kNotSupported);
|
||||
}
|
||||
ASSERT_EQ(Get("a0001111"), "1");
|
||||
ASSERT_EQ(Get("b0001111"), "2");
|
||||
ASSERT_EQ(Get("c0001111"), "3");
|
||||
if (use_write_batch) {
|
||||
// XXX: broken WriteBatch atomicity
|
||||
ASSERT_EQ(Get("d0001111"), "4");
|
||||
} else {
|
||||
ASSERT_EQ(Get("d0001111"), "NOT_FOUND");
|
||||
}
|
||||
ASSERT_EQ(Get("e0001111"), "NOT_FOUND");
|
||||
|
||||
ASSERT_EQ(Put("e0001111", "5").code(), Status::Code::kNotSupported);
|
||||
ASSERT_EQ(Get("e0001111"), "NOT_FOUND");
|
||||
|
||||
// Even trying to flush
|
||||
ASSERT_EQ(dbfull()->TEST_FlushMemTable().code(),
|
||||
Status::Code::kNotSupported);
|
||||
|
||||
// XXX: WAL is not recoverable
|
||||
ASSERT_EQ(TryReopen().code(), Status::Code::kNotSupported);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ROCKSDB_NAMESPACE
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user