mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-30 00:56:44 +01:00
365 lines
18 KiB
JavaScript
365 lines
18 KiB
JavaScript
// Tests readConcern level metrics in the serverStatus output.
|
|
// @tags: [uses_transactions, requires_majority_read_concern]
|
|
(function() {
|
|
"use strict";
|
|
|
|
// Verifies that the server status response has the fields that we expect.
|
|
function verifyServerStatusFields(serverStatusResponse) {
|
|
assert(serverStatusResponse.hasOwnProperty("opReadConcernCounters"),
|
|
"Expected the serverStatus response to have a 'opReadConcernCounters' field\n" +
|
|
tojson(serverStatusResponse));
|
|
assert(
|
|
serverStatusResponse.opReadConcernCounters.hasOwnProperty("available"),
|
|
"The 'opReadConcernCounters' field in serverStatus did not have the 'available' field\n" +
|
|
tojson(serverStatusResponse.opReadConcernCounters));
|
|
assert(
|
|
serverStatusResponse.opReadConcernCounters.hasOwnProperty("linearizable"),
|
|
"The 'opReadConcernCounters' field in serverStatus did not have the 'linearizable' field\n" +
|
|
tojson(serverStatusResponse.opReadConcernCounters));
|
|
assert(serverStatusResponse.opReadConcernCounters.hasOwnProperty("local"),
|
|
"The 'opReadConcernCounters' field in serverStatus did not have the 'local' field\n" +
|
|
tojson(serverStatusResponse.opReadConcernCounters));
|
|
assert(serverStatusResponse.opReadConcernCounters.hasOwnProperty("majority"),
|
|
"The 'opReadConcernCounters' field in serverStatus did not have the 'majority' field\n" +
|
|
tojson(serverStatusResponse.opReadConcernCounters));
|
|
assert(serverStatusResponse.opReadConcernCounters.hasOwnProperty("snapshot"),
|
|
"The 'opReadConcernCounters' field in serverStatus did not have the 'snapshot' field\n" +
|
|
tojson(serverStatusResponse.opReadConcernCounters));
|
|
assert(serverStatusResponse.opReadConcernCounters.hasOwnProperty("none"),
|
|
"The 'opReadConcernCounters' field in serverStatus did not have the 'none' field\n" +
|
|
tojson(serverStatusResponse.opReadConcernCounters));
|
|
}
|
|
|
|
// Verifies that the given value of the server status response is incremented in the way
|
|
// we expect.
|
|
function verifyServerStatusChange(initialStats, newStats, valueName, expectedIncrement) {
|
|
assert.eq(initialStats[valueName] + expectedIncrement,
|
|
newStats[valueName],
|
|
"expected " + valueName + " to increase by " + expectedIncrement +
|
|
", initialStats: " + tojson(initialStats) + ", newStats: " + tojson(newStats));
|
|
}
|
|
|
|
const rst = new ReplSetTest({nodes: 1});
|
|
rst.startSet();
|
|
rst.initiate();
|
|
const primary = rst.getPrimary();
|
|
const dbName = "test";
|
|
const collName = "server_read_concern_metrics";
|
|
const testDB = primary.getDB(dbName);
|
|
const testColl = testDB[collName];
|
|
const sessionOptions = {
|
|
causalConsistency: false
|
|
};
|
|
const session = testDB.getMongo().startSession(sessionOptions);
|
|
const sessionDb = session.getDatabase(dbName);
|
|
const sessionColl = sessionDb[collName];
|
|
testDB.runCommand({drop: collName, writeConcern: {w: "majority"}});
|
|
assert.commandWorked(testColl.insert({_id: 0}));
|
|
|
|
// Run an initial transaction to get config.transactions state into memory.
|
|
session.startTransaction();
|
|
assert.eq(sessionColl.find().itcount(), 1);
|
|
assert.commandWorked(session.abortTransaction_forTesting());
|
|
|
|
function getServerStatus(conn) {
|
|
// Don't return defaultRWConcern because it may trigger a refresh of the read write concern
|
|
// defaults, which unexpectedly increases the opReadConcernCounters.
|
|
return assert.commandWorked(conn.adminCommand({serverStatus: 1, defaultRWConcern: false}));
|
|
}
|
|
|
|
// Get initial serverStatus.
|
|
let serverStatus = getServerStatus(testDB);
|
|
verifyServerStatusFields(serverStatus);
|
|
|
|
// Run a find with no readConcern.
|
|
assert.eq(testColl.find().itcount(), 1);
|
|
let newStatus = getServerStatus(testDB);
|
|
verifyServerStatusFields(newStatus);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "available", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "linearizable", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "local", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "majority", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "snapshot", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "none", 1);
|
|
serverStatus = newStatus;
|
|
|
|
// Run a find with a readConcern with no level.
|
|
assert.commandWorked(
|
|
testDB.runCommand({find: collName, readConcern: {afterClusterTime: Timestamp(1, 1)}}));
|
|
newStatus = getServerStatus(testDB);
|
|
verifyServerStatusFields(newStatus);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "available", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "linearizable", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "local", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "majority", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "snapshot", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "none", 1);
|
|
serverStatus = newStatus;
|
|
|
|
// Run a legacy query.
|
|
primary.forceReadMode("legacy");
|
|
assert.eq(testColl.find().itcount(), 1);
|
|
newStatus = getServerStatus(testDB);
|
|
verifyServerStatusFields(newStatus);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "available", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "linearizable", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "local", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "majority", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "snapshot", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "none", 1);
|
|
primary.forceReadMode("commands");
|
|
serverStatus = newStatus;
|
|
|
|
// Run a find with a readConcern level available.
|
|
assert.eq(testColl.find().readConcern("available").itcount(), 1);
|
|
newStatus = getServerStatus(testDB);
|
|
verifyServerStatusFields(newStatus);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "available", 1);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "linearizable", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "local", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "majority", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "snapshot", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "none", 0);
|
|
serverStatus = newStatus;
|
|
|
|
// Run a find with a readConcern level linearizable.
|
|
assert.eq(testColl.find().readConcern("linearizable").itcount(), 1);
|
|
newStatus = getServerStatus(testDB);
|
|
verifyServerStatusFields(newStatus);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "available", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "linearizable", 1);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "local", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "majority", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "snapshot", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "none", 0);
|
|
serverStatus = newStatus;
|
|
|
|
// Run a find with a readConcern level local.
|
|
assert.eq(testColl.find().readConcern("local").itcount(), 1);
|
|
newStatus = getServerStatus(testDB);
|
|
verifyServerStatusFields(newStatus);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "available", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "linearizable", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "local", 1);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "majority", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "snapshot", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "none", 0);
|
|
serverStatus = newStatus;
|
|
|
|
// Run a find with a readConcern level majority.
|
|
assert.eq(testColl.find().readConcern("majority").itcount(), 1);
|
|
newStatus = getServerStatus(testDB);
|
|
verifyServerStatusFields(newStatus);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "available", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "linearizable", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "local", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "majority", 1);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "snapshot", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "none", 0);
|
|
serverStatus = newStatus;
|
|
|
|
// Run a find in a transaction with readConcern level snapshot.
|
|
session.startTransaction({readConcern: {level: "snapshot"}});
|
|
assert.eq(sessionColl.find().itcount(), 1);
|
|
newStatus = getServerStatus(testDB);
|
|
verifyServerStatusFields(newStatus);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "available", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "linearizable", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "local", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "majority", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "snapshot", 1);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "none", 0);
|
|
assert.commandWorked(session.abortTransaction_forTesting());
|
|
serverStatus = newStatus;
|
|
|
|
// Run a find in a transaction with no specified readConcern level.
|
|
session.startTransaction();
|
|
assert.eq(sessionColl.find().itcount(), 1);
|
|
newStatus = getServerStatus(testDB);
|
|
verifyServerStatusFields(newStatus);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "available", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "linearizable", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "local", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "majority", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "snapshot", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "none", 1);
|
|
assert.commandWorked(session.abortTransaction_forTesting());
|
|
serverStatus = newStatus;
|
|
|
|
// Run a find in a transaction with readConcern level local.
|
|
session.startTransaction({readConcern: {level: "local"}});
|
|
assert.eq(sessionColl.find().itcount(), 1);
|
|
newStatus = getServerStatus(testDB);
|
|
verifyServerStatusFields(newStatus);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "available", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "linearizable", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "local", 1);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "majority", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "snapshot", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "none", 0);
|
|
assert.commandWorked(session.abortTransaction_forTesting());
|
|
serverStatus = newStatus;
|
|
|
|
// Run a find in a transaction with readConcern level majority.
|
|
session.startTransaction({readConcern: {level: "majority"}});
|
|
assert.eq(sessionColl.find().itcount(), 1);
|
|
newStatus = getServerStatus(testDB);
|
|
verifyServerStatusFields(newStatus);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "available", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "linearizable", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "local", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "majority", 1);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "snapshot", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "none", 0);
|
|
serverStatus = newStatus;
|
|
|
|
// Run a second find in the same transaction. It will inherit the readConcern from the
|
|
// transaction.
|
|
assert.eq(sessionColl.find().itcount(), 1);
|
|
newStatus = getServerStatus(testDB);
|
|
verifyServerStatusFields(newStatus);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "available", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "linearizable", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "local", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "majority", 1);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "snapshot", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "none", 0);
|
|
assert.commandWorked(session.abortTransaction_forTesting());
|
|
serverStatus = newStatus;
|
|
|
|
// Aggregation does not count toward readConcern metrics. Aggregation is counted as a 'command'
|
|
// in the 'opCounters' serverStatus section, and we only track the readConcern of queries
|
|
// tracked in 'opCounters.query'.
|
|
assert.eq(testColl.aggregate([]).itcount(), 1);
|
|
newStatus = getServerStatus(testDB);
|
|
verifyServerStatusFields(newStatus);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "available", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "linearizable", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "local", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "majority", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "snapshot", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "none", 0);
|
|
serverStatus = newStatus;
|
|
|
|
// The count command does not count toward readConcern metrics. The count command is counted as
|
|
// a 'command' in the 'opCounters' serverStatus section, and we only track the readConcern of
|
|
// queries tracked in 'opCounters.query'.
|
|
assert.eq(testColl.count({_id: 0}), 1);
|
|
newStatus = getServerStatus(testDB);
|
|
verifyServerStatusFields(newStatus);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "available", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "linearizable", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "local", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "majority", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "snapshot", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "none", 0);
|
|
serverStatus = newStatus;
|
|
|
|
// getMore does not count toward readConcern metrics. getMore inherits the readConcern of the
|
|
// originating command. It is not counted in 'opCounters.query'.
|
|
let res = assert.commandWorked(testDB.runCommand({find: collName, batchSize: 0}));
|
|
serverStatus = getServerStatus(testDB);
|
|
assert.commandWorked(testDB.runCommand({getMore: res.cursor.id, collection: collName}));
|
|
newStatus = getServerStatus(testDB);
|
|
verifyServerStatusFields(newStatus);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "available", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "linearizable", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "local", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "majority", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "snapshot", 0);
|
|
verifyServerStatusChange(
|
|
serverStatus.opReadConcernCounters, newStatus.opReadConcernCounters, "none", 0);
|
|
|
|
session.endSession();
|
|
rst.stopSet();
|
|
}());
|