summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugh Tong <hugh.tong@mongodb.com>2022-09-01 21:20:37 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-09-01 22:33:32 +0000
commit07a8f061b8c63c799c1d6ecbc13656eaae0d1922 (patch)
tree3967a8dd36883a7ab41ee2c6398fa9ce92ada03f
parentc00d004b124056e3cae35410dfe24c726adbac08 (diff)
downloadmongo-07a8f061b8c63c799c1d6ecbc13656eaae0d1922.tar.gz
SERVER-69233 Replace transaction top level tenantId with operation doc tenantId
-rw-r--r--src/mongo/db/op_observer/op_observer_impl.cpp11
-rw-r--r--src/mongo/db/op_observer/op_observer_impl_test.cpp43
2 files changed, 43 insertions, 11 deletions
diff --git a/src/mongo/db/op_observer/op_observer_impl.cpp b/src/mongo/db/op_observer/op_observer_impl.cpp
index dfbd6d77361..00f0ddc253d 100644
--- a/src/mongo/db/op_observer/op_observer_impl.cpp
+++ b/src/mongo/db/op_observer/op_observer_impl.cpp
@@ -1839,7 +1839,6 @@ OpTimeBundle logApplyOps(OperationContext* opCtx,
invariant(bool(txnRetryCounter) == bool(TransactionParticipant::get(opCtx)));
oplogEntry->setOpType(repl::OpTypeEnum::kCommand);
- oplogEntry->setTid(TenantId::kSystemTenantId);
oplogEntry->setNss({"admin", "$cmd"});
// Batched writes (that is, WUOWs with 'groupOplogEntries') are not associated with a txnNumber,
// so do not emit an lsid either.
@@ -2066,6 +2065,13 @@ int logOplogEntries(
}
oplogEntry.setWallClockTime(wallClockTime);
oplogEntry.setObject(applyOpsBuilder.done());
+
+ // TODO SERVER-69286: replace this temporary fix to set the top-level tenantId to the
+ // tenantId on the first op in the list
+ auto& ops = applyOpsEntry.operations;
+ if (!ops.empty() && !ops[0][repl::OplogEntry::kTidFieldName].eoo())
+ oplogEntry.setTid(TenantId::parseFromBSON(ops[0][repl::OplogEntry::kTidFieldName]));
+
auto txnState = isPartialTxn
? DurableTxnStateEnum::kInProgress
: (implicitPrepare ? DurableTxnStateEnum::kPrepared : DurableTxnStateEnum::kCommitted);
@@ -2378,6 +2384,9 @@ void OpObserverImpl::onTransactionPrepare(
oplogEntry.setPrevWriteOpTimeInTransaction(repl::OpTime());
oplogEntry.setObject(applyOpsBuilder.done());
oplogEntry.setWallClockTime(wallClockTime);
+
+ // TODO SERVER-69286: set the top-level tenantId here
+
logApplyOps(opCtx,
&oplogEntry,
DurableTxnStateEnum::kPrepared,
diff --git a/src/mongo/db/op_observer/op_observer_impl_test.cpp b/src/mongo/db/op_observer/op_observer_impl_test.cpp
index c78fad85ddc..34b81f67dd0 100644
--- a/src/mongo/db/op_observer/op_observer_impl_test.cpp
+++ b/src/mongo/db/op_observer/op_observer_impl_test.cpp
@@ -1734,12 +1734,16 @@ TEST_F(OpObserverTransactionTest, TransactionalInsertTestIncludesTenantId) {
WriteUnitOfWork wuow(opCtx());
opObserver().onInserts(opCtx(), *autoColl1, inserts1.begin(), inserts1.end(), false);
opObserver().onInserts(opCtx(), *autoColl2, inserts2.begin(), inserts2.end(), false);
+
auto txnOps = txnParticipant.retrieveCompletedTransactionOperations(opCtx());
opObserver().onUnpreparedTransactionCommit(opCtx(), &txnOps, 0);
+
auto oplogEntryObj = getSingleOplogEntry(opCtx());
checkCommonFields(oplogEntryObj);
OplogEntry oplogEntry = assertGet(OplogEntry::parse(oplogEntryObj));
auto o = oplogEntry.getObject();
+
+ // TODO SERVER-69288: disallow more than one tenant on a single transaction
auto oExpected =
BSON("applyOps" << BSON_ARRAY(BSON("op"
<< "i"
@@ -1770,6 +1774,9 @@ TEST_F(OpObserverTransactionTest, TransactionalInsertTestIncludesTenantId) {
<< "w")
<< "o2" << BSON("_id" << 3))));
ASSERT_BSONOBJ_EQ(oExpected, o);
+
+ // This test assumes that the top level tenantId matches the tenantId in the first entry
+ ASSERT_EQ(oplogEntry.getTid(), nss1.tenantId());
ASSERT(!oplogEntry.shouldPrepare());
ASSERT_FALSE(oplogEntryObj.hasField("prepare"));
}
@@ -1854,11 +1861,16 @@ TEST_F(OpObserverTransactionTest, TransactionalUpdateTestIncludesTenantId) {
AutoGetCollection autoColl2(opCtx(), nss2, MODE_IX);
opObserver().onUpdate(opCtx(), update1);
opObserver().onUpdate(opCtx(), update2);
+
auto txnOps = txnParticipant.retrieveCompletedTransactionOperations(opCtx());
opObserver().onUnpreparedTransactionCommit(opCtx(), &txnOps, 0);
- auto oplogEntry = getSingleOplogEntry(opCtx());
- checkCommonFields(oplogEntry);
- auto o = oplogEntry.getObjectField("o");
+
+ auto oplogEntryObj = getSingleOplogEntry(opCtx());
+ checkCommonFields(oplogEntryObj);
+ OplogEntry oplogEntry = assertGet(OplogEntry::parse(oplogEntryObj));
+ auto o = oplogEntry.getObject();
+
+ // TODO SERVER-69288: disallow more than one tenant on a single transaction
auto oExpected =
BSON("applyOps" << BSON_ARRAY(BSON("op"
<< "u"
@@ -1875,8 +1887,11 @@ TEST_F(OpObserverTransactionTest, TransactionalUpdateTestIncludesTenantId) {
<< "y"))
<< "o2" << BSON("_id" << 1))));
ASSERT_BSONOBJ_EQ(oExpected, o);
- ASSERT_FALSE(oplogEntry.hasField("prepare"));
- ASSERT_FALSE(oplogEntry.getBoolField("prepare"));
+
+ // This test assumes that the top level tenantId matches the tenantId in the first entry
+ ASSERT_EQ(oplogEntry.getTid(), nss1.tenantId());
+ ASSERT_FALSE(oplogEntryObj.hasField("prepare"));
+ ASSERT_FALSE(oplogEntryObj.getBoolField("prepare"));
}
TEST_F(OpObserverTransactionTest, TransactionalDeleteTest) {
@@ -1938,11 +1953,16 @@ TEST_F(OpObserverTransactionTest, TransactionalDeleteTestIncludesTenantId) {
BSON("_id" << 1 << "data"
<< "y"));
opObserver().onDelete(opCtx(), nss2, uuid2, 0, {});
+
auto txnOps = txnParticipant.retrieveCompletedTransactionOperations(opCtx());
opObserver().onUnpreparedTransactionCommit(opCtx(), &txnOps, 0);
- auto oplogEntry = getSingleOplogEntry(opCtx());
- checkCommonFields(oplogEntry);
- auto o = oplogEntry.getObjectField("o");
+
+ auto oplogEntryObj = getSingleOplogEntry(opCtx());
+ checkCommonFields(oplogEntryObj);
+ OplogEntry oplogEntry = assertGet(OplogEntry::parse(oplogEntryObj));
+ auto o = oplogEntry.getObject();
+
+ // TODO SERVER-69288: disallow more than one tenant on a single transaction
auto oExpected = BSON("applyOps" << BSON_ARRAY(
BSON("op"
<< "d"
@@ -1953,8 +1973,11 @@ TEST_F(OpObserverTransactionTest, TransactionalDeleteTestIncludesTenantId) {
<< "tid" << nss2.tenantId().value() << "ns" << nss2.toString()
<< "ui" << uuid2 << "o" << BSON("_id" << 1))));
ASSERT_BSONOBJ_EQ(oExpected, o);
- ASSERT_FALSE(oplogEntry.hasField("prepare"));
- ASSERT_FALSE(oplogEntry.getBoolField("prepare"));
+
+ // This test assumes that the top level tenantId matches the tenantId in the first entry
+ ASSERT_EQ(oplogEntry.getTid(), nss1.tenantId());
+ ASSERT_FALSE(oplogEntryObj.hasField("prepare"));
+ ASSERT_FALSE(oplogEntryObj.getBoolField("prepare"));
}
TEST_F(OpObserverTransactionTest,