Step‑by‑Step MongoDB Migration Using Full Backup and Incremental Oplog
This article explains how to migrate a 240 GB MongoDB replica set by performing a full backup with oplog, extracting the incremental oplog timestamp, and then applying incremental backup and restore scripts to minimize downtime, while providing detailed shell commands and precautionary tips.
1 Background Introduction
The client needs to migrate a MongoDB replica‑set containing roughly 240 GB of data. Full backup takes about 3.5 hours and restore 4.5 hours. To reduce the cut‑over window, a full‑plus‑incremental Oplog strategy is used: a full backup is taken one day in advance, and on the migration day only the incremental Oplog is backed up and restored.
2 Practical Process
View Oplog Information
Check the production Oplog size and age to ensure it will not be overwritten during backup.
mongo> db.getReplicationInfo()
{
"logSizeMB" : 20480,
"usedMB" : 20374.38,
"timeDiff" : 7074665,
"timeDiffHours" : 1965.18,
"tFirst" : "Fri Feb 24 2023 18:36:32 GMT+0800 (CST)",
"tLast" : "Wed May 17 2023 15:47:37 GMT+0800 (CST)",
"now" : "Wed May 17 2023 15:47:43 GMT+0800 (CST)"
}The Oplog has grown to about 20 GB over 1965 hours.
Full Backup
Perform a full backup and keep the generated Oplog for later incremental restore.
#!/bin/bash
user=admin
password=123
host=127.0.0.1
port=27017
outputdir=/data/mongobak_$(date +%F)
authenticationdatabase=admin
start_time=$(date +%s)
mongodump -u $user --host $host --port $port -p $password \
--authenticationDatabase $authenticationdatabase --oplog --gzip -o $outputdir
stop_time=$(date +%s)
duration=$((stop_time-start_time))
echo "Spend times: $duration seconds"Full Restore
Restore the data using the full backup.
#!/bin/bash
start_time=$(date +%s)
user=admin
password=123
host=127.0.0.1
port=27017
authenticationdatabase=admin
mongorestore -u $user --host $host --port $port -p $password \
--authenticationDatabase $authenticationdatabase --oplogReplay --gzip /data/mongobak_2023-07-17
stop_time=$(date +%s)
duration=$((stop_time-start_time))
echo "Spend times: $duration seconds"Extract Incremental Backup Start Timestamp
Convert the saved Oplog BSON file to JSON with bsondump and locate the last timestamp.
shell> cd /data/mongobak_2023-07-17
mv oplog.bson oplog.bson.gz
gzip -d oplog.bson.gz
bsondump --pretty oplog.bson > op.jsonSearch op.json for the "ts" field to obtain the timestamp (e.g., t:1686669429, i:4).
Incremental Backup
Backup Oplog entries whose timestamps are greater than the last full‑backup timestamp.
#!/bin/bash
user=admin
password=123
host=127.0.0.1
port=27017
outputdir=/tmp/oplog_$(date +%F)
authenticationdatabase=admin
start_time=$(date +%s)
mongodump -u $user --host $host --port $port -p $password \
--authenticationDatabase $authenticationdatabase -d local -c oplog.rs \
-q '{"ts":{"$gt": {"$timestamp":{"t":1686669429,"i":4}}}}' -o $outputdir
stop_time=$(date +%s)
duration=$((stop_time-start_time))
echo "Spend times: $duration seconds"Incremental Restore
#!/bin/bash
user=admin
password=123
host=127.0.0.1
port=27017
authenticationdatabase=admin
start_time=$(date +%s)
mongorestore -u $user --host $host --port $port -p $password \
--authenticationDatabase $authenticationdatabase --oplogReplay /data/oplog_2023-07-17
stop_time=$(date +%s)
duration=$((stop_time-start_time))
echo "Spend times: $duration seconds"Document Count Comparison After Incremental Migration
Run the following script on both source and target clusters to verify that each database and collection contains the same number of documents.
#!/bin/bash
user=admin
password=123
host=127.0.0.1
port=27017
authenticationdatabase=admin
mpid=$(pidof mongod)
toolDir=$(dirname $(ls -l /proc/$mpid/exe | awk '{print $11}'))
# Get list of user databases (exclude admin, config, local)
databases=$(echo "show dbs" | $toolDir/mongo -uadmin --host $host --port $port -p $password \
--authenticationDatabase $authenticationdatabase --quiet | awk '{print $1}' | sed -E '/^admin$|^config$|^local$/d')
for db in $databases; do
collections=$(echo -e "use $db\nshow collections" | $toolDir/mongo -u $user --host $host --port $port -p $password \
$authenticationdatabase --quiet | sed '/switched to db/d')
for coll in $collections; do
count=$(echo -e "use $db\n db.$coll.count()" | $toolDir/mongo -u $user --host $host --port $port -p $password \
--authenticationDatabase $authenticationdatabase --quiet | sed '/switched to db/d')
echo "$db.$coll have $count documents"
done
doneSource Cluster Result
(Image omitted in text version.)
Target Cluster Result
(Image omitted in text version.)
3 Precautions
When using a secondary for backup, verify that the secondary is fully caught up with the primary before stopping business services; otherwise the backup may be inconsistent.
If the full backup was compressed with gzip, rename oplog.bson to oplog.bson.gz before decompressing, and then use bsondump to parse the BSON file; otherwise parsing will fail.
About SQLE
SQLE is an all‑round SQL quality‑management platform that supports open‑source, commercial, and domestic databases, providing automated workflow for development and operations to improve release efficiency and data quality.
GitHub: https://github.com/actiontech/sqle
Documentation: https://actiontech.github.io/sqle-docs/
Official site: https://opensource.actionsky.com/sqle/
Aikesheng Open Source Community
The Aikesheng Open Source Community provides stable, enterprise‑grade MySQL open‑source tools and services, releases a premium open‑source component each year (1024), and continuously operates and maintains them.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.