summaryrefslogtreecommitdiff
path: root/src/mongo/db/session.cpp
diff options
context:
space:
mode:
authorMatthew Russotto <matthew.russotto@10gen.com>2018-04-13 16:09:46 -0400
committerMatthew Russotto <matthew.russotto@10gen.com>2018-04-13 16:09:46 -0400
commit7c65bad3c3dd5e9fe47cdb835d5374113596df3e (patch)
tree6cf3f379a4d921cafc834933079ca4992ce23636 /src/mongo/db/session.cpp
parent2416088059f8b1fe0a14e1681c66a11e09f3fc3f (diff)
downloadmongo-7c65bad3c3dd5e9fe47cdb835d5374113596df3e.tar.gz
SERVER-33951 Abort transactions when the pending writes pass 16MB worth of write data
Diffstat (limited to 'src/mongo/db/session.cpp')
-rw-r--r--src/mongo/db/session.cpp13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/mongo/db/session.cpp b/src/mongo/db/session.cpp
index 6972f5ceb3f..6fa3bfaf8ea 100644
--- a/src/mongo/db/session.cpp
+++ b/src/mongo/db/session.cpp
@@ -786,6 +786,7 @@ void Session::_abortTransaction(WithLock wl) {
return;
}
_txnResourceStash = boost::none;
+ _transactionOperationBytes = 0;
_transactionOperations.clear();
_txnState = MultiDocumentTransactionState::kAborted;
}
@@ -825,6 +826,17 @@ void Session::addTransactionOperation(OperationContext* opCtx,
invariant(!_autocommit && _activeTxnNumber != kUninitializedTxnNumber);
invariant(opCtx->lockState()->inAWriteUnitOfWork());
_transactionOperations.push_back(operation);
+ _transactionOperationBytes += repl::OplogEntry::getReplOperationSize(operation);
+ // _transactionOperationBytes is based on the in-memory size of the operation. With overhead,
+ // we expect the BSON size of the operation to be larger, so it's possible to make a transaction
+ // just a bit too large and have it fail only in the commit. It's still useful to fail early
+ // when possible (e.g. to avoid exhausting server memory).
+ uassert(ErrorCodes::TransactionTooLarge,
+ str::stream() << "Total size of all transaction operations must be less than "
+ << BSONObjMaxInternalSize
+ << ". Actual size is "
+ << _transactionOperationBytes,
+ _transactionOperationBytes <= BSONObjMaxInternalSize);
}
std::vector<repl::ReplOperation> Session::endTransactionAndRetrieveOperations(
@@ -836,6 +848,7 @@ std::vector<repl::ReplOperation> Session::endTransactionAndRetrieveOperations(
_checkIsActiveTransaction(lk, *opCtx->getTxnNumber(), true);
invariant(!_autocommit);
+ _transactionOperationBytes = 0;
return std::move(_transactionOperations);
}