The Challenge
Modern applications often use multiple databases simultaneously: a relational database for structured data, Redis for caching and sessions, and MongoDB or Elasticsearch for specific workloads. Migrating all of these together while maintaining data consistency requires careful coordination.
Migration Plan
- Set up all database services on the target server
- Perform initial data sync for each database
- Enable continuous replication where possible
- Brief maintenance window for final sync
- Switch application to new databases
Step 1: Install Database Services
sudo apt update
sudo apt install -y mysql-server postgresql redis-server
# MongoDB
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | sudo apt-key add -
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | \
sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
sudo apt update && sudo apt install -y mongodb-org
sudo systemctl enable --now mongod
Step 2: Initial Data Sync
# MySQL (runs while source is live)
ssh root@source "mysqldump --single-transaction --all-databases" | mysql
# PostgreSQL
ssh root@source "sudo -u postgres pg_dumpall" | sudo -u postgres psql
# Redis (RDB dump method)
ssh root@source "redis-cli BGSAVE && sleep 5 && cat /var/lib/redis/dump.rdb" > /var/lib/redis/dump.rdb
sudo systemctl restart redis
# MongoDB
ssh root@source "mongodump --gzip --archive" | mongorestore --gzip --archive
Step 3: Final Coordinated Sync
#!/bin/bash
# /usr/local/bin/coordinated-migration.sh
set -euo pipefail
SOURCE="root@source-ip"
echo "1. Enabling maintenance mode..."
ssh $SOURCE "touch /var/www/html/.maintenance"
sleep 10 # Allow in-flight requests to complete
echo "2. Final MySQL sync..."
ssh $SOURCE "mysqldump --single-transaction --all-databases" | mysql
echo "3. Final PostgreSQL sync..."
ssh $SOURCE "sudo -u postgres pg_dumpall" | sudo -u postgres psql
echo "4. Final Redis sync..."
ssh $SOURCE "redis-cli BGSAVE && sleep 3 && cat /var/lib/redis/dump.rdb" > /var/lib/redis/dump.rdb
sudo systemctl restart redis
echo "5. Final MongoDB sync..."
ssh $SOURCE "mongodump --gzip --archive" | mongorestore --gzip --archive --drop
echo "6. Update application configs..."
# Update .env with new database hosts (localhost)
echo "7. Restart application..."
sudo systemctl restart myapp
echo "Migration complete! Update DNS now."
Verification
# Compare record counts across all databases
echo "MySQL tables:"
mysql -e "SELECT table_schema, table_name, table_rows FROM information_schema.tables WHERE table_schema NOT IN ('mysql','information_schema','performance_schema','sys') ORDER BY table_schema, table_name;"
echo "PostgreSQL tables:"
sudo -u postgres psql -c "SELECT schemaname, relname, n_tup_ins FROM pg_stat_user_tables ORDER BY schemaname, relname;"
echo "Redis keys:"
redis-cli DBSIZE
echo "MongoDB collections:"
mongosh --eval "db.adminCommand('listDatabases').databases.forEach(function(d) { var db = db.getSiblingDB(d.name); print(d.name + ': ' + db.getCollectionNames()); })"
Best Practices
- Migrate databases in dependency order (caches last)
- Use replication for zero-downtime where possible
- Verify data integrity for each database independently
- Keep maintenance window as short as possible
- Have a rollback plan for each database