summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeert Bosch <geert@mongodb.com>2017-06-28 14:17:30 -0400
committerGeert Bosch <geert@mongodb.com>2017-07-03 14:54:37 -0400
commitd362678ea9a9e4e948bfda0bc60e2fefdd1eb045 (patch)
tree2b6ca0fb605b361bbb60ccb7d26efc2fa914391c
parente4ee6ba2f69d402bb682decd53f635146cc3fafb (diff)
downloadmongo-d362678ea9a9e4e948bfda0bc60e2fefdd1eb045.tar.gz
SERVER-29904 don't generate convertToCapped oplog entries
-rw-r--r--jstests/core/system_profile.js7
-rw-r--r--jstests/replsets/system_profile.js6
-rw-r--r--src/mongo/db/catalog/capped_utils.cpp102
-rw-r--r--src/mongo/db/op_observer.h5
-rw-r--r--src/mongo/db/op_observer_impl.cpp34
-rw-r--r--src/mongo/db/op_observer_impl.h5
-rw-r--r--src/mongo/db/op_observer_noop.cpp6
-rw-r--r--src/mongo/db/op_observer_noop.h5
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