summaryrefslogtreecommitdiff
path: root/src/mongo/db/repl/drop_pending_collection_reaper.cpp
diff options
context:
space:
mode:
authorDianna Hohensee <dianna.hohensee@10gen.com>2018-05-04 08:45:36 -0400
committerDianna Hohensee <dianna.hohensee@10gen.com>2018-05-07 12:48:31 -0400
commit8a41a08818c38c4f79a1c4ba2dfe453e8e547dd0 (patch)
treee4bdc4c1b23807d8d78d96d8924d3ac59aac22f6 /src/mongo/db/repl/drop_pending_collection_reaper.cpp
parent36a7e1c06554522aa96e41378688568fb16754c2 (diff)
downloadmongo-8a41a08818c38c4f79a1c4ba2dfe453e8e547dd0.tar.gz
SERVER-34829 Drop pending reaper must not delete the _dropPendingNamespaces entry until after the drop occurs
Diffstat (limited to 'src/mongo/db/repl/drop_pending_collection_reaper.cpp')
-rw-r--r--src/mongo/db/repl/drop_pending_collection_reaper.cpp47
1 files changed, 32 insertions, 15 deletions
diff --git a/src/mongo/db/repl/drop_pending_collection_reaper.cpp b/src/mongo/db/repl/drop_pending_collection_reaper.cpp
index 7cd7d47a33d..709f30d64c8 100644
--- a/src/mongo/db/repl/drop_pending_collection_reaper.cpp
+++ b/src/mongo/db/repl/drop_pending_collection_reaper.cpp
@@ -135,10 +135,10 @@ void DropPendingCollectionReaper::dropCollectionsOlderThan(OperationContext* opC
DropPendingNamespaces toDrop;
{
stdx::lock_guard<stdx::mutex> lock(_mutex);
- auto it = _dropPendingNamespaces.cbegin();
- while (it != _dropPendingNamespaces.cend() && it->first <= opTime) {
+ for (auto it = _dropPendingNamespaces.cbegin();
+ it != _dropPendingNamespaces.cend() && it->first <= opTime;
+ ++it) {
toDrop.insert(*it);
- it = _dropPendingNamespaces.erase(it);
}
}
@@ -146,19 +146,36 @@ void DropPendingCollectionReaper::dropCollectionsOlderThan(OperationContext* opC
return;
}
- // Every node cleans up its own drop-pending collections. We should never replicate these drops
- // because these are internal operations.
- UnreplicatedWritesBlock uwb(opCtx);
+ {
+ // Every node cleans up its own drop-pending collections. We should never replicate these
+ // drops because these are internal operations.
+ UnreplicatedWritesBlock uwb(opCtx);
+
+ for (const auto& opTimeAndNamespace : toDrop) {
+ const auto& dropOpTime = opTimeAndNamespace.first;
+ const auto& nss = opTimeAndNamespace.second;
+ log() << "Completing collection drop for " << nss << " with drop optime " << dropOpTime
+ << " (notification optime: " << opTime << ")";
+ auto status = _storageInterface->dropCollection(opCtx, nss);
+ if (!status.isOK()) {
+ warning() << "Failed to remove drop-pending collection " << nss
+ << " with drop optime " << dropOpTime
+ << " (notification optime: " << opTime << "): " << status;
+ }
+ }
+ }
- for (const auto& opTimeAndNamespace : toDrop) {
- const auto& dropOpTime = opTimeAndNamespace.first;
- const auto& nss = opTimeAndNamespace.second;
- log() << "Completing collection drop for " << nss << " with drop optime " << dropOpTime
- << " (notification optime: " << opTime << ")";
- auto status = _storageInterface->dropCollection(opCtx, nss);
- if (!status.isOK()) {
- warning() << "Failed to remove drop-pending collection " << nss << " with drop optime "
- << dropOpTime << " (notification optime: " << opTime << "): " << status;
+ {
+ // Entries must be removed AFTER drops are completed, so that getEarliestDropOpTime()
+ // returns appropriate results.
+ stdx::lock_guard<stdx::mutex> lock(_mutex);
+ auto it = _dropPendingNamespaces.cbegin();
+ while (it != _dropPendingNamespaces.cend() && it->first <= opTime) {
+ if (toDrop.find(it->first) != toDrop.cend()) {
+ it = _dropPendingNamespaces.erase(it);
+ } else {
+ ++it;
+ }
}
}
}