diff options
author | Geert Bosch <geert@mongodb.com> | 2017-06-28 14:17:30 -0400 |
---|---|---|
committer | Geert Bosch <geert@mongodb.com> | 2017-07-03 14:54:37 -0400 |
commit | d362678ea9a9e4e948bfda0bc60e2fefdd1eb045 (patch) | |
tree | 2b6ca0fb605b361bbb60ccb7d26efc2fa914391c | |
parent | e4ee6ba2f69d402bb682decd53f635146cc3fafb (diff) | |
download | mongo-d362678ea9a9e4e948bfda0bc60e2fefdd1eb045.tar.gz |
SERVER-29904 don't generate convertToCapped oplog entries
-rw-r--r-- | jstests/core/system_profile.js | 7 | ||||
-rw-r--r-- | jstests/replsets/system_profile.js | 6 | ||||
-rw-r--r-- | src/mongo/db/catalog/capped_utils.cpp | 102 | ||||
-rw-r--r-- | src/mongo/db/op_observer.h | 5 | ||||
-rw-r--r-- | src/mongo/db/op_observer_impl.cpp | 34 | ||||
-rw-r--r-- | src/mongo/db/op_observer_impl.h | 5 | ||||
-rw-r--r-- | src/mongo/db/op_observer_noop.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/op_observer_noop.h | 5 |
8 files changed, 47 insertions, 123 deletions
diff --git a/jstests/core/system_profile.js b/jstests/core/system_profile.js index 09baf334290..0e3cacb030c 100644 --- a/jstests/core/system_profile.js +++ b/jstests/core/system_profile.js @@ -8,12 +8,13 @@ assert.commandWorked(testDB.dropDatabase()); assert.commandWorked(testDB.createCollection("system.profile")); testDB.system.profile.drop(); -// convertToCapped should succeed. +// convertToCapped should fail. assert.commandWorked(testDB.dropDatabase()); assert.commandWorked(testDB.createCollection("system.profile")); assert.eq(false, testDB.system.profile.stats().capped); -assert.commandWorked(testDB.system.profile.convertToCapped(1024 * 1024)); -assert.eq(true, testDB.system.profile.stats().capped); +assert.commandFailedWithCode(testDB.system.profile.convertToCapped(1024 * 1024), + ErrorCodes.BadValue); +assert.eq(false, testDB.system.profile.stats().capped); // Basic write operations should fail. assert.commandWorked(testDB.dropDatabase()); diff --git a/jstests/replsets/system_profile.js b/jstests/replsets/system_profile.js index 60620362491..ae524df1c75 100644 --- a/jstests/replsets/system_profile.js +++ b/jstests/replsets/system_profile.js @@ -45,10 +45,4 @@ assert.eq( op, getLatestOp(), "oplog entry created when system.profile was emptied via emptycapped"); assert(primaryDB.system.profile.drop()); - - // convertToCapped - assert.commandWorked(primaryDB.createCollection("system.profile")); - assert.commandWorked(primaryDB.runCommand({convertToCapped: "system.profile", size: 1000})); - assert.eq(op, getLatestOp(), "oplog entry created when system.profile was convertedToCapped"); - assert(primaryDB.system.profile.drop()); })(); diff --git a/src/mongo/db/catalog/capped_utils.cpp b/src/mongo/db/catalog/capped_utils.cpp index 3f26e0c5bd6..aff96becb3c 100644 --- a/src/mongo/db/catalog/capped_utils.cpp +++ b/src/mongo/db/catalog/capped_utils.cpp @@ -36,9 +36,12 @@ #include "mongo/db/background.h" #include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/collection_catalog_entry.h" +#include "mongo/db/catalog/create_collection.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/document_validation.h" +#include "mongo/db/catalog/drop_collection.h" #include "mongo/db/catalog/index_catalog.h" +#include "mongo/db/catalog/rename_collection.h" #include "mongo/db/client.h" #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/curop.h" @@ -133,7 +136,7 @@ mongo::Status mongo::cloneCollectionAsCapped(OperationContext* opCtx, return Status(ErrorCodes::NamespaceExists, "to collection already exists"); // create new collection - MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN { + { auto options = fromCollection->getCatalogEntry()->getCollectionOptions(opCtx); // The capped collection will get its own new unique id, as the conversion isn't reversible, // so it can't be rolled back. @@ -142,15 +145,14 @@ mongo::Status mongo::cloneCollectionAsCapped(OperationContext* opCtx, options.cappedSize = size; if (temp) options.temp = true; - OldClientContext ctx(opCtx, toNss.ns()); - WriteUnitOfWork wunit(opCtx); - Status status = userCreateNS(opCtx, ctx.db(), toNss.ns(), options.toBSON()); + BSONObjBuilder cmd; + cmd.append("create", toNss.coll()); + cmd.appendElements(options.toBSON()); + Status status = createCollection(opCtx, toNss.db().toString(), cmd.done()); if (!status.isOK()) return status; - wunit.commit(); } - MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "cloneCollectionAsCapped", fromNss.ns()); Collection* toCollection = db->getCollection(opCtx, toNss); invariant(toCollection); // we created above @@ -243,69 +245,51 @@ mongo::Status mongo::convertToCapped(OperationContext* opCtx, double size) { StringData dbname = collectionName.db(); StringData shortSource = collectionName.coll(); - - AutoGetDb autoDb(opCtx, collectionName.db(), MODE_X); - - bool userInitiatedWritesAndNotPrimary = opCtx->writesAreReplicated() && - !repl::getGlobalReplicationCoordinator()->canAcceptWritesFor(opCtx, collectionName); - - if (userInitiatedWritesAndNotPrimary) { - return Status(ErrorCodes::NotMaster, - str::stream() << "Not primary while converting " << collectionName.ns() - << " to a capped collection"); - } - - Database* const db = autoDb.getDb(); - if (!db) { - return Status(ErrorCodes::NamespaceNotFound, - str::stream() << "database " << dbname << " not found"); - } - - BackgroundOperation::assertNoBgOpInProgForDb(dbname); - auto opObserver = getGlobalServiceContext()->getOpObserver(); - - std::string shortTmpName = str::stream() << "tmp.convertToCapped." << shortSource; - NamespaceString longTmpName(dbname, shortTmpName); - - if (auto existingTmpColl = db->getCollection(opCtx, longTmpName)) { - WriteUnitOfWork wunit(opCtx); - Status status = db->dropCollection(opCtx, longTmpName.ns()); - if (!status.isOK()) - return status; - opObserver->onDropCollection(opCtx, longTmpName, existingTmpColl->uuid()); - wunit.commit(); - } + const std::string shortTmpName = str::stream() << "tmp.convertToCapped." << shortSource; + const NamespaceString longTmpName(dbname, shortTmpName); { - repl::UnreplicatedWritesBlock uwb(opCtx); - Status status = - cloneCollectionAsCapped(opCtx, db, shortSource.toString(), shortTmpName, size, true); + AutoGetDb autoDb(opCtx, collectionName.db(), MODE_X); - if (!status.isOK()) { - return status; + bool userInitiatedWritesAndNotPrimary = opCtx->writesAreReplicated() && + !repl::getGlobalReplicationCoordinator()->canAcceptWritesFor(opCtx, collectionName); + + if (userInitiatedWritesAndNotPrimary) { + return Status(ErrorCodes::NotMaster, + str::stream() << "Not primary while converting " << collectionName.ns() + << " to a capped collection"); } - } - OptionalCollectionUUID origUUID = db->getCollection(opCtx, collectionName)->uuid(); - OptionalCollectionUUID cappedUUID = db->getCollection(opCtx, longTmpName)->uuid(); + Database* const db = autoDb.getDb(); + if (!db) { + return Status(ErrorCodes::NamespaceNotFound, + str::stream() << "database " << dbname << " not found"); + } - { - WriteUnitOfWork wunit(opCtx); - { - repl::UnreplicatedWritesBlock uwb(opCtx); - Status status = db->dropCollection(opCtx, collectionName.ns()); + BackgroundOperation::assertNoBgOpInProgForDb(dbname); + + // If the temporary collection already exists due to an earlier aborted attempt, delete it. + if (db->getCollection(opCtx, longTmpName)) { + BSONObjBuilder unusedResult; + Status status = + dropCollection(opCtx, + longTmpName, + unusedResult, + repl::OpTime(), + DropCollectionSystemCollectionMode::kAllowSystemCollectionDrops); if (!status.isOK()) return status; } - Status status = db->renameCollection(opCtx, longTmpName.ns(), collectionName.ns(), false); - if (!status.isOK()) - return status; - - getGlobalServiceContext()->getOpObserver()->onConvertToCapped( - opCtx, collectionName, origUUID, cappedUUID, size); + { + Status status = cloneCollectionAsCapped( + opCtx, db, shortSource.toString(), shortTmpName, size, true); - wunit.commit(); + if (!status.isOK()) + return status; + } } - return Status::OK(); + + return renameCollection( + opCtx, longTmpName, collectionName, /*dropTarget*/ true, /*stayTemp*/ false); } diff --git a/src/mongo/db/op_observer.h b/src/mongo/db/op_observer.h index 742ada49432..d0b0fb03955 100644 --- a/src/mongo/db/op_observer.h +++ b/src/mongo/db/op_observer.h @@ -190,11 +190,6 @@ public: virtual void onEmptyCapped(OperationContext* opCtx, const NamespaceString& collectionName, OptionalCollectionUUID uuid) = 0; - virtual void onConvertToCapped(OperationContext* opCtx, - const NamespaceString& collectionName, - OptionalCollectionUUID origUUID, - OptionalCollectionUUID cappedUUID, - double size) = 0; }; } // namespace mongo diff --git a/src/mongo/db/op_observer_impl.cpp b/src/mongo/db/op_observer_impl.cpp index bafe2bd07f6..5d84cc77f72 100644 --- a/src/mongo/db/op_observer_impl.cpp +++ b/src/mongo/db/op_observer_impl.cpp @@ -410,40 +410,6 @@ void OpObserverImpl::onApplyOps(OperationContext* opCtx, getGlobalAuthorizationManager()->logOp(opCtx, "c", cmdNss, applyOpCmd, nullptr); } -void OpObserverImpl::onConvertToCapped(OperationContext* opCtx, - const NamespaceString& collectionName, - OptionalCollectionUUID origUUID, - OptionalCollectionUUID cappedUUID, - double size) { - const NamespaceString cmdNss = collectionName.getCommandNS(); - BSONObj cmdObj = BSON("convertToCapped" << collectionName.coll() << "size" << size); - - if (!collectionName.isSystemDotProfile()) { - // do not replicate system.profile modifications - repl::logOp(opCtx, "c", cmdNss, cappedUUID, cmdObj, nullptr, false); - } - - // Evict namespace entry from the namespace/uuid cache if it exists. - NamespaceUUIDCache& cache = NamespaceUUIDCache::get(opCtx); - cache.evictNamespace(collectionName); - opCtx->recoveryUnit()->onRollback( - [&cache, collectionName]() { cache.evictNamespace(collectionName); }); - - // Finally update the UUID Catalog. - UUIDCatalog& catalog = UUIDCatalog::get(opCtx); - if (origUUID) { - catalog.onDropCollection(opCtx, origUUID.get()); - } - if (cappedUUID) { - auto db = dbHolder().get(opCtx, collectionName.db()); - auto newColl = db->getCollection(opCtx, collectionName); - invariant(newColl); - catalog.onRenameCollection(opCtx, newColl, cappedUUID.get()); - } - - getGlobalAuthorizationManager()->logOp(opCtx, "c", cmdNss, cmdObj, nullptr); -} - void OpObserverImpl::onEmptyCapped(OperationContext* opCtx, const NamespaceString& collectionName, OptionalCollectionUUID uuid) { diff --git a/src/mongo/db/op_observer_impl.h b/src/mongo/db/op_observer_impl.h index 476711a86f5..35cd9184cca 100644 --- a/src/mongo/db/op_observer_impl.h +++ b/src/mongo/db/op_observer_impl.h @@ -94,11 +94,6 @@ public: void onEmptyCapped(OperationContext* opCtx, const NamespaceString& collectionName, OptionalCollectionUUID uuid); - void onConvertToCapped(OperationContext* opCtx, - const NamespaceString& collectionName, - OptionalCollectionUUID origUUID, - OptionalCollectionUUID cappedUUID, - double size) override; }; } // namespace mongo diff --git a/src/mongo/db/op_observer_noop.cpp b/src/mongo/db/op_observer_noop.cpp index 10901aa4cd0..47fafed9b97 100644 --- a/src/mongo/db/op_observer_noop.cpp +++ b/src/mongo/db/op_observer_noop.cpp @@ -135,12 +135,6 @@ void OpObserverNoop::onRenameCollection(OperationContext* opCtx, void OpObserverNoop::onApplyOps(OperationContext*, const std::string&, const BSONObj&) {} -void OpObserverNoop::onConvertToCapped(OperationContext*, - const NamespaceString&, - OptionalCollectionUUID, - OptionalCollectionUUID, - double) {} - void OpObserverNoop::onEmptyCapped(OperationContext*, const NamespaceString&, OptionalCollectionUUID) {} diff --git a/src/mongo/db/op_observer_noop.h b/src/mongo/db/op_observer_noop.h index 393b707f2c9..2aa4df846a0 100644 --- a/src/mongo/db/op_observer_noop.h +++ b/src/mongo/db/op_observer_noop.h @@ -94,11 +94,6 @@ public: void onEmptyCapped(OperationContext* opCtx, const NamespaceString& collectionName, OptionalCollectionUUID uuid); - void onConvertToCapped(OperationContext* opCtx, - const NamespaceString& collectionName, - OptionalCollectionUUID origUUID, - OptionalCollectionUUID cappedUUID, - double size) override; }; } // namespace mongo |