This blog is another in the series for the Percona Server for MongoDB 3.4 bundle release. Today’s blog post is about how to migrate between Percona Server for MongoDB storage engines without downtime.
Today, the default storage engine for MongoDB is WiredTiger. In previous versions (before 3.2), it was MMAPv1.
Percona Server for MongoDB features some additional storage engines, giving you the freedom for a DBA to choose the best storage based on application workload. Our storages engines are:
By design, each storage engine has its own algorithm and disk usage patterns. We simply stop and start Percona Server for MongoDB using different storage engines.
There are two common methods to change storage engines. One requires downtime, and the second doesn’t.
All the database operations are the same, even if it is using a different storage engine. From the database perspective, it doesn’t matter what storage engine gets used. The database layer asks the persistence API to save or retrieve data regardless.
For a single database instance, the best storage engine migration method is to start replication and add a secondary node with a different storage engine. Then stepdown() the primary, making the secondary the new primary (killing the old primary).
However, this isn’t always an option. In this case, create a backup and use the backup to restore the database.
In the following set of steps, we’ll explain how to migrate a replica set storage engine from WiredTiger to RocksDB without downtime. I’m assuming that the replica set is already configured and doesn’t have any replication lag.
Please follow the instructions below:
|
1 |
foo:PRIMARY> rs.status()<br>{<br> "set" : "foo",<br> "date" : ISODate("2017-02-18T18:47:54.349Z"),<br> "myState" : 2,<br> "term" : NumberLong(2),<br> "syncingTo" : "adamo-percona:27019",<br> "heartbeatIntervalMillis" : NumberLong(2000),<br> "members" : [<br> {<br> "_id" : 0,<br> "name" : "test:27017",<br> "stateStr" : "PRIMARY" (...)<br> },<br> {<br> "_id" : 1,<br> "name" : "test:27018",<br> "stateStr" : "SECONDARY" (...)<br> },<br> {<br> "_id" : 2,<br> "name" : "test:27019",<br> "stateStr" : "SECONDARY" (...)<br> } { ... }<br> ],<br> "ok" : 1<br>} |
|
1 |
foo:PRIMARY> cfg = rs.config()<br> |
|
1 |
foo:PRIMARY> cfg.members[2].name<br>test:27019<br><br>foo:PRIMARY> cfg.members[2].priority = 0<br>0<br>foo:PRIMARY> cfg.members[2].hidden = true<br>true<br>foo:PRIMARY> rs.reconfig(cfg)<br>{ "ok" : 1 }<br> |
|
1 |
foo:PRIMARY>rs.config()<br>{<br> "_id" : "foo",<br> "version" : 4,<br> "protocolVersion" : NumberLong(1),<br> "members" : [<br> {<br> "_id" : 0,<br> "host" : "test:27017",<br> "arbiterOnly" : false,<br> "buildIndexes" : true,<br> "hidden" : false,<br> "priority" : 1,<br> "votes" : 1<br> },<br> {<br> "_id" : 1,<br> "host" : "test:27018",<br> "arbiterOnly" : false,<br> "buildIndexes" : true,<br> "hidden" : false,<br> "priority" : 1,<br> "slaveDelay" : NumberLong(0),<br> "votes" : 1<br> },<br> {<br> "_id" : 2,<br> "host" : "test:27019",<br> "arbiterOnly" : false,<br> "buildIndexes" : true,<br> "hidden" : true, <--<br> "priority" : 0, <--<br> "slaveDelay" : NumberLong(0),<br> "votes" : 1<br> }<br> ],<br> "settings" : {...}<br>} |
|
1 |
ps -ef | grep mongodb | grep 27019<br>kill < mongod pid>;<br>rm -rf /data3/*<br>./mongod --dbpath data3 --logpath data3/log3.log --fork --port 27019 <strong>--storageEngine=rocksdb</strong> --replSet foo |
|
1 |
<config file><br>storage:<br> engine: rocksdb |
|
1 |
foo:PRIMARY> cfg = rs.config()<br>foo:PRIMARY> cfg.members[2].hidden = false<br>false <br>foo:PRIMARY> rs.reconfig(cfg)<br>{ "ok" : 1 } |
|
1 |
foo:PRIMARY> cfg = rs.config()<br>foo:PRIMARY> cfg.members[2].hidden = false<br>false <br>foo:PRIMARY> cfg.members[2].priority = 1<br>foo:PRIMARY> cfg.members[1].priority = 1 |
|
1 |
foo:PRIMARY> rs.stepDown()<br>2017-02-20T16:34:53.814-0300 E QUERY [thread1] Error: error doing query: failed: network error while attempting to run command 'replSetStepDown' on host '127.0.0.1:27019' :<br>DB.prototype.runCommand@src/mongo/shell/db.js:135:1<br>DB.prototype.adminCommand@src/mongo/shell/db.js:153:16<br>rs.stepDown@src/mongo/shell/utils.js:1182:12<br>@(shell):1:1<br>2017-02-20T16:34:53.815-0300 I NETWORK [thread1] trying reconnect to 127.0.0.1:27019 (127.0.0.1) failed<br>2017-02-20T16:34:53.816-0300 I NETWORK [thread1] reconnect 127.0.0.1:27019 (127.0.0.1) ok<br><br>foo:SECONDARY> rs.status() |
After this process, the instances will run RocksDB without experiencing downtime (just an election to change the primary).
Please feel free to ping us on Twitter @percona with any questions and suggestions for this blog post.
Resources
RELATED POSTS