summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Gottlieb <daniel.gottlieb@mongodb.com>2022-07-25 14:45:21 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-07-26 17:57:14 +0000
commitc90a8e578049d9921175fcd7db5f3e1becfa9076 (patch)
treed0567a9d61ea12801e13f225a95f837510287703 /src
parentaa6a253f8b9c9023377870d47240784679077a0a (diff)
downloadmongo-c90a8e578049d9921175fcd7db5f3e1becfa9076.tar.gz
SERVER-65971: Have _restoreTxnsTableEntryFromRetryableWrites declare its intent as an untimestamped write.
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/index/index_build_interceptor.cpp9
-rw-r--r--src/mongo/db/index_builds_coordinator.cpp19
-rw-r--r--src/mongo/db/repair.cpp7
-rw-r--r--src/mongo/db/repl/oplog_applier_impl_test.cpp5
-rw-r--r--src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp4
-rw-r--r--src/mongo/db/repl/oplog_applier_test.cpp5
-rw-r--r--src/mongo/db/repl/replication_recovery_test.cpp15
-rw-r--r--src/mongo/db/repl/rollback_impl.cpp1
-rw-r--r--src/mongo/db/repl/storage_timestamp_test.cpp13
-rw-r--r--src/mongo/db/service_context_d_test_fixture.cpp5
-rw-r--r--src/mongo/db/storage/recovery_unit.h6
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block.cpp4
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block.h13
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block_bm.cpp12
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp7
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp15
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp18
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.h6
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.cpp4
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.h2
20 files changed, 114 insertions, 56 deletions
diff --git a/src/mongo/db/index/index_build_interceptor.cpp b/src/mongo/db/index/index_build_interceptor.cpp
index 6061ea3b90f..b27c7169d1a 100644
--- a/src/mongo/db/index/index_build_interceptor.cpp
+++ b/src/mongo/db/index/index_build_interceptor.cpp
@@ -162,6 +162,15 @@ Status IndexBuildInterceptor::drainWritesIntoIndex(OperationContext* opCtx,
// Returns true if the cursor has reached the end of the table, false if there are more records,
// and an error Status otherwise.
auto applySingleBatch = [&]() -> StatusWith<bool> {
+ // This write is performed without a durable/commit timestamp. This transaction trips the
+ // ordered assertion for the side-table documents which are inserted with a timestamp and,
+ // in here, being deleted without a timestamp. Because the data being read is majority
+ // committed, there's no risk of needing to roll back the writes done by this "drain".
+ //
+ // Note that index builds will only "resume" once. A second resume results in the index
+ // build starting from scratch. A "resumed" index build does not use a majority read
+ // concern. And thus will observe data that can be rolled back via replication.
+ opCtx->recoveryUnit()->allowUntimestampedWrite();
WriteUnitOfWork wuow(opCtx);
int32_t batchSize = 0;
diff --git a/src/mongo/db/index_builds_coordinator.cpp b/src/mongo/db/index_builds_coordinator.cpp
index 30b66e249b5..0c3cea6fc00 100644
--- a/src/mongo/db/index_builds_coordinator.cpp
+++ b/src/mongo/db/index_builds_coordinator.cpp
@@ -191,6 +191,11 @@ void removeIndexBuildEntryAfterCommitOrAbort(OperationContext* opCtx,
return;
}
+ if (replCoord->getSettings().shouldRecoverFromOplogAsStandalone()) {
+ // TODO SERVER-60753: Remove this mixed-mode write.
+ opCtx->recoveryUnit()->allowUntimestampedWrite();
+ }
+
auto status = indexbuildentryhelpers::removeIndexBuildEntry(
opCtx, indexBuildEntryCollection, replState.buildUUID);
if (!status.isOK()) {
@@ -545,6 +550,10 @@ Status IndexBuildsCoordinator::_startIndexBuildForRecovery(OperationContext* opC
CollectionWriter collection(opCtx, nss);
{
+ // TODO SERVER-64760: Remove this usage of `allowUntimestampedWrite`. We often have a valid
+ // timestamp for this write, but the callers of this function don't pass it through.
+ opCtx->recoveryUnit()->allowUntimestampedWrite();
+
// These steps are combined into a single WUOW to ensure there are no commits without
// the indexes.
// 1) Drop all unfinished indexes.
@@ -1880,6 +1889,12 @@ Status IndexBuildsCoordinator::_setUpIndexBuildForTwoPhaseRecovery(
const UUID& buildUUID) {
NamespaceStringOrUUID nssOrUuid{dbName.toString(), collectionUUID};
+ if (opCtx->recoveryUnit()->isActive()) {
+ // This function is shared by multiple callers. Some of which have opened a transaction to
+ // perform reads. This function may make mixed-mode writes. Mixed-mode assertions can only
+ // be suppressed when beginning a fresh transaction.
+ opCtx->recoveryUnit()->abandonSnapshot();
+ }
// Don't use the AutoGet helpers because they require an open database, which may not be the
// case when an index builds is restarted during recovery.
@@ -2057,6 +2072,10 @@ IndexBuildsCoordinator::PostSetupAction IndexBuildsCoordinator::_setUpIndexBuild
options.protocol = replState->protocol;
try {
+ // TODO SERVER-64760: Remove this usage of `allowUntimestampedWrite`. There are cases where
+ // a timestamp is available to use, but the information is not passed through.
+ opCtx->recoveryUnit()->allowUntimestampedWrite();
+
if (!replSetAndNotPrimary) {
// On standalones and primaries, call setUpIndexBuild(), which makes the initial catalog
// write. On primaries, this replicates the startIndexBuild oplog entry.
diff --git a/src/mongo/db/repair.cpp b/src/mongo/db/repair.cpp
index c880b32487b..a6f8029be24 100644
--- a/src/mongo/db/repair.cpp
+++ b/src/mongo/db/repair.cpp
@@ -71,6 +71,13 @@ using namespace fmt::literals;
Status rebuildIndexesForNamespace(OperationContext* opCtx,
const NamespaceString& nss,
StorageEngine* engine) {
+ if (opCtx->recoveryUnit()->isActive()) {
+ // This function is shared by multiple callers. Some of which have opened a transaction to
+ // perform reads. This function may make mixed-mode writes. Mixed-mode assertions can only
+ // be suppressed when beginning a fresh transaction.
+ opCtx->recoveryUnit()->abandonSnapshot();
+ }
+
opCtx->checkForInterrupt();
auto collection = CollectionCatalog::get(opCtx)->lookupCollectionByNamespace(opCtx, nss);
auto swIndexNameObjs = getIndexNameObjs(collection);
diff --git a/src/mongo/db/repl/oplog_applier_impl_test.cpp b/src/mongo/db/repl/oplog_applier_impl_test.cpp
index 88eb0fb7fb7..ef1767ee934 100644
--- a/src/mongo/db/repl/oplog_applier_impl_test.cpp
+++ b/src/mongo/db/repl/oplog_applier_impl_test.cpp
@@ -2683,6 +2683,11 @@ public:
void setUp() override {
OplogApplierImplTest::setUp();
+ // This fixture sets up some replication, but notably omits installing an
+ // OpObserverImpl. This state causes collection creation to timestamp catalog writes, but
+ // secondary index creation does not. We use an UnreplicatedWritesBlock to avoid
+ // timestamping any of the catalog setup.
+ repl::UnreplicatedWritesBlock noRep(_opCtx.get());
MongoDSessionCatalog::onStepUp(_opCtx.get());
DBDirectClient client(_opCtx.get());
diff --git a/src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp b/src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp
index 72c93034d8b..7c3d062a545 100644
--- a/src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp
+++ b/src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp
@@ -503,6 +503,10 @@ void createIndex(OperationContext* opCtx,
Lock::DBLock dbLk(opCtx, nss.dbName(), MODE_IX);
Lock::CollectionLock collLk(opCtx, nss, MODE_X);
auto indexBuildsCoord = IndexBuildsCoordinator::get(opCtx);
+ // This fixture sets up some replication, but notably omits installing an OpObserverImpl. This
+ // state causes collection creation to timestamp catalog writes, but secondary index creation
+ // does not. We use an UnreplicatedWritesBlock to avoid timestamping any of the catalog setup.
+ repl::UnreplicatedWritesBlock noRep(opCtx);
indexBuildsCoord->createIndex(
opCtx, collUUID, spec, IndexBuildsManager::IndexConstraints::kEnforce, false);
}
diff --git a/src/mongo/db/repl/oplog_applier_test.cpp b/src/mongo/db/repl/oplog_applier_test.cpp
index cb35f041caa..d9eff0fced7 100644
--- a/src/mongo/db/repl/oplog_applier_test.cpp
+++ b/src/mongo/db/repl/oplog_applier_test.cpp
@@ -369,6 +369,7 @@ public:
void setUp() override {
OplogApplierTest::setUp();
auto* service = getServiceContext();
+ _origThreadName = *getThreadNameRef().get();
Client::initThread("OplogApplierDelayTest", service, nullptr);
_mockClock = std::make_shared<ClockSourceMock>();
@@ -387,6 +388,7 @@ public:
_opCtxHolder = nullptr;
Client::releaseCurrent();
OplogApplierTest::tearDown();
+ setThreadName(_origThreadName);
}
OperationContext* opCtx() override {
@@ -412,6 +414,9 @@ protected:
std::shared_ptr<ClockSourceMock> _mockClock;
ServiceContext::UniqueOperationContext _opCtxHolder;
AtomicWord<bool> _failWaits{false};
+
+private:
+ std::string _origThreadName;
};
TEST_F(OplogApplierDelayTest, GetNextApplierBatchReturnsEmptyBatchImmediately) {
diff --git a/src/mongo/db/repl/replication_recovery_test.cpp b/src/mongo/db/repl/replication_recovery_test.cpp
index dc2287e9f03..b31925a330a 100644
--- a/src/mongo/db/repl/replication_recovery_test.cpp
+++ b/src/mongo/db/repl/replication_recovery_test.cpp
@@ -195,10 +195,17 @@ private:
repl::createOplog(_opCtx.get());
- ASSERT_OK(_storageInterface->createCollection(
- getOperationContext(), testNs, generateOptionsWithUuid()));
-
- MongoDSessionCatalog::onStepUp(_opCtx.get());
+ {
+ // This fixture sets up some replication, but notably omits installing an
+ // OpObserverImpl. This state causes collection creation to timestamp catalog writes,
+ // but secondary index creation does not. We use an UnreplicatedWritesBlock to avoid
+ // timestamping any of the catalog setup.
+ repl::UnreplicatedWritesBlock noRep(_opCtx.get());
+ ASSERT_OK(_storageInterface->createCollection(
+ getOperationContext(), testNs, generateOptionsWithUuid()));
+
+ MongoDSessionCatalog::onStepUp(_opCtx.get());
+ }
auto observerRegistry = checked_cast<OpObserverRegistry*>(service->getOpObserver());
observerRegistry->addObserver(std::make_unique<ReplicationRecoveryTestObObserver>());
diff --git a/src/mongo/db/repl/rollback_impl.cpp b/src/mongo/db/repl/rollback_impl.cpp
index 91893402542..613518af43b 100644
--- a/src/mongo/db/repl/rollback_impl.cpp
+++ b/src/mongo/db/repl/rollback_impl.cpp
@@ -524,6 +524,7 @@ void RollbackImpl::_restoreTxnsTableEntryFromRetryableWrites(OperationContext* o
}
const auto nss = NamespaceString::kSessionTransactionsTableNamespace;
writeConflictRetry(opCtx, "updateSessionTransactionsTableInRollback", nss.ns(), [&] {
+ opCtx->recoveryUnit()->allowUntimestampedWrite();
AutoGetCollection collection(opCtx, nss, MODE_IX);
auto filter = BSON(SessionTxnRecord::kSessionIdFieldName << sessionId.toBSON());
UnreplicatedWritesBlock uwb(opCtx);
diff --git a/src/mongo/db/repl/storage_timestamp_test.cpp b/src/mongo/db/repl/storage_timestamp_test.cpp
index 299bfcc2339..4f3f5bf0a18 100644
--- a/src/mongo/db/repl/storage_timestamp_test.cpp
+++ b/src/mongo/db/repl/storage_timestamp_test.cpp
@@ -137,7 +137,8 @@ Status createIndexFromSpec(OperationContext* opCtx,
collection,
spec,
[opCtx, clock](const std::vector<BSONObj>& specs) -> Status {
- if (opCtx->recoveryUnit()->getCommitTimestamp().isNull()) {
+ if (opCtx->writesAreReplicated() &&
+ opCtx->recoveryUnit()->getCommitTimestamp().isNull()) {
return opCtx->recoveryUnit()->setTimestamp(
clock->tickClusterTime(1).asTimestamp());
}
@@ -167,8 +168,10 @@ Status createIndexFromSpec(OperationContext* opCtx,
collection.getWritableCollection(opCtx),
MultiIndexBlock::kNoopOnCreateEachFn,
MultiIndexBlock::kNoopOnCommitFn));
- LogicalTime indexTs = clock->tickClusterTime(1);
- ASSERT_OK(opCtx->recoveryUnit()->setTimestamp(indexTs.asTimestamp()));
+ if (opCtx->writesAreReplicated()) {
+ LogicalTime indexTs = clock->tickClusterTime(1);
+ ASSERT_OK(opCtx->recoveryUnit()->setTimestamp(indexTs.asTimestamp()));
+ }
wunit.commit();
abortOnExit.dismiss();
return Status::OK();
@@ -356,7 +359,8 @@ public:
AutoGetCollection autoColl(_opCtx, nss, LockMode::MODE_IX);
auto db = autoColl.ensureDbExists(_opCtx);
WriteUnitOfWork wunit(_opCtx);
- if (_opCtx->recoveryUnit()->getCommitTimestamp().isNull()) {
+ if (_opCtx->writesAreReplicated() &&
+ _opCtx->recoveryUnit()->getCommitTimestamp().isNull()) {
ASSERT_OK(_opCtx->recoveryUnit()->setTimestamp(Timestamp(1, 1)));
}
invariant(db->createCollection(_opCtx, nss));
@@ -1666,6 +1670,7 @@ TEST_F(StorageTimestampTest, PrimarySetIndexMultikeyOnInsert) {
TEST_F(StorageTimestampTest, PrimarySetIndexMultikeyOnInsertUnreplicated) {
// Use an unreplicated collection.
+ repl::UnreplicatedWritesBlock noRep(_opCtx);
NamespaceString nss("unittests.system.profile");
create(nss);
diff --git a/src/mongo/db/service_context_d_test_fixture.cpp b/src/mongo/db/service_context_d_test_fixture.cpp
index 0e40005bde4..caef9950914 100644
--- a/src/mongo/db/service_context_d_test_fixture.cpp
+++ b/src/mongo/db/service_context_d_test_fixture.cpp
@@ -70,6 +70,11 @@ ServiceContextMongoDTest::ServiceContextMongoDTest(Options options)
replSettings.setOplogSizeBytes(10 * 1024 * 1024);
replSettings.setReplSetString("rs0");
setGlobalReplSettings(replSettings);
+ } else {
+ repl::ReplSettings replSettings;
+ // The empty string "disables" replication.
+ replSettings.setReplSetString("");
+ setGlobalReplSettings(replSettings);
}
_stashedStorageParams.engine =
diff --git a/src/mongo/db/storage/recovery_unit.h b/src/mongo/db/storage/recovery_unit.h
index 6ac1a4375c6..fed9d478540 100644
--- a/src/mongo/db/storage/recovery_unit.h
+++ b/src/mongo/db/storage/recovery_unit.h
@@ -409,6 +409,12 @@ public:
return {};
}
+ /**
+ * MongoDB must update documents with non-decreasing timestamp values. A storage engine is
+ * allowed to assert when this contract is violated. An untimestamped write is a subset of these
+ * violations, which may be necessary in limited circumstances. This API can be called before a
+ * transaction begins to suppress this subset of errors.
+ */
virtual void allowUntimestampedWrite() {}
/**
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block.cpp
index e91b228505a..abb0617c124 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block.cpp
@@ -49,7 +49,7 @@ WiredTigerBeginTxnBlock::WiredTigerBeginTxnBlock(
PrepareConflictBehavior prepareConflictBehavior,
RoundUpPreparedTimestamps roundUpPreparedTimestamps,
RoundUpReadTimestamp roundUpReadTimestamp,
- bool allowUntimestampedWrite)
+ UntimestampedWriteAssertion allowUntimestampedWrite)
: _session(session) {
invariant(!_rollback);
@@ -70,7 +70,7 @@ WiredTigerBeginTxnBlock::WiredTigerBeginTxnBlock(
}
builder << "),";
}
- if (allowUntimestampedWrite) {
+ if (allowUntimestampedWrite == UntimestampedWriteAssertion::kSuppress) {
builder << "no_timestamp=true,";
}
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block.h b/src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block.h
index ed9b7789be0..4faf831727e 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block.h
@@ -58,12 +58,13 @@ public:
// earlier.
enum class RoundUpPreparedTimestamps { kNoRound, kRound };
- WiredTigerBeginTxnBlock(
- WT_SESSION* session,
- PrepareConflictBehavior prepareConflictBehavior,
- RoundUpPreparedTimestamps roundUpPreparedTimestamps,
- RoundUpReadTimestamp roundUpReadTimestamp,
- bool allowUntimestampedWrite);
+ enum class UntimestampedWriteAssertion { kSuppress, kEnforce };
+
+ WiredTigerBeginTxnBlock(WT_SESSION* session,
+ PrepareConflictBehavior prepareConflictBehavior,
+ RoundUpPreparedTimestamps roundUpPreparedTimestamps,
+ RoundUpReadTimestamp roundUpReadTimestamp,
+ UntimestampedWriteAssertion allowUntimestampedWrite);
WiredTigerBeginTxnBlock(WT_SESSION* session, const char* config);
~WiredTigerBeginTxnBlock();
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block_bm.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block_bm.cpp
index 7033ff3931a..3557b8d29fa 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block_bm.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block_bm.cpp
@@ -127,13 +127,13 @@ using mongo::WiredTigerBeginTxnBlock;
template <PrepareConflictBehavior behavior, RoundUpPreparedTimestamps round>
void BM_WiredTigerBeginTxnBlockWithArgs(benchmark::State& state) {
WiredTigerTestHelper helper;
- const bool allowUntimestampedWrite = false;
for (auto _ : state) {
- WiredTigerBeginTxnBlock beginTxn(helper.wtSession(),
- behavior,
- round,
- RoundUpReadTimestamp::kNoRoundError,
- allowUntimestampedWrite);
+ WiredTigerBeginTxnBlock beginTxn(
+ helper.wtSession(),
+ behavior,
+ round,
+ RoundUpReadTimestamp::kNoRoundError,
+ WiredTigerBeginTxnBlock::UntimestampedWriteAssertion::kEnforce);
}
}
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp
index 5714609a722..df275526c30 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp
@@ -162,12 +162,7 @@ StatusWith<std::string> WiredTigerIndex::generateCreateString(
ss << "prefix_compression=true,";
}
- if ( // TODO (SERVER-60753): Remove special handling for index build during recovery.
- collectionNamespace.ns() == "config.system.indexBuilds") {
- ss << "write_timestamp_usage=mixed_mode,";
- } else {
- ss << "write_timestamp_usage=ordered,";
- }
+ // Report errors on writes without ordered timestamps.
ss << "assert=(write_timestamp=on),";
ss << "verbose=[write_timestamp],";
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp
index 5481f840590..e05ae7ae795 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp
@@ -796,20 +796,7 @@ StatusWith<std::string> WiredTigerRecordStore::generateCreateString(
ss << "split_pct=90,";
ss << "leaf_value_max=64MB,";
- if (nss.isOplog()) {
- // For the above clauses we do not assert any particular `write_timestamp_usage`. In
- // particular for the oplog, WT removes all timestamp information. There's nothing in
- // MDB's control to assert against.
- } else if (
- // Side table drains are not timestamped.
- ident.startsWith("internal-") ||
- // TODO (SERVER-60753): Remove special handling for index build during recovery. This
- // includes the following _mdb_catalog ident.
- nss == NamespaceString::kIndexBuildEntryNamespace || ident.startsWith("_mdb_catalog")) {
- ss << "write_timestamp_usage=mixed_mode,";
- } else {
- ss << "write_timestamp_usage=ordered,";
- }
+ // Report errors on writes without ordered timestamps.
ss << "assert=(write_timestamp=on),";
ss << "verbose=[write_timestamp],";
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp
index 4d93dbd3c17..e121856c916 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp
@@ -520,7 +520,7 @@ void WiredTigerRecoveryUnit::_txnClose(bool commit) {
_isOplogReader = false;
_oplogVisibleTs = boost::none;
_orderedCommit = true; // Default value is true; we assume all writes are ordered.
- _allowUntimestampedWrite = false;
+ _untimestampedWriteAssertion = WiredTigerBeginTxnBlock::UntimestampedWriteAssertion::kEnforce;
}
Status WiredTigerRecoveryUnit::majorityCommittedSnapshotAvailable() const {
@@ -611,7 +611,7 @@ void WiredTigerRecoveryUnit::_txnOpen() {
_prepareConflictBehavior,
_roundUpPreparedTimestamps,
RoundUpReadTimestamp::kNoRoundError,
- _allowUntimestampedWrite)
+ _untimestampedWriteAssertion)
.done();
break;
}
@@ -620,7 +620,7 @@ void WiredTigerRecoveryUnit::_txnOpen() {
session,
_prepareConflictBehavior,
_roundUpPreparedTimestamps,
- _allowUntimestampedWrite);
+ _untimestampedWriteAssertion);
break;
}
case ReadSource::kLastApplied: {
@@ -643,7 +643,7 @@ void WiredTigerRecoveryUnit::_txnOpen() {
_prepareConflictBehavior,
_roundUpPreparedTimestamps,
RoundUpReadTimestamp::kNoRoundError,
- _allowUntimestampedWrite);
+ _untimestampedWriteAssertion);
auto status = txnOpen.setReadSnapshot(_readAtTimestamp);
if (!status.isOK() && status.code() == ErrorCodes::BadValue) {
@@ -672,7 +672,7 @@ Timestamp WiredTigerRecoveryUnit::_beginTransactionAtAllDurableTimestamp(WT_SESS
_prepareConflictBehavior,
_roundUpPreparedTimestamps,
RoundUpReadTimestamp::kRound,
- _allowUntimestampedWrite);
+ _untimestampedWriteAssertion);
Timestamp txnTimestamp = _sessionCache->getKVEngine()->getAllDurableTimestamp();
auto status = txnOpen.setReadSnapshot(txnTimestamp);
fassert(50948, status);
@@ -700,7 +700,7 @@ void WiredTigerRecoveryUnit::_beginTransactionAtLastAppliedTimestamp(WT_SESSION*
_prepareConflictBehavior,
_roundUpPreparedTimestamps,
RoundUpReadTimestamp::kNoRoundError,
- _allowUntimestampedWrite);
+ _untimestampedWriteAssertion);
LOGV2_DEBUG(4847500, 2, "no read timestamp available for kLastApplied");
txnOpen.done();
return;
@@ -710,7 +710,7 @@ void WiredTigerRecoveryUnit::_beginTransactionAtLastAppliedTimestamp(WT_SESSION*
_prepareConflictBehavior,
_roundUpPreparedTimestamps,
RoundUpReadTimestamp::kRound,
- _allowUntimestampedWrite);
+ _untimestampedWriteAssertion);
auto status = txnOpen.setReadSnapshot(_readAtTimestamp);
fassert(4847501, status);
@@ -766,7 +766,7 @@ Timestamp WiredTigerRecoveryUnit::_beginTransactionAtNoOverlapTimestamp(WT_SESSI
_prepareConflictBehavior,
_roundUpPreparedTimestamps,
RoundUpReadTimestamp::kNoRoundError,
- _allowUntimestampedWrite);
+ _untimestampedWriteAssertion);
LOGV2_DEBUG(4452900, 1, "no read timestamp available for kNoOverlap");
txnOpen.done();
return readTimestamp;
@@ -776,7 +776,7 @@ Timestamp WiredTigerRecoveryUnit::_beginTransactionAtNoOverlapTimestamp(WT_SESSI
_prepareConflictBehavior,
_roundUpPreparedTimestamps,
RoundUpReadTimestamp::kRound,
- _allowUntimestampedWrite);
+ _untimestampedWriteAssertion);
auto status = txnOpen.setReadSnapshot(readTimestamp);
fassert(51066, status);
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.h b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.h
index c16a6ce9b29..5397b91fb91 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.h
@@ -150,7 +150,8 @@ public:
void allowUntimestampedWrite() override {
invariant(!_isActive());
- _allowUntimestampedWrite = true;
+ _untimestampedWriteAssertion =
+ WiredTigerBeginTxnBlock::UntimestampedWriteAssertion::kSuppress;
}
void setTimestampReadSource(ReadSource source,
@@ -316,7 +317,8 @@ private:
boost::optional<Timestamp> _lastTimestampSet;
Timestamp _readAtTimestamp;
Timestamp _catalogConflictTimestamp;
- bool _allowUntimestampedWrite = false;
+ WiredTigerBeginTxnBlock::UntimestampedWriteAssertion _untimestampedWriteAssertion =
+ WiredTigerBeginTxnBlock::UntimestampedWriteAssertion::kEnforce;
std::unique_ptr<Timer> _timer;
bool _isOplogReader = false;
boost::optional<int64_t> _oplogVisibleTs = boost::none;
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.cpp
index 2e093d59ea1..819e19992ca 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.cpp
@@ -84,7 +84,7 @@ Timestamp WiredTigerSnapshotManager::beginTransactionOnCommittedSnapshot(
WT_SESSION* session,
PrepareConflictBehavior prepareConflictBehavior,
RoundUpPreparedTimestamps roundUpPreparedTimestamps,
- bool allowUntimestampedWrite) const {
+ WiredTigerBeginTxnBlock::UntimestampedWriteAssertion untimestampedWriteAssertion) const {
auto committedSnapshot = [this]() {
stdx::lock_guard<Latch> lock(_committedSnapshotMutex);
@@ -104,7 +104,7 @@ Timestamp WiredTigerSnapshotManager::beginTransactionOnCommittedSnapshot(
prepareConflictBehavior,
roundUpPreparedTimestamps,
RoundUpReadTimestamp::kRound,
- allowUntimestampedWrite);
+ untimestampedWriteAssertion);
auto status = txnOpen.setReadSnapshot(committedSnapshot);
fassert(30635, status);
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.h b/src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.h
index 088bf7a50f9..b3cf9b4d030 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.h
@@ -68,7 +68,7 @@ public:
WT_SESSION* session,
PrepareConflictBehavior prepareConflictBehavior,
RoundUpPreparedTimestamps roundUpPreparedTimestamps,
- bool allowUntimestampedWrite) const;
+ WiredTigerBeginTxnBlock::UntimestampedWriteAssertion untimestampedWriteAssertion) const;
/**
* Returns lowest SnapshotName that could possibly be used by a future call to