DBA Brain
A database operations toolkit for people who are on call.
Health metrics from SQL Server, Oracle, PostgreSQL and MySQL, graded against policies you write. Backups proven by restoring them. Told to you on a schedule, without an agent on any monitored machine.
pip install dbabrain
{
"success": true,
"operation": "restore-full",
"message": "Restored SALESDB_STG to
2026-08-07 01:40:00.",
"error": null,
"data": { },
"metrics": { "duration_ms": 41230 }
}
Graded verdicts, not raw rows
DBA Brain collects health metrics from your SQL Server, Oracle, PostgreSQL and MySQL instances, grades them against policies you write, runs your scheduled SQL, takes backups and proves them by restoring them, checks objectives against real measurement history, and tells you about it, on a schedule, without an agent on any monitored machine.
It sends nothing anywhere by itself. No telemetry, no usage reporting, no update check. It connects to the databases and hosts you list, and, only if you turn it on, to a chat service. Nothing else.
Health metrics
Around ninety metrics across four engines: availability, capacity, performance, recoverability, security, maintenance. Collected and normalised into one shape.
Graded, not dumped
Every measurement is graded against a policy you wrote. You read a verdict (OK, WARNING, CRITICAL) and pull the evidence only for what came back bad.
Backups proven by restore
Runs backups, restores them onto a disposable target, verifies the result and records what was proven and when. The restore is the proof.
Scheduled SQL
Your own SQL, on a schedule or on request, against approved targets, delivered as text or a spreadsheet. The SQL is a reviewable file, never a string in config.
Reports
Fleet inventory, per-server metrics, index usage and SLA pages, with a freshness gate so a stale number is never reported as a current one.
SLA / SLO
Indicators computed from stored measurement history, objectives evaluated with an error budget, and how much of it is left.
Alerts and chat commands
Telegram delivery, one message at a time. Commands people send back are gated by the person's clearance and the chat's.
Config as code
Every decision is a JSON file you keep in version control. A threshold change is a diff and a review, not an edit to somebody's script.
Secrets kept encrypted
PBKDF2-HMAC-SHA256 + Fernet. The passphrase is supplied at run time and never written to disk, a log or the store. Passwords travel on stdin, never argv.
What it is not
Not an AI agent
It is what an agent operates. Nothing here talks to a model or decides anything on its own.
Not a dashboard product
The primary interface is a CLI; the primary output is a record in a database you own.
Installs nothing on your databases
No agent, no extension, no stored procedure. It logs in with a read-only account and asks questions.
What it produces
Real report pages from a live estate, with every name replaced by a stable fake one. Click an image to open it full size.
One run, end to end
Whoever starts it (the daemon, a person, a chat command or an AI agent), a run takes the same path.
The app hands one JSON request to transport, which starts the shared operations CLI;
that CLI reaches the database or host and answers with one JSON envelope. Results land in the
runtime store, and reports and alerts are built from there.
Every command answers in the same envelope, whether the work succeeded or not:
{
"success": true,
"operation": "restore-full",
"message": "Restored SALESDB_STG to 2026-08-07 01:40:00.",
"error": null,
"data": { },
"metrics": { "duration_ms": 41230 }
}From a measurement to an alert
data/*.jsonA backup is proven by restoring it
Why: cheap for an AI agent, fine without one
The command a person runs is byte-for-byte the command an agent runs, so there is one code path to audit, and every run is logged the same way whoever started it.
WITHOUT a tool WITH DBA Brain
agent -> raw SQL -> agent agent -> DBA Brain -> database
"check this database" "check this database"
-> SELECT ... dm_os_wait_stats -> one JSON request
<- every row, into the context
-> SELECT ... sys.databases <- one graded envelope:
<- every row, into the context 41 checks, 40 OK,
-> ... once per check, per run 1 WARNING: appdb
<- all of it, healthy or not log backup 31h oldThe saving is not compression. It is not sending what nobody needed to read. And no model is required: remove the agent and the daemon, schedules, reports and alerts all still run.
A backup that outlives the host it came from
A backup kept on the database host is lost together with it. A dead disk takes the database and every backup written next to it, so a backup on the same disk as the database is one of the biggest holes there is. A lost host, or any other failure of that machine, takes every disk it has. Ransomware goes further: it encrypts every drive and every share the infected host can write to.
DBA Brain proves every backup at each step and keeps a proven copy away from the database host.
Solid boxes: done in 0.33.0. Dashed boxes: in progress. "partly": the step below says what is still being built.
Each backup run, step by step
FULL, DIFF and LOG backups for SQL Server; a base backup plus WAL for PostgreSQL; RMAN for Oracle.
1Back up, verified by the engine
SQL Server RESTORE VERIFYONLY WITH CHECKSUM, PostgreSQL pg_verifybackup, Oracle RMAN VALIDATE.
2Hash at the source
SHA-256 and size in bytes, taken on the database host when the backup ends and stored in the catalog on another host. The first hash can never be changed, not even by a direct UPDATE: a database trigger refuses it.
3Check it again later
Re-hash the file on the source and compare with the stored hash: an encrypted or altered file shows CHANGED, a vanished one MISSING.
verify-backup-filesIn progress on every cycle
4Copy to the repository
A shared folder or another VM, outside the database host. Hash before and after, compare checksum and bytes, copy again on a mismatch up to copy_max_retry; every attempt is recorded.
In progress the copy after every backup run
5Scan the copy
ClamAV, plus ransomware markers: ransom notes, locked-file extensions, a canary file. An infected copy is quarantined and reported CRITICAL; the source is never deleted.
6Mark the copy verified
Checksum, bytes and scan all pass. Only then may the source be deleted on the database server: a switch per entry, off by default, and never on a copy command's exit code alone.
7Restore drills
Daily, weekly or monthly, on an independent VM, only from verified copies: the chain is checked (FULL → DIFF → LOG, base backup + WAL), restored, and the databases opened, queried and checked for consistency. The run, its result and every file it used are recorded.
In progress reading from the repository, drill tiers, consistency checks on every engine
8History and reports
Per server, database and file: which files were backed up, copied, verified, scanned, and used by which drill with what result.
In progress coverage and success rates
Configuration
Every field is mandatory, so nothing is left to a default nobody wrote down.
upgrade-config adds them to existing entries with the values that keep today's flow:
offload_enabled: false, offload_scan: "none",
offload_delete_source: false, restore_from: "server".
{
"backups": [
{
"backup_id": "APPDB_FULL",
"server_id": "db-server",
"jobs": [
{ "job": "database", "databases": ["APPDB", "SALESDB"], "all_databases": false },
{ "job": "log", "databases": [], "all_databases": true }
],
"offload_enabled": true,
"offload_server_id": "repository-vm",
"offload_folder": "/srv/backups/db-server",
"offload_copy_max_retry": 3,
"offload_scan": "clamav",
"offload_delete_source": false,
"offload_source_share": "",
"offload_source_username": "",
"offload_source_password_ref": ""
}
],
"restores": [
{ "id": "drill-vm-daily", "restore_from": "server" }
]
}An excerpt: the fields this flow adds. The rest of each entry is unchanged.
- A backup job names its databases as a list, or an empty list with
"all_databases": true. offload_*on a backup entry: the repository byserver_idand folder, the copy retries, the scan ("none"or"clamav") and whether the source may be deleted once the copy is verified.- A Windows source read over SMB also states
offload_source_share,offload_source_usernameandoffload_source_password_ref, the three together. - A restore entry states
restore_from:"server"or"repository". - In 0.33.0 these fields are written and checked. The copy, scan and delete they switch on are in progress, and
"restore_from": "repository"is refused until reading from the repository is built.
15 components
Ten apps, each doing one job with its own CLI and never importing another app, and five shared layers that every app stands on. The list is closed, and every component has exactly one reference doc.
Who may call whom
commonmay not be imported: it is only ever run as a CLI.libmay not run a CLI: it is only ever imported.- No app imports another app. No shared layer imports an app.
- Each rule has a guard test beside it, so the diagram describes what is true, not just what was intended.
Apps
03App command daemon
db_ops/jobs · db-ops daemonThe scheduler: runs each app on its own interval inside its allowed hours, skips one that is still running.
04Metrics engine
db_ops/metricsAround ninety metrics across four engines, collected and normalised into one shape.
05SQL task runner
db_ops/sql_tasksYour own SQL, on a schedule or on request, against approved targets, as text or a spreadsheet.
06Reports
db_ops/reportsScheduled reports and inventory pages, with a freshness gate against stale numbers.
07Chat delivery and commands
db_ops/telegramDelivers the outgoing queue and executes commands, gated by the person's and the chat's clearance.
08Backup / restore
db_ops/backup_restoreRuns backups, restores them onto a disposable target, verifies, and records what was proven.
09SLA / SLO compliance
db_ops/slaIndicators from stored measurement history, objectives with an error budget.
10SRE
db_ops/sreProvisions disposable lab databases for drills: single instances or small HA clusters, in Docker or on VMs.
11Control
db_ops/controlBuilds and deploys the toolkit to another node, and watches the toolkit itself.
12Web host
db_ops/webhostServes the rendered reports over HTTP and hosts the console. Publishes files, never generates them.
Shared layers
01Runtime store
db_ops/dbThe toolkit's own data: job runs, measurements, report state, delivery queue, restore history. SQLite to start, PostgreSQL later.
02Logging engine
db_ops/logging_opsScoped application logs, runtime logs, shared errors and daily archives.
13Common
db_ops/common · CLI onlyReaching a host, running SQL, moving a file, rotating a password. Every command takes one JSON object.
14Lib
db_ops/lib · import onlyPure rules: time windows, notify routing, severity, formatting. Imports nothing from the rest.
15Transport
db_ops/transportThe one client: starts common.cli and db.cli for every component. Imports only lib.
Get started
Python 3.12+. Each database driver is an extra, so you install only what you run. Published on PyPI via trusted publishing.
[postgres] | PostgreSQL, pure Python |
[mysql] | MySQL / MariaDB, pure Python |
[oracle] | Oracle, no client library needed for 12.1 and newer |
[mssql] | SQL Server, also needs Microsoft's ODBC driver |
[ssh], [winrm] | OS-level metrics on Linux / Windows hosts |
[all] | everything |
Install
python -m venv .venv .venv/bin/pip install 'dbabrain[postgres]'
Five-minute try-out with a throwaway PostgreSQL container
cd examples/postgres-quickstart docker compose up -d python -m db_ops.db.cli --config config.json init python -m db_ops.metrics.cli --config config.json collect --dry-run python -m db_ops.metrics.cli --config config.json collect python -m db_ops.metrics.cli --config config.json report
Read more
Donations and investment
DBA Brain is free, open source, and maintained by one person. If you would like to donate, sponsor the project, or talk about investment or partnership, please get in touch directly.
For bugs and feature requests, please use GitHub issues. For security problems, follow the security policy rather than email.

