Read concern "snapshot" and the corresponding clusterTime

Viewed 118

There's been a really handy addition in MongoDB 5.x that allows enforcing snapshot read concern in some read operations outside transactions and specify the timestamp at which the snapshot is taken via atClusterTime. If the timestamp is not provided, mongo will select it automatically and kindly return its value to the user for future reference. See:

https://www.mongodb.com/docs/v6.0/reference/read-concern-snapshot/#read-concern-and-atclustertime

Since MongoDB 4.x also supports read concern snapshot - but only inside transactions with write concern majority - I am wondering if it is also possible to obtain some information about when exactly the snapshot was taken, similarly to what 5.x is doing. I understand that I cannot explicitly specify atOperationTime but somehow mongo needs to select the timestamp on its own, so it seems reasonable to expect that this information should be available somewhere.

1 Answers

I am afraid there is no convenient way to get the cluster time for Mongo < 5.0. You can always inspect the logs, but I would not consider it a reliable solution. Anyway, here is a possible script you could run on the mongo shell:

db.adminCommand( { getLog : "global" } ).log
    .map(x => JSON.parse(x))
    .filter(x => x.c === "TXN")
    .forEach(x => print(JSON.stringify(x.attr.parameters.readConcern)))

Let's start by saying that the getLog command with the global filter returns only the most recent logs, so if you are looking for old transactions I guess you need to parse the physical log files. That script:

  1. parses the log entries to convert them from strings to JS objects
  2. filters the entries and keeps only those related to transactions, see here for all the types and additional info
  3. retrieves the readConcern parameters and print them to console

You should see an output similar to this one:

{"level":"snapshot","provenance":"clientSupplied"}
{"level":"snapshot","afterClusterTime":{"$timestamp":{"t":1657483320,"i":1}},"provenance":"clientSupplied"}
{"level":"snapshot","afterClusterTime":{"$timestamp":{"t":1657483977,"i":1}},"provenance":"clientSupplied"}

We found the cluster time: afterClusterTime.

In the first transaction, I added a document to an empty collection, which could be why it does not show the cluster time (and was not used, of course). I don't know the meaning of each parameter and all the cases in which you will not get the cluster time, but there is good news. To get the logs, if exist, belonging to a given transaction id, you need to apply this filter (instead of the one shown above):

.filter(x => x.c === "TXN" && x.attr.parameters.txnNumber === your_txn_id)
Related