When you run rs.printSecondaryReplicationInfo();
then the output is like this:
source: d-mipmdb-cfg-02:27019
syncedTo: Sat Apr 02 2022 20:01:01 GMT+0200 (W. Europe Daylight Time)
0 secs (0 hrs) behind the primary
source: d-mipmdb-cfg-03:27019
syncedTo: Sat Apr 02 2022 20:00:58 GMT+0200 (W. Europe Daylight Time)
3 secs (0 hrs) behind the primary
The documentation says “Use rs.printSecondaryReplicationInfo()
for manual inspection, and rs.status()
in scripts.” but it does not tell me directly where to see this information.
I guess with rs.status()
you get the same information with a script like this:
const members = rs.status().members
const primary = members.filter(x=> x.stateStr == "PRIMARY").shift().optimeDate;
members.filter(x=> x.stateStr == "SECONDARY").map(x=> {return `${x.name} is ${(primary - x.optimeDate)/1000} Seconds behind the primary`});
[
"d-mipmdb-cfg-02:27019 is 2 Seconds behind the primary",
"d-mipmdb-cfg-03:27019 is 3 Seconds behind the primary"
]
Is this correct or do I need to run something else?
Kind Regards
Wernfried
1 Like
Hi @Wernfried_Domscheit ,
MongoDB shell helpers derive replication lag from rs.status()
, so your approach looks correct.
The implementations in the new and legacy MongoDB shells may be helpful references, although they have additional logic and error handling to try to cover broader usage scenarios than your example.
mongosh
(mongodb-js/mongosh
):
The new MongoDB shell uses the MongoDB Node.js driver and TypeScript:
@apiVersions([1])
async printShardingStatus(verbose = false): Promise<CommandResult> {
this._emitDatabaseApiCall('printShardingStatus', { verbose });
const result = await getPrintableShardStatus(await getConfigDB(this), verbose);
return new CommandResult('StatsResult', result);
}
@returnsPromise
@topologies([Topologies.ReplSet])
@apiVersions([])
async printSecondaryReplicationInfo(): Promise<CommandResult> {
let startOptimeDate = null;
const local = this.getSiblingDB('local');
if (await local.getCollection('system.replset').countDocuments({}) !== 0) {
const status = await this._runAdminCommand({ 'replSetGetStatus': 1 });
// get primary
let primary = null;
for (const member of status.members) {
if (member.state === 1) {
primary = member;
mongo
shell (mongodb/mongo/src/mongo/shell
)
The legacy mongo
shell uses an embedded JavaScript engine:
print("oplog last event time: " + result.tLast);
print("now: " + result.now);
};
DB.prototype.printSlaveReplicationInfo = function() {
print(
"WARNING: printSlaveReplicationInfo is deprecated and may be removed in the next major release. Please use printSecondaryReplicationInfo instead.");
this.printSecondaryReplicationInfo();
};
DB.prototype.printSecondaryReplicationInfo = function() {
var startOptimeDate = null;
var primary = null;
function getReplLag(st) {
assert(startOptimeDate, "how could this be null (getReplLag startOptimeDate)");
print("\tsyncedTo: " + st.toString());
var ago = (startOptimeDate - st) / 1000;
var hrs = Math.round(ago / 36) / 100;
var suffix = "";
if (primary) {
Regards,
Stennie
2 Likes
Just a small remark - you won’t see unhealthy hosts with that query, for example in "(not reachable/healthy)
state. To fix it, just change this string to
members.
filter(x=> x.stateStr != "PRIMARY").
map(x=> {
return `${x.name} is ${(primary - x.optimeDate)/1000} Seconds behind the primary`
});