summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorDaniel Gottlieb <daniel.gottlieb@mongodb.com>2020-03-20 09:04:22 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-03-20 15:24:52 +0000
commit5ab625013bcf6438515dceb5fe7c2228257cb863 (patch)
treee319b2b5907db52ad1685317ebdca14d3c0fa7e5 /src/mongo
parent9846834c3ad936367657e11f03f283af4b305717 (diff)
downloadmongo-5ab625013bcf6438515dceb5fe7c2228257cb863.tar.gz
SERVER-45147: Ensure ghost timestamped transactions trigger the stable timestamp to advance when they commit/abort. Ensure the durable timestamp does not move backwards.
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/catalog/index_timestamp_helper.cpp21
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp14
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h4
3 files changed, 35 insertions, 4 deletions
diff --git a/src/mongo/db/catalog/index_timestamp_helper.cpp b/src/mongo/db/catalog/index_timestamp_helper.cpp
index bfdc902ba20..2e9f2cc7074 100644
--- a/src/mongo/db/catalog/index_timestamp_helper.cpp
+++ b/src/mongo/db/catalog/index_timestamp_helper.cpp
@@ -40,6 +40,21 @@
namespace mongo {
namespace {
+Status setGhostTimestamp(OperationContext* opCtx, Timestamp timestamp) {
+ if (auto status = opCtx->recoveryUnit()->setTimestamp(timestamp); !status.isOK()) {
+ return status;
+ }
+ opCtx->recoveryUnit()->setOrderedCommit(false);
+
+ auto replCoord = repl::ReplicationCoordinator::get(opCtx);
+ if (replCoord->isReplEnabled()) {
+ opCtx->recoveryUnit()->onCommit(
+ [replCoord](auto commitTime) { replCoord->attemptToAdvanceStableTimestamp(); });
+ }
+
+ return Status::OK();
+}
+
bool requiresGhostCommitTimestampForWrite(OperationContext* opCtx, const NamespaceString& nss) {
if (!nss.isReplicated()) {
return false;
@@ -92,7 +107,7 @@ void IndexTimestampHelper::setGhostCommitTimestampForWrite(OperationContext* opC
<< " cannot be older than current read timestamp "
<< mySnapshot->toString());
- auto status = opCtx->recoveryUnit()->setTimestamp(commitTimestamp);
+ auto status = setGhostTimestamp(opCtx, commitTimestamp);
if (status.code() == ErrorCodes::BadValue) {
LOGV2(20379,
"Temporarily could not apply ghost commit timestamp. {status_reason}",
@@ -155,8 +170,8 @@ bool IndexTimestampHelper::setGhostCommitTimestampForCatalogWrite(OperationConte
if (!requiresGhostCommitTimestampForCatalogWrite(opCtx, nss)) {
return false;
}
- auto status = opCtx->recoveryUnit()->setTimestamp(
- LogicalClock::get(opCtx)->getClusterTime().asTimestamp());
+ auto status =
+ setGhostTimestamp(opCtx, LogicalClock::get(opCtx)->getClusterTime().asTimestamp());
if (status.code() == ErrorCodes::BadValue) {
LOGV2(20381,
"Temporarily could not timestamp the index build commit, retrying. {status_reason}",
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
index 26ef526ae86..00a0a7b3da8 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
@@ -1825,6 +1825,8 @@ void WiredTigerKVEngine::setStableTimestamp(Timestamp stableTimestamp, bool forc
stableTSConfigString =
"force=true,oldest_timestamp={0:x},commit_timestamp={0:x},stable_timestamp={0:x}"_format(
ts);
+ stdx::lock_guard<Latch> lk(_highestDurableTimestampMutex);
+ _highestSeenDurableTimestamp = ts;
} else {
stableTSConfigString = "stable_timestamp={:x}"_format(ts);
}
@@ -1881,6 +1883,8 @@ void WiredTigerKVEngine::setOldestTimestamp(Timestamp newOldestTimestamp, bool f
newOldestTimestamp.asULL());
invariantWTOK(_conn->set_timestamp(_conn, oldestTSConfigString.c_str()));
_oldestTimestamp.store(newOldestTimestamp.asULL());
+ stdx::lock_guard<Latch> lk(_highestDurableTimestampMutex);
+ _highestSeenDurableTimestamp = newOldestTimestamp.asULL();
LOGV2_DEBUG(22342,
2,
"oldest_timestamp and commit_timestamp force set to {newOldestTimestamp}",
@@ -2009,7 +2013,15 @@ StatusWith<Timestamp> WiredTigerKVEngine::recoverToStableTimestamp(OperationCont
}
Timestamp WiredTigerKVEngine::getAllDurableTimestamp() const {
- return Timestamp(_oplogManager->fetchAllDurableValue(_conn));
+ auto ret = _oplogManager->fetchAllDurableValue(_conn);
+
+ stdx::lock_guard<Latch> lk(_highestDurableTimestampMutex);
+ if (ret < _highestSeenDurableTimestamp) {
+ ret = _highestSeenDurableTimestamp;
+ } else {
+ _highestSeenDurableTimestamp = ret;
+ }
+ return Timestamp(ret);
}
Timestamp WiredTigerKVEngine::getOldestOpenReadTimestamp() const {
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
index 8f948cbc8b7..23d29fb1c6f 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
@@ -493,5 +493,9 @@ private:
std::unique_ptr<WiredTigerEngineRuntimeConfigParameter> _runTimeConfigParam;
std::unique_ptr<WiredTigerMaxCacheOverflowSizeGBParameter> _maxCacheOverflowParam;
+
+ mutable Mutex _highestDurableTimestampMutex =
+ MONGO_MAKE_LATCH("WiredTigerKVEngine::_highestDurableTimestampMutex");
+ mutable unsigned long long _highestSeenDurableTimestamp = StorageEngine::kMinimumTimestamp;
};
} // namespace mongo