diff options
author | Mihai Andrei <mihai.andrei@mongodb.com> | 2023-05-13 02:35:14 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-05-13 03:47:43 +0000 |
commit | a1f0cfdcbcc632133a7e65665c84b9344f4d8153 (patch) | |
tree | 643542c2538a72286617fb8d563a7fc8c7491e2a /src/mongo | |
parent | 68145fa6580490c6d6d1e3829359f3260be8f9bc (diff) | |
download | mongo-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.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/ops/write_ops.cpp | 27 | ||||
-rw-r--r-- | src/mongo/db/ops/write_ops.h | 14 |
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 |