diff options
author | Rishab Joshi <rishab.joshi@mongodb.com> | 2022-06-23 08:44:08 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-06-23 09:13:49 +0000 |
commit | c41d2317c3c560114a090338658d21cba7b86171 (patch) | |
tree | b13f5628377199033a83af68b32a63201cd1911e | |
parent | 3d1c61099274ec772302cf16e486403cfc427e9b (diff) | |
download | mongo-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.cpp | 28 |
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; |