summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJosef Ahmad <josef.ahmad@mongodb.com>2021-12-01 09:17:15 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-12-01 09:42:25 +0000
commit1858238ec9d0cd4924c94a3f274a514c589f1154 (patch)
tree38fbb3393186325ba561e451c494510ca4ac06bb /src
parent630b966f4d6f502aeb30ff4706da60862a2f2b12 (diff)
downloadmongo-1858238ec9d0cd4924c94a3f274a514c589f1154.tar.gz
SERVER-61441 Improve robustness of clustered record store creation
This patch improves the usability of the internal record store API. * Reject creation of a clustered record store that uses an incompatible WiredTiger key format. * makeTemporaryRecordStore() automatically selects the appropriate WiredTiger key format and cursor settings for clustered record stores.
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/storage/devnull/devnull_kv_engine.h3
-rw-r--r--src/mongo/db/storage/durable_catalog_impl.cpp12
-rw-r--r--src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_kv_engine.cpp3
-rw-r--r--src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_kv_engine.h3
-rw-r--r--src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_record_store_test.cpp13
-rw-r--r--src/mongo/db/storage/kv/kv_drop_pending_ident_reaper_test.cpp3
-rw-r--r--src/mongo/db/storage/kv/kv_engine.h3
-rw-r--r--src/mongo/db/storage/kv/storage_engine_test.cpp26
-rw-r--r--src/mongo/db/storage/record_store_test_harness.cpp27
-rw-r--r--src/mongo/db/storage/record_store_test_harness.h4
-rw-r--r--src/mongo/db/storage/storage_engine_test_fixture.h4
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp21
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h3
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp22
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h3
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test.cpp70
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.cpp8
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.h4
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit_test.cpp2
19 files changed, 210 insertions, 24 deletions
diff --git a/src/mongo/db/storage/devnull/devnull_kv_engine.h b/src/mongo/db/storage/devnull/devnull_kv_engine.h
index 86fac5527af..f866a9340f5 100644
--- a/src/mongo/db/storage/devnull/devnull_kv_engine.h
+++ b/src/mongo/db/storage/devnull/devnull_kv_engine.h
@@ -52,7 +52,8 @@ public:
virtual Status createRecordStore(OperationContext* opCtx,
StringData ns,
StringData ident,
- const CollectionOptions& options) {
+ const CollectionOptions& options,
+ KeyFormat keyFormat = KeyFormat::Long) {
return Status::OK();
}
diff --git a/src/mongo/db/storage/durable_catalog_impl.cpp b/src/mongo/db/storage/durable_catalog_impl.cpp
index 686daf0da06..6d2b3535f6d 100644
--- a/src/mongo/db/storage/durable_catalog_impl.cpp
+++ b/src/mongo/db/storage/durable_catalog_impl.cpp
@@ -646,7 +646,17 @@ StatusWith<std::pair<RecordId, std::unique_ptr<RecordStore>>> DurableCatalogImpl
return swEntry.getStatus();
Entry& entry = swEntry.getValue();
- Status status = _engine->getEngine()->createRecordStore(opCtx, nss.ns(), entry.ident, options);
+ const auto keyFormat = [&] {
+ // Clustered collections require KeyFormat::String, but the opposite is not necessarily
+ // true: a clustered record store that is not associated with a collection has
+ // KeyFormat::String and and no CollectionOptions.
+ if (options.clusteredIndex) {
+ return KeyFormat::String;
+ }
+ return KeyFormat::Long;
+ }();
+ Status status =
+ _engine->getEngine()->createRecordStore(opCtx, nss.ns(), entry.ident, options, keyFormat);
if (!status.isOK())
return status;
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_kv_engine.cpp b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_kv_engine.cpp
index 678fad9e536..ae588195341 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_kv_engine.cpp
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_kv_engine.cpp
@@ -69,7 +69,8 @@ mongo::RecoveryUnit* KVEngine::newRecoveryUnit() {
Status KVEngine::createRecordStore(OperationContext* opCtx,
StringData ns,
StringData ident,
- const CollectionOptions& options) {
+ const CollectionOptions& options,
+ KeyFormat keyFormat) {
stdx::lock_guard lock(_identsLock);
_idents[ident.toString()] = true;
return Status::OK();
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_kv_engine.h b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_kv_engine.h
index 517bcf16df9..0f1ed9a936f 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_kv_engine.h
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_kv_engine.h
@@ -57,7 +57,8 @@ public:
virtual Status createRecordStore(OperationContext* opCtx,
StringData ns,
StringData ident,
- const CollectionOptions& options);
+ const CollectionOptions& options,
+ KeyFormat keyFormat = KeyFormat::Long);
virtual Status importRecordStore(OperationContext* opCtx,
StringData ident,
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 f37b95b9665..81eac126088 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
@@ -56,7 +56,18 @@ public:
}
virtual std::unique_ptr<mongo::RecordStore> newNonCappedRecordStore(
- const std::string& ns, const CollectionOptions& collOptions) {
+ const std::string& ns,
+ const CollectionOptions& collOptions,
+ KeyFormat keyFormat = KeyFormat::Long) {
+ if (collOptions.clusteredIndex) {
+ // A clustered collection requires both CollectionOptions.clusteredIndex and
+ // KeyFormat::String. For a clustered record store that is not associated with a
+ // clustered collection KeyFormat::String is sufficient.
+ uassert(6144102,
+ "RecordStore with CollectionOptions.clusteredIndex requires KeyFormat::String",
+ keyFormat == KeyFormat::String);
+ }
+
return std::make_unique<RecordStore>(ns,
"ident"_sd /* ident */,
collOptions.clusteredIndex ? KeyFormat::String
diff --git a/src/mongo/db/storage/kv/kv_drop_pending_ident_reaper_test.cpp b/src/mongo/db/storage/kv/kv_drop_pending_ident_reaper_test.cpp
index df4470cd80d..c206a052efc 100644
--- a/src/mongo/db/storage/kv/kv_drop_pending_ident_reaper_test.cpp
+++ b/src/mongo/db/storage/kv/kv_drop_pending_ident_reaper_test.cpp
@@ -72,7 +72,8 @@ public:
Status createRecordStore(OperationContext* opCtx,
StringData ns,
StringData ident,
- const CollectionOptions& options) override {
+ const CollectionOptions& options,
+ KeyFormat keyFormat) override {
return Status::OK();
}
std::unique_ptr<RecordStore> makeTemporaryRecordStore(OperationContext* opCtx,
diff --git a/src/mongo/db/storage/kv/kv_engine.h b/src/mongo/db/storage/kv/kv_engine.h
index 977380a7117..2120cdb2f7e 100644
--- a/src/mongo/db/storage/kv/kv_engine.h
+++ b/src/mongo/db/storage/kv/kv_engine.h
@@ -97,7 +97,8 @@ public:
virtual Status createRecordStore(OperationContext* opCtx,
StringData ns,
StringData ident,
- const CollectionOptions& options) = 0;
+ const CollectionOptions& options,
+ KeyFormat keyFormat = KeyFormat::Long) = 0;
virtual std::unique_ptr<RecordStore> makeTemporaryRecordStore(OperationContext* opCtx,
StringData ident,
diff --git a/src/mongo/db/storage/kv/storage_engine_test.cpp b/src/mongo/db/storage/kv/storage_engine_test.cpp
index 04c93fd8244..dd3f5714864 100644
--- a/src/mongo/db/storage/kv/storage_engine_test.cpp
+++ b/src/mongo/db/storage/kv/storage_engine_test.cpp
@@ -113,6 +113,32 @@ TEST_F(StorageEngineTest, LoadCatalogDropsOrphansAfterUncleanShutdown) {
ASSERT(!collectionExists(opCtx.get(), collNs));
}
+TEST_F(StorageEngineTest, TemporaryRecordStoreClustered) {
+ auto opCtx = cc().makeOperationContext();
+
+ Lock::GlobalLock lk(&*opCtx, MODE_IS);
+
+ const auto trs = makeTemporaryClustered(opCtx.get());
+ ASSERT(trs.get());
+ const auto rs = trs->rs();
+ ASSERT(identExists(opCtx.get(), rs->getIdent()));
+
+ // Insert record with RecordId of KeyFormat::String.
+ const auto id = StringData{"1"};
+ const auto rid = RecordId(id.rawData(), id.size());
+ const auto data = "data";
+ WriteUnitOfWork wuow(opCtx.get());
+ StatusWith<RecordId> s = rs->insertRecord(opCtx.get(), rid, data, strlen(data), Timestamp());
+ ASSERT_TRUE(s.isOK());
+ ASSERT_EQUALS(1, rs->numRecords(opCtx.get()));
+ wuow.commit();
+
+ // Read the record back.
+ RecordData rd;
+ ASSERT_TRUE(rs->findRecord(opCtx.get(), rid, &rd));
+ ASSERT_EQ(0, memcmp(data, rd.data(), strlen(data)));
+}
+
TEST_F(StorageEngineTest, ReconcileDropsTemporary) {
auto opCtx = cc().makeOperationContext();
diff --git a/src/mongo/db/storage/record_store_test_harness.cpp b/src/mongo/db/storage/record_store_test_harness.cpp
index 6dbd86f7d1f..93f0e33359e 100644
--- a/src/mongo/db/storage/record_store_test_harness.cpp
+++ b/src/mongo/db/storage/record_store_test_harness.cpp
@@ -413,7 +413,8 @@ TEST(RecordStoreTestHarness, ClusteredRecordStore) {
const std::string ns = "test.system.buckets.a";
CollectionOptions options;
options.clusteredIndex = clustered_util::makeCanonicalClusteredInfoForLegacyFormat();
- std::unique_ptr<RecordStore> rs = harnessHelper->newNonCappedRecordStore(ns, options);
+ std::unique_ptr<RecordStore> rs =
+ harnessHelper->newNonCappedRecordStore(ns, options, KeyFormat::String);
invariant(rs->keyFormat() == KeyFormat::String);
auto opCtx = harnessHelper->newOperationContext();
@@ -519,7 +520,8 @@ TEST(RecordStoreTestHarness, ClusteredRecordStoreSeekNear) {
const std::string ns = "test.system.buckets.a";
CollectionOptions options;
options.clusteredIndex = clustered_util::makeCanonicalClusteredInfoForLegacyFormat();
- std::unique_ptr<RecordStore> rs = harnessHelper->newNonCappedRecordStore(ns, options);
+ std::unique_ptr<RecordStore> rs =
+ harnessHelper->newNonCappedRecordStore(ns, options, KeyFormat::String);
invariant(rs->keyFormat() == KeyFormat::String);
auto opCtx = harnessHelper->newOperationContext();
@@ -581,5 +583,26 @@ TEST(RecordStoreTestHarness, ClusteredRecordStoreSeekNear) {
ASSERT_EQ(records[i].id, rec->id);
}
}
+
+TEST(RecordStoreTestHarness, ClusteredRecordMismatchedKeyFormat) {
+ const auto harnessHelper = newRecordStoreHarnessHelper();
+ const std::string ns = "test.system.buckets.a";
+ CollectionOptions options;
+ options.clusteredIndex = clustered_util::makeCanonicalClusteredInfoForLegacyFormat();
+ // Cannot create a clustered record store without KeyFormat::String.
+ bool failAsExpected = false;
+ try {
+ auto rs = harnessHelper->newNonCappedRecordStore(ns, options);
+ } catch (DBException& e) {
+ // 6144101: WiredTiger-specific error code
+ // 6144102: Ephemeral For Test-specific error code
+ ASSERT_GTE(e.toStatus().code(), 6144101);
+ ASSERT_LTE(e.toStatus().code(), 6144102);
+ failAsExpected = true;
+ }
+
+ ASSERT_EQ(failAsExpected, true);
+}
+
} // namespace
} // namespace mongo
diff --git a/src/mongo/db/storage/record_store_test_harness.h b/src/mongo/db/storage/record_store_test_harness.h
index 9863d22f821..a7d89080301 100644
--- a/src/mongo/db/storage/record_store_test_harness.h
+++ b/src/mongo/db/storage/record_store_test_harness.h
@@ -52,7 +52,9 @@ public:
}
virtual std::unique_ptr<RecordStore> newNonCappedRecordStore(
- const std::string& ns, const CollectionOptions& options) = 0;
+ const std::string& ns,
+ const CollectionOptions& options,
+ KeyFormat keyFormat = KeyFormat::Long) = 0;
virtual std::unique_ptr<RecordStore> newOplogRecordStore() = 0;
diff --git a/src/mongo/db/storage/storage_engine_test_fixture.h b/src/mongo/db/storage/storage_engine_test_fixture.h
index 81ee4eb7a75..18a803b60ae 100644
--- a/src/mongo/db/storage/storage_engine_test_fixture.h
+++ b/src/mongo/db/storage/storage_engine_test_fixture.h
@@ -94,6 +94,10 @@ public:
return _storageEngine->makeTemporaryRecordStore(opCtx, KeyFormat::Long);
}
+ std::unique_ptr<TemporaryRecordStore> makeTemporaryClustered(OperationContext* opCtx) {
+ return _storageEngine->makeTemporaryRecordStore(opCtx, KeyFormat::String);
+ }
+
/**
* Create a collection table in the KVEngine not reflected in the DurableCatalog.
*/
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
index 40b88204d2f..1420dbf73c8 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
@@ -73,6 +73,7 @@
#include "mongo/db/service_context.h"
#include "mongo/db/snapshot_window_options_gen.h"
#include "mongo/db/storage/journal_listener.h"
+#include "mongo/db/storage/key_format.h"
#include "mongo/db/storage/storage_file_util.h"
#include "mongo/db/storage/storage_options.h"
#include "mongo/db/storage/storage_parameters_gen.h"
@@ -1370,12 +1371,23 @@ void WiredTigerKVEngine::setSortedDataInterfaceExtraOptions(const std::string& o
Status WiredTigerKVEngine::createRecordStore(OperationContext* opCtx,
StringData ns,
StringData ident,
- const CollectionOptions& options) {
+ const CollectionOptions& options,
+ KeyFormat keyFormat) {
_ensureIdentPath(ident);
WiredTigerSession session(_conn);
- StatusWith<std::string> result =
- WiredTigerRecordStore::generateCreateString(_canonicalName, ns, ident, options, _rsOptions);
+ StatusWith<std::string> result = WiredTigerRecordStore::generateCreateString(
+ _canonicalName, ns, ident, options, _rsOptions, keyFormat);
+
+ if (options.clusteredIndex) {
+ // A clustered collection requires both CollectionOptions.clusteredIndex and
+ // KeyFormat::String. For a clustered record store that is not associated with a clustered
+ // collection KeyFormat::String is sufficient.
+ uassert(6144100,
+ "RecordStore with CollectionOptions.clusteredIndex requires KeyFormat::String",
+ keyFormat == KeyFormat::String);
+ }
+
if (!result.isOK()) {
return result.getStatus();
}
@@ -1628,9 +1640,8 @@ std::unique_ptr<RecordStore> WiredTigerKVEngine::makeTemporaryRecordStore(Operat
_ensureIdentPath(ident);
WiredTigerSession wtSession(_conn);
- CollectionOptions noOptions;
StatusWith<std::string> swConfig = WiredTigerRecordStore::generateCreateString(
- _canonicalName, "" /* internal table */, ident, noOptions, _rsOptions);
+ _canonicalName, "" /* internal table */, ident, CollectionOptions(), _rsOptions, keyFormat);
uassertStatusOK(swConfig.getStatus());
std::string config = swConfig.getValue();
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
index de5e1292bad..f64b39d555d 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
@@ -133,7 +133,8 @@ public:
Status createRecordStore(OperationContext* opCtx,
StringData ns,
StringData ident,
- const CollectionOptions& options) override;
+ const CollectionOptions& options,
+ KeyFormat keyFormat = KeyFormat::Long) override;
std::unique_ptr<RecordStore> getRecordStore(OperationContext* opCtx,
StringData ns,
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp
index 566745b8223..8481f67344a 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp
@@ -764,7 +764,9 @@ StatusWith<std::string> WiredTigerRecordStore::generateCreateString(
StringData ns,
StringData ident,
const CollectionOptions& options,
- StringData extraStrings) {
+ StringData extraStrings,
+ KeyFormat keyFormat) {
+
// Separate out a prefix and suffix in the default string. User configuration will
// override values in the prefix, but not values in the suffix.
str::stream ss;
@@ -826,6 +828,14 @@ StatusWith<std::string> WiredTigerRecordStore::generateCreateString(
// WARNING: No user-specified config can appear below this line. These options are required
// for correct behavior of the server.
if (options.clusteredIndex) {
+ // A clustered collection requires both CollectionOptions.clusteredIndex and
+ // KeyFormat::String. For a clustered record store that is not associated with a clustered
+ // collection KeyFormat::String is sufficient.
+ uassert(6144101,
+ "RecordStore with CollectionOptions.clusteredIndex requires KeyFormat::String",
+ keyFormat == KeyFormat::String);
+ }
+ if (keyFormat == KeyFormat::String) {
// If the RecordId format is a String, assume a byte array key format.
ss << "key_format=u";
} else {
@@ -881,6 +891,16 @@ WiredTigerRecordStore::WiredTigerRecordStore(WiredTigerKVEngine* kvEngine,
_kvEngine(kvEngine) {
invariant(getIdent().size() > 0);
+ if (kDebugBuild && _keyFormat == KeyFormat::String) {
+ // This is a clustered record store. Its WiredTiger table requires key_format='u' for
+ // correct operation.
+ const std::string wtTableConfig =
+ uassertStatusOK(WiredTigerUtil::getMetadataCreate(ctx, _uri));
+ const bool wtTableConfigMatchesStringKeyFormat =
+ wtTableConfig.find("key_format=u") != string::npos;
+ invariant(wtTableConfigMatchesStringKeyFormat);
+ }
+
if (_oplogMaxSize) {
invariant(_isOplog, str::stream() << "Namespace " << params.ns);
}
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h
index 821cda6bf3a..7369138051d 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h
@@ -98,7 +98,8 @@ public:
StringData ns,
StringData ident,
const CollectionOptions& options,
- StringData extraStrings);
+ StringData extraStrings,
+ KeyFormat keyFormat);
struct Params {
StringData ns;
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test.cpp
index 7ccc4e7eb64..24c10fa085d 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test.cpp
@@ -38,6 +38,7 @@
#include "mongo/base/init.h"
#include "mongo/base/string_data.h"
#include "mongo/bson/bsonobjbuilder.h"
+#include "mongo/db/catalog/clustered_collection_util.h"
#include "mongo/db/concurrency/write_conflict_exception.h"
#include "mongo/db/json.h"
#include "mongo/db/operation_context_noop.h"
@@ -1071,5 +1072,74 @@ TEST(WiredTigerRecordStoreTest, CursorInActiveTxnAfterSeek) {
}
}
+// Verify clustered record stores.
+// This test case complements StorageEngineTest:TemporaryRecordStoreClustered which verifies
+// clustered temporary record stores.
+TEST(WiredTigerRecordStoreTest, ClusteredRecordStore) {
+ const unique_ptr<RecordStoreHarnessHelper> harnessHelper(newRecordStoreHarnessHelper());
+ const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
+
+ ASSERT(opCtx.get());
+ const std::string ns = "testRecordStore";
+ const std::string uri = WiredTigerKVEngine::kTableUriPrefix + ns;
+ const StatusWith<std::string> result = WiredTigerRecordStore::generateCreateString(
+ kWiredTigerEngineName, ns, "", CollectionOptions(), "", KeyFormat::String);
+ ASSERT_TRUE(result.isOK());
+ const std::string config = result.getValue();
+
+ {
+ WriteUnitOfWork uow(opCtx.get());
+ WiredTigerRecoveryUnit* ru =
+ checked_cast<WiredTigerRecoveryUnit*>(opCtx.get()->recoveryUnit());
+ WT_SESSION* s = ru->getSession()->getSession();
+ invariantWTOK(s->create(s, uri.c_str(), config.c_str()));
+ uow.commit();
+ }
+
+ WiredTigerRecordStore::Params params;
+ params.ns = ns;
+ params.ident = ns;
+ params.engineName = kWiredTigerEngineName;
+ params.isCapped = false;
+ params.keyFormat = KeyFormat::String;
+ params.overwrite = false;
+ params.isEphemeral = false;
+ params.cappedCallback = nullptr;
+ params.sizeStorer = nullptr;
+ params.tracksSizeAdjustments = true;
+ params.isReadOnly = false;
+ params.forceUpdateWithFullDocument = false;
+
+ const auto wtKvEngine = dynamic_cast<WiredTigerKVEngine*>(harnessHelper->getEngine());
+ auto rs = std::make_unique<StandardWiredTigerRecordStore>(wtKvEngine, opCtx.get(), params);
+ rs->postConstructorInit(opCtx.get());
+
+ const auto id = StringData{"1"};
+ const auto rid = RecordId(id.rawData(), id.size());
+ const auto data = "data";
+ {
+ WriteUnitOfWork wuow(opCtx.get());
+ StatusWith<RecordId> s =
+ rs->insertRecord(opCtx.get(), rid, data, strlen(data), Timestamp());
+ ASSERT_TRUE(s.isOK());
+ ASSERT_EQUALS(1, rs->numRecords(opCtx.get()));
+ wuow.commit();
+ }
+ // Read the record back.
+ RecordData rd;
+ ASSERT_TRUE(rs->findRecord(opCtx.get(), rid, &rd));
+ ASSERT_EQ(0, memcmp(data, rd.data(), strlen(data)));
+ // Update the record.
+ const auto dataUpdated = "updated";
+ {
+ WriteUnitOfWork wuow(opCtx.get());
+ ASSERT_OK(rs->updateRecord(opCtx.get(), rid, dataUpdated, strlen(dataUpdated)));
+ ASSERT_EQUALS(1, rs->numRecords(opCtx.get()));
+ wuow.commit();
+ }
+ ASSERT_TRUE(rs->findRecord(opCtx.get(), rid, &rd));
+ ASSERT_EQ(0, memcmp(dataUpdated, rd.data(), strlen(dataUpdated)));
+}
+
} // namespace
} // namespace mongo
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 d44a205a6f8..40d0c09f53a 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
@@ -54,14 +54,14 @@ WiredTigerHarnessHelper::WiredTigerHarnessHelper(StringData extraStrings)
}
std::unique_ptr<RecordStore> WiredTigerHarnessHelper::newNonCappedRecordStore(
- const std::string& ns, const CollectionOptions& collOptions) {
+ const std::string& ns, const CollectionOptions& collOptions, KeyFormat keyFormat) {
WiredTigerRecoveryUnit* ru = checked_cast<WiredTigerRecoveryUnit*>(_engine.newRecoveryUnit());
OperationContextNoop opCtx(ru);
std::string uri = WiredTigerKVEngine::kTableUriPrefix + ns;
StringData ident = ns;
StatusWith<std::string> result = WiredTigerRecordStore::generateCreateString(
- kWiredTigerEngineName, ns, ident, collOptions, "");
+ kWiredTigerEngineName, ns, ident, collOptions, "", keyFormat);
ASSERT_TRUE(result.isOK());
std::string config = result.getValue();
@@ -109,8 +109,8 @@ std::unique_ptr<RecordStore> WiredTigerHarnessHelper::newOplogRecordStoreNoInit(
options.capped = true;
const std::string ns = NamespaceString::kRsOplogNamespace.toString();
- StatusWith<std::string> result =
- WiredTigerRecordStore::generateCreateString(kWiredTigerEngineName, ns, ident, options, "");
+ StatusWith<std::string> result = WiredTigerRecordStore::generateCreateString(
+ kWiredTigerEngineName, ns, ident, options, "", KeyFormat::Long);
ASSERT_TRUE(result.isOK());
std::string config = result.getValue();
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 42d7923e465..43a4007d718 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
@@ -53,7 +53,9 @@ public:
}
virtual std::unique_ptr<RecordStore> newNonCappedRecordStore(
- const std::string& ns, const CollectionOptions& collOptions) override;
+ const std::string& ns,
+ const CollectionOptions& collOptions,
+ KeyFormat keyFormat = KeyFormat::Long) override;
virtual std::unique_ptr<RecordStore> newOplogRecordStore() override;
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit_test.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit_test.cpp
index c763bbef839..07480a1ce6a 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit_test.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit_test.cpp
@@ -81,7 +81,7 @@ public:
std::string ident = ns;
std::string uri = WiredTigerKVEngine::kTableUriPrefix + ns;
StatusWith<std::string> result = WiredTigerRecordStore::generateCreateString(
- kWiredTigerEngineName, ns, ident, CollectionOptions(), "");
+ kWiredTigerEngineName, ns, ident, CollectionOptions(), "", KeyFormat::Long);
ASSERT_TRUE(result.isOK());
std::string config = result.getValue();