coyote uses mongodump and mongorestore to perform:
- a point in time restore (pitr) of a live source cluster to a new target cluster
- subsequent source operation log replays on the target, in perpetuity, to keep target synced with source until the source goes offline
coyote requires jq and assumes it can be installed with sudo apt-get install -y jq
if it isn't installed. if that isn't the case, make sure jq is installed already at a location included in ${PATH}.
clone the gist and create an environment file containing variables like those seen in atlas-hetzner.env
name it something simple, like source-target.env
. do ensure it has a .env
extension
dump_path
is the folder that will hold the initial database dump (${dump_path}/init
) and subsequent oplog dumps (${dump_path}/${datetime}
)source_uri
is the connection string for the source cluster, including credentials or certificate-paths. it must not contain a database specifiertarget_uri
is the connection string for the target cluster, including credentials or certificate-paths. it must not contain a database specifier
run the install script, supplying positional arguments for:
environment_file
: the filename without folder or extension of the environment file you created earlier. ie:source-target
target_admin_username
: the admin user on the target cluster. ie:admin
target_admin_password
: the password for admin user on the target cluster. ie:password
service_user
: the name of the user the service will run under. ie:coyote
. omit this parameter to use the default,coyote
service_name
: the name of the systemd service. ie:coyote
. omit this parameter to use the default,coyote
tail the system journal to observe the running service logs. ie:
journalctl -fu coyote.service
coyote log output contains a delta value for each collection and database. if your application design is such that documents are never modified, you can assume a zero value to mean that your source and target are in sync. if your application design includes document modification, you will need to implement an application specific mechanism for determining delta.
- a delta value of
0
indicates that both source and target have an equal number of documents. - a positive delta value indicates that source contains delta documents more than target. either your target sync is incomplete or your application layer is still adding documents to source.
- a negative delta value indicates that source contains abs(delta) documents fewer than target. your application layer has commenced adding documents to target. coyote will terminate on detection of a negative delta since target has more documents than source.
to migrate your applications without data loss:
- wait for delta values to reach the smallest values they are likely to arrive at
- pause/disable/stop all applications which write to source
- disable a lambda by destroying its connection string:
aws lambda update-function-configuration \ --profile manta-service \ --region eu-central-1 \ --function-name calamari-faucet-prod-shortlist \ --description "-" \ --environment '{ "Variables": { "db_readwrite": "mongodb://undefined" } }'
- disable a lambda by destroying its connection string:
- wait for all delta values to reach zero
- stop, disable and remove the coyote service
sudo systemctl stop coyote.service sudo systemctl disable coyote.service sudo rm /etc/systemd/system/coyote.service
- modify the connection strings of all applications to write to target rather than source
- re-enable a lambda by restoring its connection string:
aws lambda update-function-configuration \ --profile manta-service \ --region eu-central-1 \ --function-name calamari-faucet-prod-shortlist \ --description "-" \ --environment '{ "Variables": { "db_readwrite": "mongodb://username:[email protected]:27017/?ssl=true&replicaSet=rs0&authSource=admin" } }'
- re-enable a lambda by restoring its connection string:
- resume/enable/restart all applications which now write to target
if something goes wrong with one or more of the continuous oplog replays, causing some operations to be skipped, manually delete the initial dump folder (${dump_path}/init
) to force a new init dump and resync.