diff options
author | Daniel Gottlieb <daniel.gottlieb@mongodb.com> | 2021-08-09 23:17:07 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-08-10 19:05:11 +0000 |
commit | aeb2417ce739b5f74504383d2b4ea3b50005c328 (patch) | |
tree | d2540b18af60f6f2e9f41aba9712f89e245dd40b /src | |
parent | dcb0c2f2001fc17be51c38db1319197973758a8c (diff) | |
download | mongo-aeb2417ce739b5f74504383d2b4ea3b50005c328.tar.gz |
SERVER-59197: Delete findAndModify image entries when their corresponding session is deleted.
(cherry picked from commit 7bd6ae3c4b69df592e48779d3c1ed26c61780522)
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/session_catalog_mongod.cpp | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/src/mongo/db/session_catalog_mongod.cpp b/src/mongo/db/session_catalog_mongod.cpp index cec7f708ed7..7fa62f5363a 100644 --- a/src/mongo/db/session_catalog_mongod.cpp +++ b/src/mongo/db/session_catalog_mongod.cpp @@ -141,14 +141,20 @@ int removeSessionsTransactionRecords(OperationContext* opCtx, if (expiredSessionIds.empty()) return 0; - // Remove the session ids from the on-disk catalog - write_ops::DeleteCommandRequest deleteOp(NamespaceString::kSessionTransactionsTableNamespace); - deleteOp.setWriteCommandRequestBase([] { + // Remove findAndModify images that map to deleted sessions. We first delete any images + // belonging to sessions about to be reaped, followed by the sessions. This way if there's a + // failure, we'll only be left with sessions that have a dangling reference to an image. Session + // reaping will rediscover the sessions to delete and try again. + // + // We opt for this rather than performing the two sets of deletes in a single transaction simply + // to reduce code complexity. + write_ops::DeleteCommandRequest imageDeleteOp(NamespaceString::kConfigImagesNamespace); + imageDeleteOp.setWriteCommandRequestBase([] { write_ops::WriteCommandRequestBase base; base.setOrdered(false); return base; }()); - deleteOp.setDeletes([&] { + imageDeleteOp.setDeletes([&] { std::vector<write_ops::DeleteOpEntry> entries; for (const auto& lsid : expiredSessionIds) { entries.emplace_back(BSON(LogicalSessionRecord::kIdFieldName << lsid.toBSON()), @@ -157,20 +163,45 @@ int removeSessionsTransactionRecords(OperationContext* opCtx, return entries; }()); + BatchedCommandResponse response; + std::string errmsg; BSONObj result; DBDirectClient client(opCtx); + client.runCommand( + NamespaceString::kConfigImagesNamespace.db().toString(), imageDeleteOp.toBSON({}), result); + + uassert(ErrorCodes::FailedToParse, + str::stream() << "Failed to parse response " << result, + response.parseBSON(result, &errmsg)); + uassertStatusOK(response.getTopLevelStatus()); + + // Remove the session ids from the on-disk catalog + write_ops::DeleteCommandRequest sessionDeleteOp( + NamespaceString::kSessionTransactionsTableNamespace); + sessionDeleteOp.setWriteCommandRequestBase([] { + write_ops::WriteCommandRequestBase base; + base.setOrdered(false); + return base; + }()); + sessionDeleteOp.setDeletes([&] { + std::vector<write_ops::DeleteOpEntry> entries; + for (const auto& lsid : expiredSessionIds) { + entries.emplace_back(BSON(LogicalSessionRecord::kIdFieldName << lsid.toBSON()), + false /* multi = false */); + } + return entries; + }()); + + client.runCommand(NamespaceString::kSessionTransactionsTableNamespace.db().toString(), - deleteOp.toBSON({}), + sessionDeleteOp.toBSON({}), result); - BatchedCommandResponse response; - std::string errmsg; uassert(ErrorCodes::FailedToParse, str::stream() << "Failed to parse response " << result, response.parseBSON(result, &errmsg)); uassertStatusOK(response.getTopLevelStatus()); - return response.getN(); } |