summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorHenrik Edin <henrik.edin@mongodb.com>2022-05-16 12:37:20 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-05-16 19:19:55 +0000
commit04e49a5d48ac6e9486f196806efae1ed11d79948 (patch)
tree0dc16a8666ccfd7f050668c045daaa4e8c94aa09 /src/mongo
parentfeb2dfc188dd4108224c85ab03b0dd0d7ceaa8ea (diff)
downloadmongo-04e49a5d48ac6e9486f196806efae1ed11d79948.tar.gz
SERVER-66139 Disable oplog visibility in standalone mode
(cherry picked from commit fbdcf79b38b141aa89d7b38ddcf40d4065c4c2ae)
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_record_store_test.cpp3
-rw-r--r--src/mongo/db/storage/record_store_test_harness.cpp11
-rw-r--r--src/mongo/db/storage/record_store_test_harness.h9
-rw-r--r--src/mongo/db/storage/record_store_test_oplog.cpp49
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.cpp8
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.cpp35
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.h7
7 files changed, 96 insertions, 26 deletions
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_record_store_test.cpp b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_record_store_test.cpp
index 15ebe93cad0..f5b66a36c16 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_record_store_test.cpp
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_record_store_test.cpp
@@ -95,7 +95,8 @@ public:
}
};
-std::unique_ptr<mongo::RecordStoreHarnessHelper> makeRecordStoreHarnessHelper() {
+std::unique_ptr<mongo::RecordStoreHarnessHelper> makeRecordStoreHarnessHelper(
+ RecordStoreHarnessHelper::Options options) {
return std::make_unique<RecordStoreHarnessHelper>();
}
diff --git a/src/mongo/db/storage/record_store_test_harness.cpp b/src/mongo/db/storage/record_store_test_harness.cpp
index 00f937ac8be..f026681a77d 100644
--- a/src/mongo/db/storage/record_store_test_harness.cpp
+++ b/src/mongo/db/storage/record_store_test_harness.cpp
@@ -39,16 +39,19 @@
namespace mongo {
namespace {
-std::function<std::unique_ptr<RecordStoreHarnessHelper>()> recordStoreHarnessFactory;
+std::function<std::unique_ptr<RecordStoreHarnessHelper>(RecordStoreHarnessHelper::Options)>
+ recordStoreHarnessFactory;
}
void registerRecordStoreHarnessHelperFactory(
- std::function<std::unique_ptr<RecordStoreHarnessHelper>()> factory) {
+ std::function<std::unique_ptr<RecordStoreHarnessHelper>(RecordStoreHarnessHelper::Options)>
+ factory) {
recordStoreHarnessFactory = std::move(factory);
}
-auto newRecordStoreHarnessHelper() -> std::unique_ptr<RecordStoreHarnessHelper> {
- return recordStoreHarnessFactory();
+auto newRecordStoreHarnessHelper(RecordStoreHarnessHelper::Options options)
+ -> std::unique_ptr<RecordStoreHarnessHelper> {
+ return recordStoreHarnessFactory(options);
}
namespace {
diff --git a/src/mongo/db/storage/record_store_test_harness.h b/src/mongo/db/storage/record_store_test_harness.h
index 72f087463bf..4cae8fa740c 100644
--- a/src/mongo/db/storage/record_store_test_harness.h
+++ b/src/mongo/db/storage/record_store_test_harness.h
@@ -45,6 +45,8 @@ class RecoveryUnit;
class RecordStoreHarnessHelper : public HarnessHelper {
public:
+ enum class Options { Standalone, ReplicationEnabled };
+
virtual std::unique_ptr<RecordStore> newRecordStore() = 0;
std::unique_ptr<RecordStore> newRecordStore(const std::string& ns) {
@@ -61,8 +63,11 @@ public:
};
void registerRecordStoreHarnessHelperFactory(
- std::function<std::unique_ptr<RecordStoreHarnessHelper>()> factory);
+ std::function<std::unique_ptr<RecordStoreHarnessHelper>(RecordStoreHarnessHelper::Options)>
+ factory);
-std::unique_ptr<RecordStoreHarnessHelper> newRecordStoreHarnessHelper();
+std::unique_ptr<RecordStoreHarnessHelper> newRecordStoreHarnessHelper(
+ RecordStoreHarnessHelper::Options options =
+ RecordStoreHarnessHelper::Options::ReplicationEnabled);
} // namespace mongo
diff --git a/src/mongo/db/storage/record_store_test_oplog.cpp b/src/mongo/db/storage/record_store_test_oplog.cpp
index 368ba88278d..6c61f93ee76 100644
--- a/src/mongo/db/storage/record_store_test_oplog.cpp
+++ b/src/mongo/db/storage/record_store_test_oplog.cpp
@@ -509,5 +509,54 @@ TEST(RecordStoreTestHarness, OplogOrder) {
ASSERT(!nextRecord) << stringifyForDebug(opCtx.get(), nextRecord, cursor.get());
}
}
+
+TEST(RecordStoreTestHarness, OplogVisibilityStandalone) {
+ std::unique_ptr<RecordStoreHarnessHelper> harnessHelper(
+ newRecordStoreHarnessHelper(RecordStoreHarnessHelper::Options::Standalone));
+ std::unique_ptr<RecordStore> rs(harnessHelper->newOplogRecordStore());
+
+ RecordId id1;
+
+ // insert a document
+ {
+ ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
+ {
+ WriteUnitOfWork uow(opCtx.get());
+ // We must have a "ts" field with a timestamp.
+ Timestamp ts(5, 1);
+ BSONObj obj = BSON("ts" << ts);
+ // However, the insert is not timestamped in standalone mode.
+ StatusWith<RecordId> res =
+ rs->insertRecord(opCtx.get(), obj.objdata(), obj.objsize(), Timestamp());
+ ASSERT_OK(res.getStatus());
+ id1 = res.getValue();
+ StatusWith<RecordId> expectedId = record_id_helpers::keyForOptime(ts);
+ ASSERT_OK(expectedId.getStatus());
+ // RecordId should be extracted from 'ts' field when inserting into oplog namespace
+ ASSERT(expectedId.getValue().compare(id1) == 0);
+
+ uow.commit();
+ }
+ }
+
+ // verify that we can read it
+ {
+ ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
+ auto cursor = rs->getCursor(opCtx.get());
+ auto record = cursor->seekExact(id1);
+ ASSERT(record);
+ ASSERT_EQ(id1, record->id);
+ ASSERT(!cursor->next());
+ }
+
+ {
+ ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
+ auto cursor = rs->getCursor(opCtx.get());
+ auto record = cursor->seekNear(RecordId(id1.getLong() + 1));
+ ASSERT(record);
+ ASSERT_EQ(id1, record->id);
+ ASSERT(!cursor->next());
+ }
+}
} // namespace
} // namespace mongo
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.cpp
index 332f3bb0519..fb3bc211faa 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.cpp
@@ -34,6 +34,7 @@
#include <cstring>
#include "mongo/db/concurrency/lock_state.h"
+#include "mongo/db/repl/replication_coordinator.h"
#include "mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h"
#include "mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.h"
#include "mongo/db/storage/wiredtiger/wiredtiger_util.h"
@@ -69,9 +70,14 @@ void WiredTigerOplogManager::startVisibilityThread(OperationContext* opCtx,
1,
"Initializing the oplog read timestamp (oplog visibility).",
"oplogReadTimestamp"_attr = topOfOplogTimestamp);
- } else {
+ } else if (repl::ReplicationCoordinator::get(opCtx)->isReplEnabled()) {
// Avoid setting oplog visibility to 0. That means "everything is visible".
setOplogReadTimestamp(Timestamp(StorageEngine::kMinimumTimestamp));
+ } else {
+ // Use max Timestamp to disable oplog visibility in standalone mode. The read timestamp may
+ // be interpreted as signed so we need to use signed int64_t max to make sure it is always
+ // larger than any user 'ts' field.
+ setOplogReadTimestamp(Timestamp(std::numeric_limits<int64_t>::max()));
}
// Need to obtain the mutex before starting the thread, as otherwise it may race ahead
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.cpp
index 70912221539..0b64d1c2974 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.cpp
@@ -42,7 +42,7 @@ std::string _testLoggingSettings(std::string extraStrings) {
}
} // namespace
-WiredTigerHarnessHelper::WiredTigerHarnessHelper(StringData extraStrings)
+WiredTigerHarnessHelper::WiredTigerHarnessHelper(Options options, StringData extraStrings)
: _dbpath("wt_test"),
_lockerNoopClientObserverRegisterer(getServiceContext()),
_engine(kWiredTigerEngineName,
@@ -57,14 +57,17 @@ WiredTigerHarnessHelper::WiredTigerHarnessHelper(StringData extraStrings)
false) {
repl::ReplicationCoordinator::set(
serviceContext(),
- std::make_unique<repl::ReplicationCoordinatorMock>(serviceContext(), repl::ReplSettings()));
+ options == Options::ReplicationEnabled
+ ? std::make_unique<repl::ReplicationCoordinatorMock>(serviceContext())
+ : std::make_unique<repl::ReplicationCoordinatorMock>(serviceContext(),
+ repl::ReplSettings()));
_engine.notifyStartupComplete();
}
std::unique_ptr<RecordStore> WiredTigerHarnessHelper::newRecordStore(
const std::string& ns, const CollectionOptions& collOptions, KeyFormat keyFormat) {
- WiredTigerRecoveryUnit* ru = checked_cast<WiredTigerRecoveryUnit*>(_engine.newRecoveryUnit());
- OperationContextNoop opCtx(ru);
+ ServiceContext::UniqueOperationContext opCtx(newOperationContext());
+ WiredTigerRecoveryUnit* ru = checked_cast<WiredTigerRecoveryUnit*>(opCtx->recoveryUnit());
std::string uri = WiredTigerKVEngine::kTableUriPrefix + ns;
StringData ident = ns;
NamespaceString nss(ns);
@@ -81,7 +84,7 @@ std::unique_ptr<RecordStore> WiredTigerHarnessHelper::newRecordStore(
std::string config = result.getValue();
{
- WriteUnitOfWork uow(&opCtx);
+ WriteUnitOfWork uow(opCtx.get());
WT_SESSION* s = ru->getSession()->getSession();
invariantWTOK(s->create(s, uri.c_str(), config.c_str()), s);
uow.commit();
@@ -102,22 +105,21 @@ std::unique_ptr<RecordStore> WiredTigerHarnessHelper::newRecordStore(
params.tracksSizeAdjustments = true;
params.forceUpdateWithFullDocument = collOptions.timeseries != boost::none;
- auto ret = std::make_unique<StandardWiredTigerRecordStore>(&_engine, &opCtx, params);
- ret->postConstructorInit(&opCtx);
+ auto ret = std::make_unique<StandardWiredTigerRecordStore>(&_engine, opCtx.get(), params);
+ ret->postConstructorInit(opCtx.get());
return std::move(ret);
}
std::unique_ptr<RecordStore> WiredTigerHarnessHelper::newOplogRecordStore() {
auto ret = newOplogRecordStoreNoInit();
- auto* ru = _engine.newRecoveryUnit();
- OperationContextNoop opCtx(ru);
- dynamic_cast<WiredTigerRecordStore*>(ret.get())->postConstructorInit(&opCtx);
+ ServiceContext::UniqueOperationContext opCtx(newOperationContext());
+ dynamic_cast<WiredTigerRecordStore*>(ret.get())->postConstructorInit(opCtx.get());
return ret;
}
std::unique_ptr<RecordStore> WiredTigerHarnessHelper::newOplogRecordStoreNoInit() {
- WiredTigerRecoveryUnit* ru = dynamic_cast<WiredTigerRecoveryUnit*>(_engine.newRecoveryUnit());
- OperationContextNoop opCtx(ru);
+ ServiceContext::UniqueOperationContext opCtx(newOperationContext());
+ WiredTigerRecoveryUnit* ru = checked_cast<WiredTigerRecoveryUnit*>(opCtx->recoveryUnit());
std::string ident = NamespaceString::kRsOplogNamespace.ns();
std::string uri = WiredTigerKVEngine::kTableUriPrefix + ident;
@@ -137,7 +139,7 @@ std::unique_ptr<RecordStore> WiredTigerHarnessHelper::newOplogRecordStoreNoInit(
std::string config = result.getValue();
{
- WriteUnitOfWork uow(&opCtx);
+ WriteUnitOfWork uow(opCtx.get());
WT_SESSION* s = ru->getSession()->getSession();
invariantWTOK(s->create(s, uri.c_str(), config.c_str()), s);
uow.commit();
@@ -159,15 +161,16 @@ std::unique_ptr<RecordStore> WiredTigerHarnessHelper::newOplogRecordStoreNoInit(
params.isReadOnly = false;
params.tracksSizeAdjustments = true;
params.forceUpdateWithFullDocument = false;
- return std::make_unique<StandardWiredTigerRecordStore>(&_engine, &opCtx, params);
+ return std::make_unique<StandardWiredTigerRecordStore>(&_engine, opCtx.get(), params);
}
std::unique_ptr<RecoveryUnit> WiredTigerHarnessHelper::newRecoveryUnit() {
return std::unique_ptr<RecoveryUnit>(_engine.newRecoveryUnit());
}
-std::unique_ptr<RecordStoreHarnessHelper> makeWTRSHarnessHelper() {
- return std::make_unique<WiredTigerHarnessHelper>();
+std::unique_ptr<RecordStoreHarnessHelper> makeWTRSHarnessHelper(
+ RecordStoreHarnessHelper::Options options) {
+ return std::make_unique<WiredTigerHarnessHelper>(options);
}
MONGO_INITIALIZER(RegisterRecordStoreHarnessFactory)(InitializerContext* const) {
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.h b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.h
index 97e9b2ad7b4..8a9ef19b16e 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.h
@@ -39,9 +39,12 @@ namespace mongo {
class WiredTigerHarnessHelper final : public RecordStoreHarnessHelper {
public:
- WiredTigerHarnessHelper() : WiredTigerHarnessHelper(""_sd) {}
+ WiredTigerHarnessHelper() : WiredTigerHarnessHelper(Options::ReplicationEnabled, ""_sd) {}
+ WiredTigerHarnessHelper(Options options) : WiredTigerHarnessHelper(options, ""_sd) {}
+ WiredTigerHarnessHelper(StringData extraStrings)
+ : WiredTigerHarnessHelper(Options::ReplicationEnabled, extraStrings) {}
- WiredTigerHarnessHelper(StringData extraStrings);
+ WiredTigerHarnessHelper(Options options, StringData extraStrings);
~WiredTigerHarnessHelper() {}
virtual std::unique_ptr<RecordStore> newRecordStore() override {