diff options
author | Mathias Stearn <mathias@10gen.com> | 2015-02-04 14:40:58 -0500 |
---|---|---|
committer | Ramon Fernandez <ramon@mongodb.com> | 2015-02-15 10:27:19 -0500 |
commit | e71db695221e39b3b6aa972d7503ca8c52c8fd55 (patch) | |
tree | 79097883f56123180bde4975d0ea2fcaaad0eda2 | |
parent | 79492d9cc1885d74b31b5fe24194dbc227096d6e (diff) | |
download | mongo-e71db695221e39b3b6aa972d7503ca8c52c8fd55.tar.gz |
SERVER-17175 Use X lock for $isolated updates and deletes
(cherry picked from commit 7286fb36c36daaa8ee4941fa5f6c225b0a25dc61)
-rw-r--r-- | src/mongo/db/commands/write_commands/batch_executor.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/instance.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/ops/parsed_delete.cpp | 12 | ||||
-rw-r--r-- | src/mongo/db/ops/parsed_delete.h | 5 | ||||
-rw-r--r-- | src/mongo/db/ops/parsed_update.cpp | 12 | ||||
-rw-r--r-- | src/mongo/db/ops/parsed_update.h | 5 |
6 files changed, 36 insertions, 12 deletions
diff --git a/src/mongo/db/commands/write_commands/batch_executor.cpp b/src/mongo/db/commands/write_commands/batch_executor.cpp index 0d2560b486e..d42d4e1a826 100644 --- a/src/mongo/db/commands/write_commands/batch_executor.cpp +++ b/src/mongo/db/commands/write_commands/batch_executor.cpp @@ -1247,7 +1247,7 @@ namespace mongo { Lock::DBLock dbLock(txn->lockState(), nsString.db(), MODE_IX); Lock::CollectionLock colLock(txn->lockState(), nsString.ns(), - MODE_IX); + parsedUpdate.isIsolated() ? MODE_X : MODE_IX); /////////////////////////////////////////// if (!checkIsMasterForDatabase(nsString, result)) { @@ -1388,7 +1388,9 @@ namespace mongo { break; } - Lock::CollectionLock collLock(txn->lockState(), nss.ns(), MODE_IX); + Lock::CollectionLock collLock(txn->lockState(), + nss.ns(), + parsedDelete.isIsolated() ? MODE_X : MODE_IX); // getExecutorDelete() also checks if writes are allowed. if (!checkIsMasterForDatabase(nss, result)) { diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp index 0b75def0e27..7b86671e723 100644 --- a/src/mongo/db/instance.cpp +++ b/src/mongo/db/instance.cpp @@ -594,7 +594,9 @@ namespace mongo { // If DB doesn't exist, don't implicitly create it in Client::Context break; } - Lock::CollectionLock colLock(txn->lockState(), ns.ns(), MODE_IX); + Lock::CollectionLock collLock(txn->lockState(), + ns.ns(), + parsedUpdate.isIsolated() ? MODE_X : MODE_IX); Client::Context ctx(txn, ns); // The common case: no implicit collection creation @@ -707,7 +709,9 @@ namespace mongo { break; } - Lock::CollectionLock colLock(txn->lockState(), ns.ns(), MODE_IX); + Lock::CollectionLock collLock(txn->lockState(), + ns.ns(), + parsedDelete.isIsolated() ? MODE_X : MODE_IX); Client::Context ctx(txn, ns); PlanExecutor* rawExec; diff --git a/src/mongo/db/ops/parsed_delete.cpp b/src/mongo/db/ops/parsed_delete.cpp index 1eb22ebab78..64a67c50f80 100644 --- a/src/mongo/db/ops/parsed_delete.cpp +++ b/src/mongo/db/ops/parsed_delete.cpp @@ -85,10 +85,14 @@ namespace mongo { bool ParsedDelete::canYield() const { return !_request->isGod() && - PlanExecutor::YIELD_AUTO == _request->getYieldPolicy() && ( - _canonicalQuery.get() ? - !QueryPlannerCommon::hasNode(_canonicalQuery->root(), MatchExpression::ATOMIC) : - !LiteParsedQuery::isQueryIsolated(_request->getQuery())); + PlanExecutor::YIELD_AUTO == _request->getYieldPolicy() && + !isIsolated(); + } + + bool ParsedDelete::isIsolated() const { + return _canonicalQuery.get() + ? QueryPlannerCommon::hasNode(_canonicalQuery->root(), MatchExpression::ATOMIC) + : LiteParsedQuery::isQueryIsolated(_request->getQuery()); } bool ParsedDelete::hasParsedQuery() const { diff --git a/src/mongo/db/ops/parsed_delete.h b/src/mongo/db/ops/parsed_delete.h index c117db28cb7..cb189bfccc8 100644 --- a/src/mongo/db/ops/parsed_delete.h +++ b/src/mongo/db/ops/parsed_delete.h @@ -84,6 +84,11 @@ namespace mongo { bool canYield() const; /** + * Is this update supposed to be isolated? + */ + bool isIsolated() const; + + /** * As an optimization, we don't create a canonical query for updates with simple _id * queries. Use this method to determine whether or not we actually parsed the query. */ diff --git a/src/mongo/db/ops/parsed_update.cpp b/src/mongo/db/ops/parsed_update.cpp index 8570ee212d8..d6a26fdaed2 100644 --- a/src/mongo/db/ops/parsed_update.cpp +++ b/src/mongo/db/ops/parsed_update.cpp @@ -107,10 +107,14 @@ namespace mongo { bool ParsedUpdate::canYield() const { return !_request->isGod() && - PlanExecutor::YIELD_AUTO == _request->getYieldPolicy() && ( - _canonicalQuery.get() ? - !QueryPlannerCommon::hasNode(_canonicalQuery->root(), MatchExpression::ATOMIC) : - !LiteParsedQuery::isQueryIsolated(_request->getQuery())); + PlanExecutor::YIELD_AUTO == _request->getYieldPolicy() && + !isIsolated(); + } + + bool ParsedUpdate::isIsolated() const { + return _canonicalQuery.get() + ? QueryPlannerCommon::hasNode(_canonicalQuery->root(), MatchExpression::ATOMIC) + : LiteParsedQuery::isQueryIsolated(_request->getQuery()); } bool ParsedUpdate::hasParsedQuery() const { diff --git a/src/mongo/db/ops/parsed_update.h b/src/mongo/db/ops/parsed_update.h index f93a264b3b8..5a7854f93fa 100644 --- a/src/mongo/db/ops/parsed_update.h +++ b/src/mongo/db/ops/parsed_update.h @@ -89,6 +89,11 @@ namespace mongo { bool canYield() const; /** + * Is this update supposed to be isolated? + */ + bool isIsolated() const; + + /** * As an optimization, we don't create a canonical query for updates with simple _id * queries. Use this method to determine whether or not we actually parsed the query. */ |