MongoDB more indexes on Secondaries
I’ve been wondering for a time if it works, the documentation is not really clear if you can have different indexes on a replicaset secondary, maybe delayed or with priority 0.
Using this feature you can do reports better on a secondary (maybe delayed too) secondary server. Make sure the journal is big enough to allow secondary indexes to be built.
Step 1: Build replica set
a. Here are the replica set config files:
dbpath = /tmp/mongo/data logpath = /tmp/mongo/log.log replSet = rs0 port = 27100 fork = true smallfiles = true |
dbpath = /tmp/mongo/data1 logpath = /tmp/mongo/log1.log replSet = rs0 port = 27101 fork = true smallfiles = true |
dbpath = /tmp/mongo/data2 logpath = /tmp/mongo/log2.log replSet = rs0 port = 27102 fork = true smallfiles = true |
b. Start servers
> mongod --config mongodb-rpl-s0.conf > mongod --config mongodb-rpl-s1.conf > mongod --config mongodb-rpl-s2.conf
c. Configure replica set members
> mongo --port 27100 rs.add("127.0.0.1:27100") rs.add("127.0.0.1:27101") rs.add({_id:2, host:"127.0.0.1:27102",priority:0})
d. Add some data and indexes
use testdb db.test.insert({a:1,b:1,c:1}) db.test.insert({a:2,b:2,c:2}) db.test.insert({a:3,b:3,c:3}) db.ensureIndex({a:1})
Step 2. Separate node and add indexes
a. Remove node from replicaset
rs.remove("127.0.0.1"27102")
b. Stop server
> mongo --port 27102 use admin db.db.shutdownServer()
c. Modify config outside the replica set
dbpath = /tmp/mongo/data2 logpath = /tmp/mongo/log2.log # replSet = rs0 port = 27102 fork = true smallfiles = true
d. Start server
> mongod --config mongodb-rpl-s2.conf
e. Add index
use testdb db.test.ensureIndex({c:1})
f. Meanwhile on the primary some inserts happen
db.test.insert({a:4,b:4,c:4}) db.test.insert({a:5,b:5,c:5})
Step 3. Rebuild replica set
a. Stop separated slave
mongo --port 27102 use admin db.db.shutdownServer()
b. Modify back the config
dbpath = /tmp/mongo/data2 logpath = /tmp/mongo/log2.log replSet = rs0 port = 27102 fork = true smallfiles = true
c. Start server again
> mongod --config mongodb-rpl-s2.conf
d. Add back to replica set
> mongo --port 27100 rs.add({_id:2, host:"127.0.0.1:27102",priority:0})
e. Wait for synchronisation
> mongo --port 27102 use testdb db.test.find() // documents with a:1 and a:2 will be synced
f. Test queries on primary
mongo --port 27100 db.test.find({a:1}).explain() { "cursor" : "BtreeCursor a_1", "indexBounds" : {"a" : [[1,1]]}, ... } db.test.find({c:1}).explain() // NO INDEX ON c { "cursor" : "BasicCursor", ... }
g. Test queries on node 2
mongo --port 27102 db.test.find({a:1}).explain() { "cursor" : "BtreeCursor a_1", "indexBounds" : {"a" : [[1,1]]}, ... } db.test.find({c:1}).explain() // HAVE AN INDEX ON c { "cursor" : "BtreeCursor c_1", "indexBounds" : {"c" : [[1,1]]}, ... }
Didn’t have time for benchmarking, will do probably this in another post