1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
// Tests multi-document transactions metrics are still correct after 'killSessions'.
// @tags: [uses_transactions]
(function() {
"use strict";
// Verifies that the given value of the transaction metrics is incremented in the way we expect.
function verifyMetricsChange(initialStats, newStats, valueName, expectedIncrement) {
assert.eq(initialStats[valueName] + expectedIncrement,
newStats[valueName],
"expected " + valueName + " to increase by " + expectedIncrement +
".\nInitial stats: " + tojson(initialStats) + "; New stats: " + tojson(newStats));
}
// Set up the replica set and enable majority read concern for atClusterTime snapshot reads.
const rst = new ReplSetTest({nodes: 1, nodeOptions: {enableMajorityReadConcern: "true"}});
rst.startSet();
rst.initiate();
const dbName = "test";
const collName = "server_transactions_metrics_kill_sessions";
const testDB = rst.getPrimary().getDB(dbName);
assert.commandWorked(testDB.runCommand({create: collName, writeConcern: {w: "majority"}}));
const sessionOptions = {
causalConsistency: false
};
let session = testDB.getMongo().startSession(sessionOptions);
let sessionDb = session.getDatabase(dbName);
let initialMetrics = assert.commandWorked(testDB.adminCommand({serverStatus: 1})).transactions;
jsTest.log("Start a transaction.");
session.startTransaction();
assert.commandWorked(sessionDb.runCommand({find: collName}));
let newMetrics = assert.commandWorked(testDB.adminCommand({serverStatus: 1})).transactions;
verifyMetricsChange(initialMetrics, newMetrics, "currentActive", 0);
verifyMetricsChange(initialMetrics, newMetrics, "currentInactive", 1);
verifyMetricsChange(initialMetrics, newMetrics, "currentOpen", 1);
jsTest.log("Kill session " + tojson(session.getSessionId()) + ".");
assert.commandWorked(testDB.runCommand({killSessions: [session.getSessionId()]}));
newMetrics = assert.commandWorked(testDB.adminCommand({serverStatus: 1})).transactions;
verifyMetricsChange(initialMetrics, newMetrics, "currentActive", 0);
verifyMetricsChange(initialMetrics, newMetrics, "currentInactive", 0);
verifyMetricsChange(initialMetrics, newMetrics, "currentOpen", 0);
verifyMetricsChange(initialMetrics, newMetrics, "totalCommitted", 0);
verifyMetricsChange(initialMetrics, newMetrics, "totalAborted", 1);
verifyMetricsChange(initialMetrics, newMetrics, "totalStarted", 1);
session.endSession();
session = testDB.getMongo().startSession(sessionOptions);
sessionDb = session.getDatabase(dbName);
jsTest.log("Start a snapshot transaction at a time that is too old.");
session.startTransaction({readConcern: {level: "snapshot", atClusterTime: Timestamp(1, 1)}});
// Operation runs unstashTransactionResources() and throws prior to onUnstash(). As a result,
// the transaction will be implicitly aborted.
assert.commandFailedWithCode(sessionDb.runCommand({find: collName}), ErrorCodes.SnapshotTooOld);
newMetrics = assert.commandWorked(testDB.adminCommand({serverStatus: 1})).transactions;
verifyMetricsChange(initialMetrics, newMetrics, "currentActive", 0);
verifyMetricsChange(initialMetrics, newMetrics, "currentInactive", 0);
verifyMetricsChange(initialMetrics, newMetrics, "currentOpen", 0);
// Kill the session that threw exception before.
jsTest.log("Kill session " + tojson(session.getSessionId()) + ".");
assert.commandWorked(testDB.runCommand({killSessions: [session.getSessionId()]}));
newMetrics = assert.commandWorked(testDB.adminCommand({serverStatus: 1})).transactions;
verifyMetricsChange(initialMetrics, newMetrics, "currentActive", 0);
verifyMetricsChange(initialMetrics, newMetrics, "currentInactive", 0);
verifyMetricsChange(initialMetrics, newMetrics, "currentOpen", 0);
verifyMetricsChange(initialMetrics, newMetrics, "totalCommitted", 0);
verifyMetricsChange(initialMetrics, newMetrics, "totalAborted", 2);
verifyMetricsChange(initialMetrics, newMetrics, "totalStarted", 2);
session.endSession();
rst.stopSet();
}());
|