Make the db_stress reopen loop in OperateDb() more robust (#5893)

Summary:
The loop in OperateDb() is getting quite complicated with the introduction of multiple key operations such as MultiGet and Reseeks. This is resulting in a number of corner cases that hangs db_stress due to synchronization problems during reopen (i.e when -reopen=<> option is specified). This PR makes it more robust by ensuring all db_stress threads vote to reopen the DB the exact same number of times.
Most of the changes in this diff are due to indentation.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/5893

Test Plan: Run crash test

Differential Revision: D17823827

Pulled By: anand1976

fbshipit-source-id: ec893829f611ac7cac4057c0d3d99f9ffb6a6dd9
main
anand76 5 years ago committed by Facebook Github Bot
parent 5b123813f8
commit 80ad996b35
  1. 17
      tools/db_stress.cc

@ -2087,18 +2087,11 @@ class StressTest {
const uint64_t ops_per_open = FLAGS_ops_per_thread / (FLAGS_reopen + 1); const uint64_t ops_per_open = FLAGS_ops_per_thread / (FLAGS_reopen + 1);
thread->stats.Start(); thread->stats.Start();
for (uint64_t i = 0, prev_i = 0; i < FLAGS_ops_per_thread; i++) { for (int open_cnt = 0; open_cnt <= FLAGS_reopen; ++open_cnt) {
if (thread->shared->HasVerificationFailedYet()) { if (thread->shared->HasVerificationFailedYet()) {
break; break;
} }
// In case i is incremented more than once due to multiple operations, if (open_cnt != 0) {
// such as MultiGet or iterator seeks, check whether we have crossed
// the ops_per_open boundary in the previous iteration. If it did,
// then vote to reopen
if (i != 0 &&
(i % ops_per_open == 0 ||
i % ops_per_open < prev_i % ops_per_open)) {
{
thread->stats.FinishedSingleOp(); thread->stats.FinishedSingleOp();
MutexLock l(thread->shared->GetMutex()); MutexLock l(thread->shared->GetMutex());
while (!thread->snapshot_queue.empty()) { while (!thread->snapshot_queue.empty()) {
@ -2117,8 +2110,11 @@ class StressTest {
// Commenting this out as we don't want to reset stats on each open. // Commenting this out as we don't want to reset stats on each open.
// thread->stats.Start(); // thread->stats.Start();
} }
for (uint64_t i = 0; i < ops_per_open; i++) {
if (thread->shared->HasVerificationFailedYet()) {
break;
} }
prev_i = i;
// Change Options // Change Options
if (FLAGS_set_options_one_in > 0 && if (FLAGS_set_options_one_in > 0 &&
@ -2372,6 +2368,7 @@ class StressTest {
} }
#endif #endif
} }
}
while (!thread->snapshot_queue.empty()) { while (!thread->snapshot_queue.empty()) {
db_->ReleaseSnapshot(thread->snapshot_queue.front().second.snapshot); db_->ReleaseSnapshot(thread->snapshot_queue.front().second.snapshot);
delete thread->snapshot_queue.front().second.key_vec; delete thread->snapshot_queue.front().second.key_vec;

Loading…
Cancel
Save