dbtrail

Quick Start

Install the dbtrail console and start tracking your database changes in minutes

dbtrail: the MySQL backup you can query, powered by binary logs

dbtrail is an open-source (Apache-2.0) change-tracking and point-in-time recovery system. It tails your database's replication stream and keeps every row-level change (with full before/after images) in a searchable index, so you can query your entire history, generate precise undo SQL, and time-travel any row to any moment. The web console is the primary interface: you add servers, watch preflight checks pass, and browse changes without touching a terminal beyond the install.

It captures from MySQL and Percona Server 8.0 and 8.4 (including Amazon RDS, Aurora, and Google Cloud SQL), PostgreSQL 14+ (beta), and MariaDB 10.6+ (alpha).

Claude is the recommended interface for questions

The fastest way to ask things of dbtrail is Claude: natural language, no query syntax to learn. The console is fully featured and works without Claude; Claude is optional, not required. See Connect Claude.


Install

One line stands up the full stack (the web console, the capture control plane, and a bundled index MySQL) and opens the console when it's ready:

curl -fsSL https://raw.githubusercontent.com/dbtrail/dbtrail/main/install.sh | sh

Open http://127.0.0.1:8090. On first run the console asks you to create a username and password.

The stack bundles a MySQL 8.4 container as the index store; that index holds your forensic record, so back up its volumes. For every other install path (single binaries, .deb/.rpm packages, Docker images, bringing your own index MySQL, building from source), see the installation guide in the repository.


Prepare your MySQL source

Adding a PostgreSQL server instead? Its prerequisites are different. See PostgreSQL (Beta) and come back to Add your server.

Before connecting a MySQL server, make sure it's ready:

RequirementSQL checkExpected value
MySQL 8.0 or 8.4SELECT VERSION();8.0.x or 8.4.x
Binary logging enabledSHOW VARIABLES LIKE 'log_bin';ON
Row-based replicationSHOW VARIABLES LIKE 'binlog_format';ROW
Full row imagesSHOW VARIABLES LIKE 'binlog_row_image';FULL
InnoDB storage engineSee belowAll tracked tables use InnoDB
Primary key on every tableSee belowAll tracked tables have a primary key

The console checks all of this for you

The + Add server flow runs a full preflight (every check above, plus privileges and binlog retention) and turns anything that fails into a remediation card with the exact SQL to fix it. The tables below are for preparing ahead of time.

binlog_row_image must be FULL

This is the most commonly missed prerequisite. If binlog_row_image is set to MINIMAL or NOBLOB, dbtrail cannot capture complete before/after row data. Set it in your MySQL configuration:

[mysqld]
binlog_row_image = FULL

Create a dedicated MySQL user

Create a user with the minimum privileges dbtrail needs: replication access for binlog streaming and SELECT for schema snapshots (the + Add server form also spells this out, ready to copy):

CREATE USER 'bintrail'@'%' IDENTIFIED BY 'strong_password_here';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'bintrail'@'%';
GRANT SELECT ON *.* TO 'bintrail'@'%';

-- Needed only for base snapshots (point-in-time recovery, Time-travel).
-- Capture works without it; the snapshot is refused.
GRANT LOCK TABLES ON *.* TO 'bintrail'@'%';

On Amazon RDS and Aurora, grant the rds_replication role instead of REPLICATION SLAVE:

GRANT rds_replication TO 'bintrail'@'%';

Why LOCK TABLES, if dbtrail never locks your database?

Capture never does — it reads the binlog as a replica and touches nothing else. A base snapshot is different: it is a parallel logical dump, and it is point-consistent by default, meaning every worker thread opens its snapshot at the same instant. That guarantee needs a lock, held only for the moment the threads synchronize — not for the duration of the dump. Without it you would get a snapshot stitched from several moments: a database state that never actually existed, which every later point-in-time recovery would silently inherit.

Leave it out and nothing breaks quietly — capture runs normally and only the snapshot is refused, naming the exact GRANT to run.

On RDS and Aurora, also set the lock mode to lock-all (BINTRAIL_CONSOLE_BASELINE_LOCK_MODE=lock-all, or --lock-mode lock-all). The default mode needs BACKUP_ADMIN, which managed MySQL will not grant to anyone.

Use a strong, unique password

Replace strong_password_here with a strong password. If your MySQL server is not accessible from the public internet, you can restrict the host part (e.g., 'bintrail'@'10.0.%') instead of using '%'.


Add your server

In the console, click + Add server:

  1. Pick the source type: MySQL, PostgreSQL, or MariaDB.
  2. Paste the connection details (host, port, and the dedicated user you created above). Optionally restrict which schemas to track.
  3. Save. dbtrail runs the preflight (failures come back as remediation cards with copy-pasteable fixes), provisions a dedicated index database for the server, and starts a supervised stream; the badge goes RUNNING once the stream has proven it's attached and writing, and you'll see events within the minute.
The + Add server form: name, source type, host, port, user, password and schemas fields, with the CREATE USER and GRANT statements ready to copy.

Monitoring survives restarts: the daemon resumes every stream from its saved checkpoint. Unhealthy streams surface as explicit states (STALLED, FAILED, LOST POSITION) instead of failing silently.


Verify it works

Make a test change to confirm dbtrail is capturing events:

CREATE DATABASE IF NOT EXISTS dbtrail_test;
CREATE TABLE IF NOT EXISTS dbtrail_test.ping (
  id INT PRIMARY KEY,
  ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO dbtrail_test.ping (id) VALUES (1);

Wait 30 seconds for the change to be indexed. The INSERT appears in the recent-changes list on the console's Overview, and the Events screen lets you filter by schema and table, and export what's on screen as JSON or CSV.

The Events screen listing indexed row events with time, table, type badge, primary key and changed columns, plus search, filters and JSON/CSV export.

Clean up the test table when you're done:

DROP DATABASE dbtrail_test;

No changes appearing?

If nothing shows up after 60 seconds, check that the stream is running in the console's Status view, and that the MySQL user has SELECT and REPLICATION privileges. See Troubleshooting for common issues.


Connect Claude

The console serves your change history to Claude (or any MCP client) through read-only tools: query, recover (always dry-run: the AI never executes SQL), status, and list_schema_changes. Open Settings → Connect AI in the console. It shows your MCP URL, and for Claude Desktop a one-click bundle. See Connect Claude for every client (Claude Desktop, claude.ai, Claude Code, Cursor).

Once connected, ask Claude anything about your database changes:

"Show me recent changes in dbtrail_test"

Claude querying dbtrail via MCP, showing recent changes with event counts and table breakdown

Prefer the terminal?

Everything above (and everything the console does) is also available from the bintrail CLI for headless and scripted deployments. The CLI is documented in the repository:


Next steps

On this page