summaryrefslogtreecommitdiff
path: root/src/mongo/db/index/index_access_method.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/index/index_access_method.cpp')
-rw-r--r--src/mongo/db/index/index_access_method.cpp157
1 files changed, 36 insertions, 121 deletions
diff --git a/src/mongo/db/index/index_access_method.cpp b/src/mongo/db/index/index_access_method.cpp
index 4d454f2b5a3..63148efb8cf 100644
--- a/src/mongo/db/index/index_access_method.cpp
+++ b/src/mongo/db/index/index_access_method.cpp
@@ -31,7 +31,7 @@
#include "mongo/platform/basic.h"
-#include "mongo/db/index/index_access_method.h"
+#include "mongo/db/index/btree_access_method.h"
#include <utility>
#include <vector>
@@ -42,17 +42,10 @@
#include "mongo/db/catalog/index_consistency.h"
#include "mongo/db/client.h"
#include "mongo/db/commands/server_status.h"
-#include "mongo/db/concurrency/exception_util.h"
+#include "mongo/db/concurrency/write_conflict_exception.h"
#include "mongo/db/curop.h"
-#include "mongo/db/index/2d_access_method.h"
-#include "mongo/db/index/btree_access_method.h"
-#include "mongo/db/index/fts_access_method.h"
-#include "mongo/db/index/hash_access_method.h"
#include "mongo/db/index/index_build_interceptor.h"
#include "mongo/db/index/index_descriptor.h"
-#include "mongo/db/index/s2_access_method.h"
-#include "mongo/db/index/s2_bucket_access_method.h"
-#include "mongo/db/index/wildcard_access_method.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/keypattern.h"
#include "mongo/db/operation_context.h"
@@ -60,7 +53,6 @@
#include "mongo/db/repl/timestamp_block.h"
#include "mongo/db/sorter/sorter.h"
#include "mongo/db/storage/execution_context.h"
-#include "mongo/db/storage/kv/kv_engine.h"
#include "mongo/db/storage/storage_options.h"
#include "mongo/logv2/log.h"
#include "mongo/platform/atomic_word.h"
@@ -79,35 +71,6 @@ MONGO_FAIL_POINT_DEFINE(hangIndexBuildDuringBulkLoadPhaseSecond);
MONGO_FAIL_POINT_DEFINE(hangDuringIndexBuildBulkLoadYield);
MONGO_FAIL_POINT_DEFINE(hangDuringIndexBuildBulkLoadYieldSecond);
-/**
- * Static factory method that constructs and returns an appropriate IndexAccessMethod depending on
- * the type of the index.
- */
-std::unique_ptr<IndexAccessMethod> IndexAccessMethod::make(
- IndexCatalogEntry* entry, std::unique_ptr<SortedDataInterface> sortedDataInterface) {
- auto desc = entry->descriptor();
- const std::string& type = desc->getAccessMethodName();
- if ("" == type)
- return std::make_unique<BtreeAccessMethod>(entry, std::move(sortedDataInterface));
- else if (IndexNames::HASHED == type)
- return std::make_unique<HashAccessMethod>(entry, std::move(sortedDataInterface));
- else if (IndexNames::GEO_2DSPHERE == type)
- return std::make_unique<S2AccessMethod>(entry, std::move(sortedDataInterface));
- else if (IndexNames::GEO_2DSPHERE_BUCKET == type)
- return std::make_unique<S2BucketAccessMethod>(entry, std::move(sortedDataInterface));
- else if (IndexNames::TEXT == type)
- return std::make_unique<FTSAccessMethod>(entry, std::move(sortedDataInterface));
- else if (IndexNames::GEO_2D == type)
- return std::make_unique<TwoDAccessMethod>(entry, std::move(sortedDataInterface));
- else if (IndexNames::WILDCARD == type)
- return std::make_unique<WildcardAccessMethod>(entry, std::move(sortedDataInterface));
- LOGV2(20688,
- "Can't find index for keyPattern {keyPattern}",
- "Can't find index for keyPattern",
- "keyPattern"_attr = desc->keyPattern());
- fassertFailed(31021);
-}
-
namespace {
/**
@@ -136,10 +99,6 @@ public:
builder.append("resumed", resumed.loadRelaxed());
builder.append("filesOpenedForExternalSort", sorterFileStats.opened.loadRelaxed());
builder.append("filesClosedForExternalSort", sorterFileStats.closed.loadRelaxed());
- builder.append("spilledRanges", sorterTracker.spilledRanges.loadRelaxed());
- builder.append("bytesSpilledUncompressed",
- sorterTracker.bytesSpilledUncompressed.loadRelaxed());
- builder.append("bytesSpilled", sorterTracker.bytesSpilled.loadRelaxed());
return builder.obj();
}
@@ -150,15 +109,11 @@ public:
// This value should not exceed 'count'.
AtomicWord<long long> resumed;
- // Sorter statistics that are aggregate of all sorters.
- SorterTracker sorterTracker;
-
// Number of times the external sorter opened/closed a file handle to spill data to disk.
// This pair of counters in aggregate indicate the number of open file handles used by
// the external sorter and may be useful in diagnosing situations where the process is
// close to exhausting this finite resource.
- SorterFileStats sorterFileStats = {&sorterTracker};
-
+ SorterFileStats sorterFileStats;
} indexBulkBuilderSSS;
/**
@@ -177,9 +132,7 @@ SortOptions makeSortOptions(size_t maxMemoryUsageBytes, StringData dbName) {
.TempDir(storageGlobalParams.dbpath + "/_tmp")
.ExtSortAllowed()
.MaxMemoryUsageBytes(maxMemoryUsageBytes)
- .UseMemoryPool(true)
.FileStats(&indexBulkBuilderSSS.sorterFileStats)
- .Tracker(&indexBulkBuilderSSS.sorterTracker)
.DBName(dbName.toString());
}
@@ -412,13 +365,6 @@ void SortedDataIndexAccessMethod::removeOneKey(OperationContext* opCtx,
try {
_newInterface->unindex(opCtx, keyString, dupsAllowed);
} catch (AssertionException& e) {
- if (e.code() == ErrorCodes::DataCorruptionDetected) {
- // DataCorruptionDetected errors are expected to have logged an error and added an entry
- // to the health log with the stack trace at the location where the error was initially
- // thrown. No need to do so again.
- throw;
- }
-
NamespaceString ns = _indexCatalogEntry->getNSSFromCatalog(opCtx);
LOGV2(20683,
"Assertion failure: _unindex failed on: {namespace} for index: {indexName}. "
@@ -500,13 +446,9 @@ RecordId SortedDataIndexAccessMethod::findSingle(OperationContext* opCtx,
void SortedDataIndexAccessMethod::validate(OperationContext* opCtx,
int64_t* numKeys,
IndexValidateResults* fullResults) const {
- if (numKeys) {
- long long keys = 0;
- _newInterface->fullValidate(opCtx, &keys, fullResults);
- *numKeys = keys;
- } else {
- _newInterface->fullValidate(opCtx, nullptr, fullResults);
- }
+ long long keys = 0;
+ _newInterface->fullValidate(opCtx, &keys, fullResults);
+ *numKeys = keys;
}
bool SortedDataIndexAccessMethod::appendCustomStats(OperationContext* opCtx,
@@ -638,8 +580,7 @@ Status SortedDataIndexAccessMethod::doUpdate(OperationContext* opCtx,
// Add all new data keys into the index.
for (const auto& keyString : ticket.added) {
- bool dupsAllowed = (!_descriptor->prepareUnique() || !opCtx->isEnforcingConstraints()) &&
- ticket.dupsAllowed;
+ bool dupsAllowed = !_descriptor->prepareUnique() && ticket.dupsAllowed;
auto status = _newInterface->insert(opCtx, keyString, dupsAllowed);
if (!status.isOK())
return status;
@@ -668,23 +609,6 @@ Ident* SortedDataIndexAccessMethod::getIdentPtr() const {
return this->_newInterface.get();
}
-void IndexAccessMethod::BulkBuilder::countNewBuildInStats() {
- indexBulkBuilderSSS.count.addAndFetch(1);
-}
-
-void IndexAccessMethod::BulkBuilder::countResumedBuildInStats() {
- indexBulkBuilderSSS.count.addAndFetch(1);
- indexBulkBuilderSSS.resumed.addAndFetch(1);
-}
-
-SorterFileStats* IndexAccessMethod::BulkBuilder::bulkBuilderFileStats() {
- return &indexBulkBuilderSSS.sorterFileStats;
-}
-
-SorterTracker* IndexAccessMethod::BulkBuilder::bulkBuilderTracker() {
- return &indexBulkBuilderSSS.sorterTracker;
-}
-
class SortedDataIndexAccessMethod::BulkBuilderImpl final : public IndexAccessMethod::BulkBuilder {
public:
using Sorter = mongo::Sorter<KeyString::Value, mongo::NullValue>;
@@ -700,6 +624,7 @@ public:
Status insert(OperationContext* opCtx,
const CollectionPtr& collection,
+ SharedBufferFragmentBuilder& pooledBuilder,
const BSONObj& obj,
const RecordId& loc,
const InsertDeleteOptions& options,
@@ -783,6 +708,7 @@ SortedDataIndexAccessMethod::BulkBuilderImpl::BulkBuilderImpl(SortedDataIndexAcc
Status SortedDataIndexAccessMethod::BulkBuilderImpl::insert(
OperationContext* opCtx,
const CollectionPtr& collection,
+ SharedBufferFragmentBuilder& pooledBuilder,
const BSONObj& obj,
const RecordId& loc,
const InsertDeleteOptions& options,
@@ -796,7 +722,7 @@ Status SortedDataIndexAccessMethod::BulkBuilderImpl::insert(
try {
_iam->getKeys(opCtx,
collection,
- _sorter->memPool(),
+ pooledBuilder,
obj,
options.getKeysMode,
GetKeysContext::kAddingKeys,
@@ -917,23 +843,26 @@ void SortedDataIndexAccessMethod::BulkBuilderImpl::_yield(OperationContext* opCt
auto locker = opCtx->lockState();
Locker::LockSnapshot snapshot;
- locker->saveLockStateAndUnlock(&snapshot);
-
- // Track the number of yields in CurOp.
- CurOp::get(opCtx)->yielded();
-
- auto failPointHang = [opCtx, &ns](FailPoint* fp) {
- fp->executeIf(
- [fp](auto&&) {
- LOGV2(5180600, "Hanging index build during bulk load yield");
- fp->pauseWhileSet();
- },
- [opCtx, &ns](auto&& config) { return config.getStringField("namespace") == ns.ns(); });
- };
- failPointHang(&hangDuringIndexBuildBulkLoadYield);
- failPointHang(&hangDuringIndexBuildBulkLoadYieldSecond);
-
- locker->restoreLockState(opCtx, snapshot);
+ if (locker->saveLockStateAndUnlock(&snapshot)) {
+
+ // Track the number of yields in CurOp.
+ CurOp::get(opCtx)->yielded();
+
+ auto failPointHang = [opCtx, &ns](FailPoint* fp) {
+ fp->executeIf(
+ [fp](auto&&) {
+ LOGV2(5180600, "Hanging index build during bulk load yield");
+ fp->pauseWhileSet();
+ },
+ [opCtx, &ns](auto&& config) {
+ return config.getStringField("namespace") == ns.ns();
+ });
+ };
+ failPointHang(&hangDuringIndexBuildBulkLoadYield);
+ failPointHang(&hangDuringIndexBuildBulkLoadYieldSecond);
+
+ locker->restoreLockState(opCtx, snapshot);
+ }
yieldable->restore();
}
@@ -1215,16 +1144,6 @@ Status SortedDataIndexAccessMethod::_indexKeysOrWriteToSideTable(
*keysInsertedOut += inserted;
}
} else {
- // Ensure that our snapshot is compatible with the index's minimum visibile snapshot.
- const auto minVisibleTimestamp = _indexCatalogEntry->getMinimumVisibleSnapshot();
- const auto readTimestamp =
- opCtx->recoveryUnit()->getPointInTimeReadTimestamp(opCtx).value_or(
- opCtx->recoveryUnit()->getCatalogConflictingTimestamp());
- if (minVisibleTimestamp && !readTimestamp.isNull() &&
- readTimestamp < *minVisibleTimestamp) {
- throw WriteConflictException();
- }
-
int64_t numInserted = 0;
status = insertKeysAndUpdateMultikeyPaths(
opCtx,
@@ -1280,16 +1199,12 @@ void SortedDataIndexAccessMethod::_unindexKeysOrWriteToSideTable(
// are allowed in unique indexes, WiredTiger does not do blind unindexing, and instead confirms
// that the recordid matches the element we are removing.
//
- // We need to disable blind-deletes if 'checkRecordId' is explicitly set 'On'.
- options.dupsAllowed = options.dupsAllowed || checkRecordId == CheckRecordId::On;
-
- // Ensure that our snapshot is compatible with the index's minimum visibile snapshot.
- const auto minVisibleTimestamp = _indexCatalogEntry->getMinimumVisibleSnapshot();
- const auto readTimestamp = opCtx->recoveryUnit()->getPointInTimeReadTimestamp(opCtx).value_or(
- opCtx->recoveryUnit()->getCatalogConflictingTimestamp());
- if (minVisibleTimestamp && !readTimestamp.isNull() && readTimestamp < *minVisibleTimestamp) {
- throw WriteConflictException();
- }
+ // We need to disable blind-deletes if 'checkRecordId' is explicitly set 'On', or for
+ // in-progress indexes, in order to force recordid-matching for unindex operations, since
+ // initial sync can build an index over a collection with duplicates. See SERVER-17487 for more
+ // details.
+ options.dupsAllowed = options.dupsAllowed || !_indexCatalogEntry->isReady(opCtx) ||
+ (checkRecordId == CheckRecordId::On);
int64_t removed = 0;
Status status = removeKeys(opCtx, keys, options, &removed);