summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Gottlieb <daniel.gottlieb@mongodb.com>2021-08-09 23:17:07 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-08-10 19:05:11 +0000
commitaeb2417ce739b5f74504383d2b4ea3b50005c328 (patch)
treed2540b18af60f6f2e9f41aba9712f89e245dd40b /src
parentdcb0c2f2001fc17be51c38db1319197973758a8c (diff)
downloadmongo-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.cpp47
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();
}