rocksdb/utilities/transactions/snapshot_checker.cc
Yi Wu 128f532858 WritePrepared: fix issue with snapshot released during compaction (#4858)
Summary:
Compaction iterator keep a copy of list of live snapshots at the beginning of compaction, and then query snapshot checker to verify if values of a sequence number is visible to these snapshots. However when the snapshot is released in the middle of compaction, the snapshot checker implementation (i.e. WritePreparedSnapshotChecker) may remove info with the snapshot and may report incorrect result, which lead to values being compacted out when it shouldn't. This patch conservatively keep the values if snapshot checker determines that the snapshots is released.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/4858

Differential Revision: D13617146

Pulled By: maysamyabandeh

fbshipit-source-id: cf18a94f6f61a94bcff73c280f117b224af5fbc3
2019-01-16 09:55:32 -08:00

50 lines
1.6 KiB
C++

// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
// This source code is licensed under both the GPLv2 (found in the
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).
#include "db/snapshot_checker.h"
#ifdef ROCKSDB_LITE
#include <assert.h>
#endif // ROCKSDB_LITE
#include "utilities/transactions/write_prepared_txn_db.h"
namespace rocksdb {
#ifdef ROCKSDB_LITE
WritePreparedSnapshotChecker::WritePreparedSnapshotChecker(
WritePreparedTxnDB* /*txn_db*/) {}
SnapshotCheckerResult WritePreparedSnapshotChecker::CheckInSnapshot(
SequenceNumber /*sequence*/, SequenceNumber /*snapshot_sequence*/) const {
// Should never be called in LITE mode.
assert(false);
return SnapshotCheckerResult::kInSnapshot;
}
#else
WritePreparedSnapshotChecker::WritePreparedSnapshotChecker(
WritePreparedTxnDB* txn_db)
: txn_db_(txn_db){};
SnapshotCheckerResult WritePreparedSnapshotChecker::CheckInSnapshot(
SequenceNumber sequence, SequenceNumber snapshot_sequence) const {
bool snapshot_released = false;
// TODO(myabandeh): set min_uncommitted
bool in_snapshot = txn_db_->IsInSnapshot(
sequence, snapshot_sequence, 0 /*min_uncommitted*/, &snapshot_released);
if (snapshot_released) {
return SnapshotCheckerResult::kSnapshotReleased;
}
return in_snapshot ? SnapshotCheckerResult::kInSnapshot
: SnapshotCheckerResult::kNotInSnapshot;
}
#endif // ROCKSDB_LITE
DisableGCSnapshotChecker DisableGCSnapshotChecker::instance_;
} // namespace rocksdb