summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRishab Joshi <rishab.joshi@mongodb.com>2022-06-23 08:44:08 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-06-23 09:13:49 +0000
commitc41d2317c3c560114a090338658d21cba7b86171 (patch)
treeb13f5628377199033a83af68b32a63201cd1911e
parent3d1c61099274ec772302cf16e486403cfc427e9b (diff)
downloadmongo-c41d2317c3c560114a090338658d21cba7b86171.tar.gz
SERVER-66924 Avoid inserting to the change collection that is already dropped.
-rw-r--r--src/mongo/db/change_stream_change_collection_manager.cpp28
1 files changed, 27 insertions, 1 deletions
diff --git a/src/mongo/db/change_stream_change_collection_manager.cpp b/src/mongo/db/change_stream_change_collection_manager.cpp
index e2872e3d815..d76d197c505 100644
--- a/src/mongo/db/change_stream_change_collection_manager.cpp
+++ b/src/mongo/db/change_stream_change_collection_manager.cpp
@@ -71,7 +71,9 @@ public:
* collection when the 'write()' method is called.
*/
void add(const TenantId& tenantId, InsertStatement insertStatement) {
- _tenantStatementsMap[tenantId].push_back(std::move(insertStatement));
+ if (_shouldAddEntry(insertStatement)) {
+ _tenantStatementsMap[tenantId].push_back(std::move(insertStatement));
+ }
}
/**
@@ -112,6 +114,30 @@ public:
}
private:
+ bool _shouldAddEntry(const InsertStatement& insertStatement) {
+ auto& oplogDoc = insertStatement.doc;
+
+ // TODO SERVER-65950 retreive tenant from the oplog.
+ // TODO SERVER-67170 avoid inspecting the oplog BSON object.
+
+ if (auto nssFieldElem = oplogDoc[repl::OplogEntry::kNssFieldName];
+ nssFieldElem && nssFieldElem.String() == "config.$cmd"_sd) {
+ if (auto objectFieldElem = oplogDoc[repl::OplogEntry::kObjectFieldName]) {
+ // The oplog entry might be a drop command on the change collection. Check if the
+ // drop request is for the already deleted change collection, as such do not attempt
+ // to write to the change collection if that is the case. This scenario is possible
+ // because 'WriteUnitOfWork' will stage the changes and while committing the staged
+ // 'CollectionImpl::insertDocuments' change the collection object might have already
+ // been deleted.
+ if (auto dropFieldElem = objectFieldElem["drop"_sd]) {
+ return dropFieldElem.String() != NamespaceString::kChangeCollectionName;
+ }
+ }
+ }
+
+ return true;
+ }
+
// Maps inserts statements for each tenant.
stdx::unordered_map<TenantId, std::vector<InsertStatement>, TenantId::Hasher>
_tenantStatementsMap;