summaryrefslogtreecommitdiff
path: root/src/mongo/db/repl
diff options
context:
space:
mode:
authorCheahuychou Mao <mao.cheahuychou@gmail.com>2021-10-19 14:52:57 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-10-29 00:50:10 +0000
commitea197fd5193fe034174584e60290dd90fe01d2b1 (patch)
treeac2e923c5dc87fd4115293b60f6ed926433b078a /src/mongo/db/repl
parent5e8446f92d4826cfe2e8b9082efd0fbd540a9718 (diff)
downloadmongo-ea197fd5193fe034174584e60290dd90fe01d2b1.tar.gz
SERVER-58756 Store stmtIds for the operations in retryable internal transactions in applyOps oplog entries
Diffstat (limited to 'src/mongo/db/repl')
-rw-r--r--src/mongo/db/repl/oplog_entry.cpp4
-rw-r--r--src/mongo/db/repl/oplog_entry.h45
-rw-r--r--src/mongo/db/repl/oplog_entry.idl18
3 files changed, 47 insertions, 20 deletions
diff --git a/src/mongo/db/repl/oplog_entry.cpp b/src/mongo/db/repl/oplog_entry.cpp
index 3f3c88cd359..ee80f7afaf3 100644
--- a/src/mongo/db/repl/oplog_entry.cpp
+++ b/src/mongo/db/repl/oplog_entry.cpp
@@ -284,8 +284,10 @@ OpTime MutableOplogEntry::getOpTime() const {
}
size_t DurableOplogEntry::getDurableReplOperationSize(const DurableReplOperation& op) {
+ const auto stmtIds = variant_util::toVector<StmtId>(op.getStatementIds());
return sizeof(op) + op.getNss().size() + op.getObject().objsize() +
- (op.getObject2() ? op.getObject2()->objsize() : 0);
+ (op.getObject2() ? op.getObject2()->objsize() : 0) +
+ (sizeof(std::vector<StmtId>) + (sizeof(StmtId) * stmtIds.size()));
}
StatusWith<DurableOplogEntry> DurableOplogEntry::parse(const BSONObj& object) {
diff --git a/src/mongo/db/repl/oplog_entry.h b/src/mongo/db/repl/oplog_entry.h
index c13fd9265df..f8d63ca61cc 100644
--- a/src/mongo/db/repl/oplog_entry.h
+++ b/src/mongo/db/repl/oplog_entry.h
@@ -41,6 +41,18 @@
namespace mongo {
namespace repl {
+namespace variant_util {
+template <typename T>
+std::vector<T> toVector(boost::optional<stdx::variant<T, std::vector<T>>> optVals) {
+ if (!optVals) {
+ return {};
+ }
+ return stdx::visit(visit_helper::Overloaded{[](T val) { return std::vector<T>{val}; },
+ [](const std::vector<T>& vals) { return vals; }},
+ *optVals);
+}
+} // namespace variant_util
+
/**
* The first oplog entry is a no-op with this message in its "msg" field.
*/
@@ -76,6 +88,25 @@ public:
_fullPreImage = std::move(value);
}
+ /**
+ * Sets the statement ids for this ReplOperation to 'stmtIds' if it does not contain any
+ * kUninitializedStmtId (i.e. placeholder statement id).
+ */
+ void setInitializedStatementIds(const std::vector<StmtId>& stmtIds) & {
+ if (std::count(stmtIds.begin(), stmtIds.end(), kUninitializedStmtId) > 0) {
+ return;
+ }
+ if (stmtIds.size() > 1) {
+ DurableReplOperation::setStatementIds({{stmtIds}});
+ } else if (stmtIds.size() == 1) {
+ DurableReplOperation::setStatementIds({{stmtIds.front()}});
+ }
+ }
+
+ std::vector<StmtId> getStatementIds() const {
+ return variant_util::toVector<StmtId>(DurableReplOperation::getStatementIds());
+ }
+
private:
BSONObj _preImageDocumentKey;
BSONObj _fullPreImage;
@@ -123,22 +154,16 @@ public:
void setStatementIds(const std::vector<StmtId>& stmtIds) & {
if (stmtIds.empty()) {
- OplogEntryBase::setStatementIds(boost::none);
+ getDurableReplOperation().setStatementIds(boost::none);
} else if (stmtIds.size() == 1) {
- OplogEntryBase::setStatementIds({{stmtIds.front()}});
+ getDurableReplOperation().setStatementIds({{stmtIds.front()}});
} else {
- OplogEntryBase::setStatementIds({{stmtIds}});
+ getDurableReplOperation().setStatementIds({{stmtIds}});
}
}
std::vector<StmtId> getStatementIds() const {
- if (!OplogEntryBase::getStatementIds()) {
- return {};
- }
- return stdx::visit(
- visit_helper::Overloaded{[](StmtId stmtId) { return std::vector<StmtId>{stmtId}; },
- [](const std::vector<StmtId>& stmtIds) { return stmtIds; }},
- *OplogEntryBase::getStatementIds());
+ return variant_util::toVector<StmtId>(OplogEntryBase::getStatementIds());
}
void setTxnNumber(boost::optional<std::int64_t> value) & {
diff --git a/src/mongo/db/repl/oplog_entry.idl b/src/mongo/db/repl/oplog_entry.idl
index 6b014e66e3e..06c9ee1fcab 100644
--- a/src/mongo/db/repl/oplog_entry.idl
+++ b/src/mongo/db/repl/oplog_entry.idl
@@ -59,8 +59,8 @@ enums:
structs:
DurableReplOperation:
- description: "A document that represents an operation in a transaction. Should never be
- used directly in server code. Instead, create an instance of ReplOperation."
+ description: "A document that represents an operation. Should never be used directly in
+ server code. Instead, create an instance of ReplOperation."
fields:
op:
cpp_name: opType
@@ -104,6 +104,13 @@ structs:
optional: true
description: "The destined recipient for this op under the new shard key pattern.
Only included when a resharding operation is in progress."
+ stmtId:
+ cpp_name: statementIds
+ type:
+ variant: [StmtId, array<StmtId>]
+ optional: true
+ description: "Identifier of the transaction statement(s) which generated this oplog
+ entry"
OplogEntryBase:
description: A document in which the server stores an oplog entry.
@@ -142,13 +149,6 @@ structs:
optional: true
description: "Used by tests in replication and also by production resharding code to
store timestamps."
- stmtId:
- cpp_name: statementIds
- type:
- variant: [StmtId, array<StmtId>]
- optional: true
- description: "Identifier of the transaction statement(s) which generated this oplog
- entry"
prevOpTime:
cpp_name: prevWriteOpTimeInTransaction
type: optime