diff --git a/db/write_batch.cc b/db/write_batch.cc index 3b7e49bbe..021af9c0d 100644 --- a/db/write_batch.cc +++ b/db/write_batch.cc @@ -405,9 +405,11 @@ Status WriteBatch::Iterate(Handler* handler) const { Status s; char tag = 0; uint32_t column_family = 0; // default - while ((s.ok() || UNLIKELY(s.IsTryAgain())) && !input.empty() && + bool last_was_try_again = false; + while (((s.ok() && !input.empty()) || UNLIKELY(s.IsTryAgain())) && handler->Continue()) { if (LIKELY(!s.IsTryAgain())) { + last_was_try_again = false; tag = 0; column_family = 0; // default @@ -418,6 +420,13 @@ Status WriteBatch::Iterate(Handler* handler) const { } } else { assert(s.IsTryAgain()); + assert(!last_was_try_again); // to detect infinite loop bugs + if (UNLIKELY(last_was_try_again)) { + return Status::Corruption( + "two consecutive TryAgain in WriteBatch handler; this is either a " + "software bug or data corruption."); + } + last_was_try_again = true; s = Status::OK(); } diff --git a/utilities/transactions/transaction_test.h b/utilities/transactions/transaction_test.h index cf7e08a50..56d3d6e2e 100644 --- a/utilities/transactions/transaction_test.h +++ b/utilities/transactions/transaction_test.h @@ -359,12 +359,8 @@ class TransactionTestBase : public ::testing::Test { WriteBatch wb; committed_kvs[k] = v; wb.Put(k, v); - // TODO(myabandeh): remove this when we supprot duplicate keys in - // db->Write method - if (false) { - committed_kvs[k] = v2; - wb.Put(k, v2); - } + committed_kvs[k] = v2; + wb.Put(k, v2); s = db->Write(write_options, &wb); ASSERT_OK(s); } break; @@ -376,12 +372,8 @@ class TransactionTestBase : public ::testing::Test { committed_kvs[k] = v; s = txn->Put(k, v); ASSERT_OK(s); - // TODO(myabandeh): remove this when we supprot duplicate keys in - // db->Write method - if (false) { - committed_kvs[k] = v2; - s = txn->Put(k, v2); - } + committed_kvs[k] = v2; + s = txn->Put(k, v2); ASSERT_OK(s); if (type == 3) { s = txn->Prepare();