axeolotl
axeolotl

Reputation: 51

How to set up a mongodb delayed slave that is not hidden?

For testing purposes, I am trying to simulate a replication lag in a mongodb cluster, by setting up a slave with slaveDelay=n. As it turns out, this magically causes the slave to be hidden, so my test cannot access it.

The mongodb documentation states "Typically we would not want a delayed member to be used for slaveOkay reads. Thus, setting slaveDelay also hides the member from your application as if you also set hidden:true."

Is there a way to configure for my "untypical" use case? Or is there a better way to simulate reading from different slaves with varying time lag?

I tried forcing the test code to connect to the delayed slave using a TaggedReadPreference, but this results in a

com.mongodb.MongoException: Could not find any valid secondaries with the supplied tags ('{ "delayed" : "true"}'

Apparently the Java driver does cannot see the secondary. When I remove the "slaveDelay" setting, it connects fine.

Here's my cluster configuration:

rs.reconfig({
"_id" : "rs0",
"version" : 4,
"members" : [
    {   "_id" : 0,
        "host" : "localhost:27017",
        "priority" : 0,
        slaveDelay: 10,
        tags: { delayed: "true" }
    },
    {   "_id" : 1,
        "host" : "localhost:27018"
    },
    {   "_id" : 2,
        "host" : "localhost:27019",
        "arbiterOnly" : true
    }
]
})

Upvotes: 5

Views: 2048

Answers (2)

Adam Comerford
Adam Comerford

Reputation: 21692

You could fsync and lock the secondary for a time to force it to fall behind:

http://www.mongodb.org/display/DOCS/fsync+Command#fsyncCommand-v2.0Notes

Although it would quickly catch up once you unlocked, with a decent oplog and a large insert rate you could repeatedly simulate the lagging effect. It would mean waiting for it to lag before you start your tests etc.

If you had a primary, one secondary and an arbiter as you describe and used the W=2 equivalent (REPLICAS_SAFE etc) in your language of choice, while the secondary is locked that would block indefinitely unless you set wtimeout (which you should, and catch the exception if using W=2).

Upvotes: 1

Remon van Vliet
Remon van Vliet

Reputation: 18615

This is not possible as far as I'm aware. Your only route is to simulate/force actual network delay between your primary and your delayed secondary through a proxy for example. There are a number of such tools available and they will give you a more accurate test.

Upvotes: 1

Related Questions