summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorMihai Andrei <mihai.andrei@mongodb.com>2023-05-13 02:35:14 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-05-13 03:47:43 +0000
commita1f0cfdcbcc632133a7e65665c84b9344f4d8153 (patch)
tree643542c2538a72286617fb8d563a7fc8c7491e2a /src/mongo
parent68145fa6580490c6d6d1e3829359f3260be8f9bc (diff)
downloadmongo-a1f0cfdcbcc632133a7e65665c84b9344f4d8153.tar.gz
SERVER-77099 Account for OpMsg::sequence in write_ops::verifySizeEstimate functions
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/commands/write_commands.cpp6
-rw-r--r--src/mongo/db/ops/write_ops.cpp27
-rw-r--r--src/mongo/db/ops/write_ops.h14
3 files changed, 38 insertions, 9 deletions
diff --git a/src/mongo/db/commands/write_commands.cpp b/src/mongo/db/commands/write_commands.cpp
index ceb797e339c..922bfe889f4 100644
--- a/src/mongo/db/commands/write_commands.cpp
+++ b/src/mongo/db/commands/write_commands.cpp
@@ -261,7 +261,7 @@ public:
// On debug builds, verify that the estimated size of the insert command is at least as
// large as the size of the actual, serialized insert command. This ensures that the
// logic which estimates the size of insert commands is correct.
- dassert(write_ops::verifySizeEstimate(request()));
+ dassert(write_ops::verifySizeEstimate(request(), &unparsedRequest()));
doTransactionValidationForWrites(opCtx, ns());
if (request().getEncryptionInformation().has_value()) {
@@ -438,7 +438,7 @@ public:
// On debug builds, verify that the estimated size of the update command is at least as
// large as the size of the actual, serialized update command. This ensures that the
// logic which estimates the size of update commands is correct.
- dassert(write_ops::verifySizeEstimate(request()));
+ dassert(write_ops::verifySizeEstimate(request(), &unparsedRequest()));
doTransactionValidationForWrites(opCtx, ns());
write_ops::UpdateCommandReply updateReply;
@@ -673,7 +673,7 @@ public:
// On debug builds, verify that the estimated size of the deletes are at least as large
// as the actual, serialized size. This ensures that the logic that estimates the size
// of deletes for batch writes is correct.
- dassert(write_ops::verifySizeEstimate(request()));
+ dassert(write_ops::verifySizeEstimate(request(), &unparsedRequest()));
doTransactionValidationForWrites(opCtx, ns());
write_ops::DeleteCommandReply deleteReply;
diff --git a/src/mongo/db/ops/write_ops.cpp b/src/mongo/db/ops/write_ops.cpp
index 7bac799c5cf..8e071f9665d 100644
--- a/src/mongo/db/ops/write_ops.cpp
+++ b/src/mongo/db/ops/write_ops.cpp
@@ -352,15 +352,23 @@ bool verifySizeEstimate(const write_ops::UpdateOpEntry& update) {
update.toBSON().objsize();
}
-bool verifySizeEstimate(const InsertCommandRequest& insertReq) {
+bool verifySizeEstimate(const InsertCommandRequest& insertReq,
+ const OpMsgRequest* unparsedRequest) {
int size = getInsertHeaderSizeEstimate(insertReq);
for (auto&& docToInsert : insertReq.getDocuments()) {
size += docToInsert.objsize() + kWriteCommandBSONArrayPerElementOverheadBytes;
}
+
+ // Return true if 'insertReq' originated from a document sequence and our size estimate exceeds
+ // the size limit.
+ if (unparsedRequest && !unparsedRequest->sequences.empty() && size > BSONObjMaxUserSize) {
+ return true;
+ }
return size >= insertReq.toBSON({} /* commandPassthroughFields */).objsize();
}
-bool verifySizeEstimate(const UpdateCommandRequest& updateReq) {
+bool verifySizeEstimate(const UpdateCommandRequest& updateReq,
+ const OpMsgRequest* unparsedRequest) {
int size = getUpdateHeaderSizeEstimate(updateReq);
for (auto&& update : updateReq.getUpdates()) {
@@ -376,10 +384,17 @@ bool verifySizeEstimate(const UpdateCommandRequest& updateReq) {
update.getAllowShardKeyUpdatesWithoutFullShardKeyInQuery().has_value()) +
kWriteCommandBSONArrayPerElementOverheadBytes;
}
+
+ // Return true if 'updateReq' originated from a document sequence and our size estimate exceeds
+ // the size limit.
+ if (unparsedRequest && !unparsedRequest->sequences.empty() && size > BSONObjMaxUserSize) {
+ return true;
+ }
return size >= updateReq.toBSON({} /* commandPassthroughFields */).objsize();
}
-bool verifySizeEstimate(const DeleteCommandRequest& deleteReq) {
+bool verifySizeEstimate(const DeleteCommandRequest& deleteReq,
+ const OpMsgRequest* unparsedRequest) {
int size = getDeleteHeaderSizeEstimate(deleteReq);
for (auto&& deleteOp : deleteReq.getDeletes()) {
@@ -389,6 +404,12 @@ bool verifySizeEstimate(const DeleteCommandRequest& deleteReq) {
deleteOp.getSampleId()) +
kWriteCommandBSONArrayPerElementOverheadBytes;
}
+
+ // Return true if 'deleteReq' originated from a document sequence and our size estimate exceeds
+ // the size limit.
+ if (unparsedRequest && !unparsedRequest->sequences.empty() && size > BSONObjMaxUserSize) {
+ return true;
+ }
return size >= deleteReq.toBSON({} /* commandPassthroughFields */).objsize();
}
diff --git a/src/mongo/db/ops/write_ops.h b/src/mongo/db/ops/write_ops.h
index 4f44b8e0c95..29c70a04574 100644
--- a/src/mongo/db/ops/write_ops.h
+++ b/src/mongo/db/ops/write_ops.h
@@ -124,12 +124,20 @@ int getDeleteSizeEstimate(const BSONObj& q,
/**
* Set of utilities which return true if the estimated write size is greater than or equal to the
* actual write size, false otherwise.
+ *
+ * If the caller specifies 'unparsedRequest', these utilities will also return true if the request
+ * used document sequences and the size estimate is greater than the maximum size of a BSONObj. This
+ * indicates that 'unparsedRequest' cannot be serialized to a BSONObj because it exceeds the maximum
+ * BSONObj size.
*/
bool verifySizeEstimate(const write_ops::UpdateOpEntry& update);
bool verifySizeEstimate(const write_ops::DeleteOpEntry& deleteOp);
-bool verifySizeEstimate(const InsertCommandRequest& insertReq);
-bool verifySizeEstimate(const UpdateCommandRequest& updateReq);
-bool verifySizeEstimate(const DeleteCommandRequest& deleteReq);
+bool verifySizeEstimate(const InsertCommandRequest& insertReq,
+ const OpMsgRequest* unparsedRequest = nullptr);
+bool verifySizeEstimate(const UpdateCommandRequest& updateReq,
+ const OpMsgRequest* unparsedRequest = nullptr);
+bool verifySizeEstimate(const DeleteCommandRequest& deleteReq,
+ const OpMsgRequest* unparsedRequest = nullptr);
/**
* Set of utilities which estimate the size of the headers (that is, all fields in a write command