Пример #1
0
void AutoGetCollectionForRead::_ensureMajorityCommittedSnapshotIsValid(const NamespaceString& nss) {
    while (true) {
        auto coll = _autoColl->getCollection();
        if (!coll) {
            return;
        }
        auto minSnapshot = coll->getMinimumVisibleSnapshot();
        if (!minSnapshot) {
            return;
        }
        auto mySnapshot = _txn->recoveryUnit()->getMajorityCommittedSnapshot();
        if (!mySnapshot) {
            return;
        }
        if (mySnapshot >= minSnapshot) {
            return;
        }

        // Yield locks.
        _autoColl = boost::none;

        repl::ReplicationCoordinator::get(_txn)->waitUntilSnapshotCommitted(_txn, *minSnapshot);

        uassertStatusOK(_txn->recoveryUnit()->setReadFromMajorityCommittedSnapshot());

        {
            stdx::lock_guard<Client> lk(*_txn->getClient());
            CurOp::get(_txn)->yielded();
        }

        // Relock.
        _autoColl.emplace(_txn, nss, MODE_IS);
    }
}
Пример #2
0
MinVisibleTimestampMap closeCatalog(OperationContext* opCtx) {
    invariant(opCtx->lockState()->isW());

    MinVisibleTimestampMap minVisibleTimestampMap;
    std::vector<std::string> allDbs;
    opCtx->getServiceContext()->getStorageEngine()->listDatabases(&allDbs);

    auto databaseHolder = DatabaseHolder::get(opCtx);
    for (auto&& dbName : allDbs) {
        const auto db = databaseHolder->getDb(opCtx, dbName);
        for (auto collIt = db->begin(opCtx); collIt != db->end(opCtx); ++collIt) {
            auto coll = *collIt;
            if (!coll) {
                break;
            }

            OptionalCollectionUUID uuid = coll->uuid();
            boost::optional<Timestamp> minVisible = coll->getMinimumVisibleSnapshot();

            // If there's a minimum visible, invariant there's also a UUID.
            invariant(!minVisible || uuid);
            if (uuid && minVisible) {
                LOG(1) << "closeCatalog: preserving min visible timestamp. Collection: "
                       << coll->ns() << " UUID: " << uuid << " TS: " << minVisible;
                minVisibleTimestampMap[*uuid] = *minVisible;
            }
        }
    }

    // Need to mark the UUIDCatalog as open if we our closeAll fails, dismissed if successful.
    auto reopenOnFailure = makeGuard([opCtx] { UUIDCatalog::get(opCtx).onOpenCatalog(opCtx); });
    // Closing UUID Catalog: only lookupNSSByUUID will fall back to using pre-closing state to
    // allow authorization for currently unknown UUIDs. This is needed because authorization needs
    // to work before acquiring locks, and might otherwise spuriously regard a UUID as unknown
    // while reloading the catalog.
    UUIDCatalog::get(opCtx).onCloseCatalog(opCtx);
    LOG(1) << "closeCatalog: closing UUID catalog";

    // Close all databases.
    log() << "closeCatalog: closing all databases";
    databaseHolder->closeAll(opCtx);

    // Close the storage engine's catalog.
    log() << "closeCatalog: closing storage engine catalog";
    opCtx->getServiceContext()->getStorageEngine()->closeCatalog(opCtx);

    reopenOnFailure.dismiss();
    return minVisibleTimestampMap;
}