-
Notifications
You must be signed in to change notification settings - Fork 97
Migrating Replica Set Online
This guide explains how to do an online data migration from MongoDB to TokuMX, for a replica set, converting the existing data in MongoDB to TokuMX.
For other migration strategies, start with Migrating from MongoDB and Migrating from MongoDB: Replica sets.
You will need to prepare by provisioning a number of extra machines where you will build your TokuMX replica set.
The online migration of a replica set is four phases:
- Backup
- Import
- Catchup
- Switch
If you already have a backup with a known OpTime
, you can skip the first
steps that take a backup of a secondary.
-
Shut down one of the MongoDB secondaries.
-
Take a backup of that secondary with
mongodump
.$ sudo mongodump --dbpath /var/lib/mongodb --out /var/lib/mongodb.backup - MongoDB latest version - $ sudo mongodump --out /var/lib/mongodb.backup
-
While the secondary is down, connect to the primary and find out the
OpTime
that the secondary was at when it was shut down. Look for theoptime
for the machine in themembers
array that is"(not reachable/healthy)"
.rs:PRIMARY> rs.status() { "set" : "rs", "date" : ISODate("2013-07-13T18:19:04Z"), "myState" : 1, "members" : [ ..., { "_id" : 2, "name" : "cavil:20002", "health" : 0, "state" : 8, "stateStr" : "(not reachable/healthy)", "uptime" : 0, "optime" : { "t" : 1373658837, "i" : 999 }, ... } ], "ok" : 1 }
Save this
OpTime
along with the backup:{t: 1373658837, i: 999}
-
Start the secondary back up and let it catch up with its replica set.
You need to import this backup into a TokuMX replica set. The latter half of the offline migration process applies here:
-
Install TokuMX for your distribution on all machines (instructions). If your distribution's package manager automatically starts TokuMX, stop it for now.
-
Import your backup to just the primary with
mongorestore
. You will need thedbpath
from/etc/tokumx.conf
(by default,/var/lib/tokumx
).Primary server only:
$ mongorestore --dbpath /var/lib/tokumx /var/lib/mongodb.backup
-
Add the
replSet
option to/etc/tokumx.conf
on all machines, for example,replSet = rs0
. -
Start the primary, connect to it, and run
rs.initiate()
and wait for it to become primary, and then shut it down, to initialize the oplog.Primary server only:
$ mongo TokuMX mongo shell v1.4.2-mongodb-2.4.10 connecting to: test > rs.initiate() { "info2" : "no configuration explicitly specified -- making one", "me" : "db1.localdomain:27017", "info" : "Config now saved locally. Should come online in about a minute.", "ok" : 1 } > rs0:PRIMARY>
-
Copy the
dbpath
to all the secondaries. The data is already compressed, so compressing withrsync
will not be faster, and it will be much faster than a normal initial sync. -
Add the
fastsync=true
option to/etc/tokumx.conf
on all secondaries. -
Start TokuMX on all servers.
-
Connect to the primary and
rs.add()
each of the secondaries. Withfastsync
they will not need to do a full initial sync.Primary server only:
$ mongo TokuMX mongo shell v1.4.2-mongodb-2.4.10 connecting to: test rs0:PRIMARY> rs.add('db2.domain:27017') { "ok" : 1 } rs0:PRIMARY> rs.add('db3.domain:27017') { "ok" : 1 }
-
Remove the
fastsync=true
option from/etc/tokumx.conf
on each of the secondaries. You do not need to restart them now.
This phase uses the mongo2toku
tool to catch the TokuMX replica set
up with the MongoDB replica set by replaying the MongoDB oplog.
Below, suppose the MongoDB replica set is identified by
mongodb/v1.domain,v2.domain,v3.domain
and the TokuMX replica set is
identified by tokumx/t1.domain,t2.domain,t3.domain
.
-
Using the
OpTime
recorded earlier, startmongo2toku
. This will read the MongoDB oplog and replay its operations on the TokuMX replica set, but the TokuMX replica set will not count for write concern on the MongoDB set, and it will not be able to vote in elections on the MongoDB set.$ mongo2toku --ts=1373658837:999 \ --from mongodb/m1.domain,m2.domain,m3.domain \ --host tokumx/t1.domain,t2.domain,t3.domain
Let mongo2toku
run until it is fully caught up to (or only a few seconds
behind) the MongoDB replica set. Feel free to stop and start it, taking
in to consideration the notes below.
Once mongo2toku
is fully synced, it will continue to tail the MongoDB
oplog until stopped, so you can leave it running and keep the TokuMX
replica set synced until it is appropriate to switch over your
application.
When you are ready to switch your application over to TokuMX, leave
mongo2toku
running through the entire process.
-
Pause your application's writes to the MongoDB replica set.
-
Wait until
mongo2toku
reports that it is "fully synced" a few times to the log. -
Redirect your application to point to the TokuMX replica set.
-
Shut down
mongo2toku
.
At this point, you can delete the old MongoDB data and shut down the machines it was running on.
It is important that mongo2toku
does not try to replay an operation
twice. If there is an error, or if mongo2toku
is stopped manually
(control C works), mongo2toku
will save a file in the current directory
with the OpTime
it had reached while syncing, and will also print that
value to the console.
When resuming, it will assume that operation was replayed and will try to
replay the following operation. If you do not provide --ts
when
restarting mongo2toku
it will use the value saved in the file, but
--ts
can override it.
The mongo2toku
tool is simple: it reads the oplog from one MongoDB
server or set of servers and replays those operations on another MongoDB
or TokuMX server or set of servers. Therefore, it can be used to test
TokuMX's suitability for handling a write workload that MongoDB is
running, without making the application rely on TokuMX for queries.
To do this, you would follow the above guide until TokuMX was caught up,
then just leave mongo2toku
running and monitor system load and metrics,
response latencies, and anything else important for your workload. You
could also try building additional background indexes on TokuMX.
Since mongo2toku
just looks like a normal client application to the
TokuMX server, you can run multiple instances copying data to the same
TokuMX replica set. Therefore, it is possible to simulate the result of
running a MongoDB sharded cluster workload on a single TokuMX replica
set. For details on how to migrate a MongoDB sharded cluster to a single
TokuMX replica set, see
Migrating from MongoDB: Sharded cluster (offline, all data at once).
The online migration procedure typically requires approximately double the machine capacity since there need to be two replica sets running concurrently: MongoDB and TokuMX.
However, it is possible to do an online migration with little or no extra capacity. This process is more complicated and takes longer, but is suitable for applications with limited resources.
The process is site-specific, but this is the general procedure:
-
Begin as above, by taking a backup and noting the
OpTime
of that backup. -
Instead of starting the secondary back up, remove it from the MongoDB replica set and delete its
dbpath
.If necessary, add more arbiters to the MongoDB replica set, since it has one fewer members now.
-
Import the backup into TokuMX on the machine that was just cleaned. Turn it into a replica set (set
replSet
and runrs.initiate()
) and add some arbiters to that replica set. -
(Optional) Shut down that TokuMX instance once its oplog is initialized, and copy its
dbpath
somewhere else, to be used to start other TokuMX secondaries later. Then start it again. -
Run
mongo2toku
as before, from the MongoDB replica set to the TokuMX replica set. -
Select another MongoDB secondary, remove it from the replica set, and delete its
dbpath
. -
Install TokuMX to that machine, and either add it to the TokuMX replica set and let it complete an initial sync, or if the original TokuMX
dbpath
was saved above, copy that to thedbpath
and start the server withfastsync
to avoid the initial sync (see the offline migration instructions for more details onfastsync
). -
Continue taking machines out of the MongoDB replica set and replacing them with TokuMX machines until there are enough TokuMX machines to handle the full application workload. During this process, any application queries that can normally be done on secondaries (with
slaveOk
) can be redirected to the TokuMX replica set if it is suitably well synced. -
When the TokuMX replica set is full enough to accept the full application workload, switch the application over to it (remember to wait for
mongo2toku
to be "fully synced" after pausing the application), and then tear down the remaining MongoDB machines and replace them with TokuMX machines if needed.
The dbHash
command can be run on any database and will produce a hash
value that is dependent on all the documents in that database. After a
successful migration, it will produce the same results on MongoDB as on
TokuMX, so it can be used to verify that a migration process was
implemented successfully. Just remember to make sure MongoDB is not
accepting writes while dbHash
is running, and make sure that
mongo2toku
says it is "fully synced" before running dbHash
on TokuMX.
When creating a unique index in MongoDB, it is possible to add the option
dropDups
. This is an arbitrarily destructive operation, so it was not
implemented in TokuMX. Even if it were implemented, there is no way for
TokuMX to be sure that it dropped the same documents that MongoDB would
have dropped.
Therefore, if an ensureIndex
with dropDups: true
is encountered by
mongo2toku
, it will attempt to build the index without that option, but
if there actually are duplicates, that index build will fail.
If it fails, the only option is to restart the migration process by taking a new backup. That backup will now be after the index creation happened, so you won’t need to process the same index build operation again.