DBTrail

In production

The whole setup as a file and a few commands, with no clicks, so you can put it in your automation and run it again.

The same result as the Quick Start, written as configuration: one .env file and six API calls you can keep in a script. The web interface stays available for looking, not needed for setting up.

1. Start DBTrail with a token

mkdir dbtrail && cd dbtrail
curl -fsSL -o docker-compose.yml https://raw.githubusercontent.com/dbtrail/dbtrail/main/docker-compose.yml
echo "CONSOLE_TOKEN=$(openssl rand -hex 24)" > .env
docker compose up -d

The token is the key for every call below. Keep it in your secrets store.

export TOKEN=$(grep CONSOLE_TOKEN .env | cut -d= -f2)
export API=http://127.0.0.1:8090/api

2. Create DBTrail's user on your MySQL

CREATE USER 'dbtrail'@'%' IDENTIFIED BY '<a password>';
GRANT REPLICATION SLAVE, REPLICATION CLIENT, SELECT ON *.* TO 'dbtrail'@'%';
GRANT RELOAD, BACKUP_ADMIN, SHOW VIEW ON *.* TO 'dbtrail'@'%';

3. Connect your MySQL

curl -s -X POST -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  $API/servers/check -d '{
    "flavor": "mysql", "name": "",
    "source_host": "<your MySQL host>", "source_port": "3306",
    "source_user": "dbtrail", "source_password": "<a password>"}'

It runs the same checks as the web form and starts capture when they pass: "ok": true. Each failed check comes back with its fix. A MySQL on the same machine is host.docker.internal.

export ID=$(curl -s -H "Authorization: Bearer $TOKEN" $API/servers | jq -r '.servers[0].id')

4. Take the first copy, and keep it current

curl -s -X POST -H "Authorization: Bearer $TOKEN" $API/servers/$ID/baseline
curl -s -X PUT  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  $API/servers/$ID/backup-schedule -d '{"every": "1h"}'

The first reads every table once, with a short lock, so run it at a quiet time. The second updates the copy every hour from the recorded changes, without reading your MySQL again.

5. Turn on the MySQL port

curl -s -X PUT -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  $API/flashback -d '{"enabled": true}' | jq -r .password

Keep the password it prints: it is shown only now. A new one: curl -s -X POST -H "Authorization: Bearer $TOKEN" $API/flashback/password. The port takes a new password a few seconds after it is made.

6. Name the server and connect your application

Your application keeps its SQL when routing is on: what the copy cannot answer goes to your MySQL, as a user with your application's grants.

-- on your MySQL
CREATE USER 'shop_fwd'@'%' IDENTIFIED BY '<another password>';
GRANT SELECT ON shop.* TO 'shop_fwd'@'%';
curl -s -X PUT -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  $API/servers/$ID -d '{"name": "shop", "route_user": "shop_fwd", "route_password": "<another password>"}'
curl -s -X PUT -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  $API/flashback -d '{"routing": true}'
You should see
mysql -h <DBTrail host> -P 3309 -u shop -p

SHOW ROUTER STATUS; answers, and heavy queries come back from the copy.

Upgrades: Upgrade. Day-to-day health: Status and Alerts.

On this page