Skip to content

nethalo/dbsafe

Repository files navigation


dbsafe

🛡️ Know exactly what your MySQL DDL/DML will do before you run it

Latest Release Downloads License

No more surprises. Pre-execution safety analysis for MySQL DDL/DML operations.


✨ Highlights

  • 🔍 Algorithm detection — INSTANT / INPLACE / COPY, per MySQL version
  • 🎯 Risk classification — Safe, Caution, or Dangerous
  • 🌐 Topology aware — Galera/PXC, Group Replication, async replicas, Aurora, RDS
  • ☁️ AWS MySQL ready — Aurora MySQL, Amazon RDS (TLS support)
  • 📊 Impact estimation — table size, row count, replication lag
  • 📝 Chunked scripts — auto-generated batched DELETE/UPDATE for large operations
  • 🔁 Idempotent wrappers--idempotent generates a stored procedure with IF NOT EXISTS guards, safe to re-run
  • 🎨 Multiple formats — text, plain, JSON, Markdown (great for CI/CD)
  • Read-only — never modifies your data

📦 Installation

curl -sSfL https://raw.githubusercontent.com/nethalo/dbsafe/main/install.sh | sh -s -- -b /usr/local/bin

Or build from source (requires Go 1.23+):

git clone https://github.com/nethalo/dbsafe.git && cd dbsafe && make build

🚀 Quick Start

-- 1. Create a read-only MySQL user
CREATE USER 'dbsafe'@'%' IDENTIFIED BY '<password>';
GRANT SELECT, PROCESS, REPLICATION CLIENT ON *.* TO 'dbsafe'@'%';
# 2. Configure
dbsafe config init

# 3. Analyze
dbsafe plan "ALTER TABLE users ADD COLUMN email VARCHAR(255)"

💡 Examples

DDL analysis — INPLACE on a 1.2 GB table, recommends gh-ost or pt-osc:

dbsafe plan "ALTER TABLE orders ADD INDEX idx_created (created_at)"

DDL analysis: ADD INDEX on orders


CHANGE COLUMN — detects rename-only (INPLACE) vs type change (COPY) using live schema:

dbsafe plan "ALTER TABLE orders CHANGE COLUMN total_amount amount DECIMAL(14,4)"

CHANGE COLUMN: type change detected as COPY/DANGEROUS


DML with chunked script generation — safe batched deletes for large tables:

dbsafe plan "DELETE FROM audit_log WHERE created_at < '2025-06-01'"

DML analysis: chunked DELETE script


JSON output for CI/CD pipelines:

dbsafe plan --format json "ALTER TABLE customers DROP COLUMN phone" | jq .

JSON output for CI/CD


Idempotent wrapper — safe to re-run; outputs a stored procedure with IF NOT EXISTS guard:

dbsafe plan --idempotent "ALTER TABLE orders ADD COLUMN email VARCHAR(255)"

Idempotent SP wrapper


From a file:

dbsafe plan --file migration.sql

🐬 Supported Versions

Environment Support
MySQL 8.0.x
MySQL 8.4 LTS
Aurora MySQL 3.x (8.0 compat)
Amazon RDS MySQL 8.x
Percona XtraDB Cluster 8.x
Group Replication 8.x
MySQL 5.7 / MariaDB

☁️ AWS RDS and Aurora MySQL

dbsafe supports Amazon RDS and Aurora MySQL. Both require TLS:

# Amazon RDS (TLS required)
dbsafe plan --host mydb.rds.amazonaws.com --tls=required \
  "ALTER TABLE orders ADD COLUMN archived_at DATETIME"

# Aurora MySQL (auto-detected; gh-ost is replaced with pt-osc automatically)
dbsafe plan --host cluster.cluster-xyz.us-east-1.rds.amazonaws.com \
  --tls=required "ALTER TABLE users ADD INDEX idx_email (email)"

# Custom CA certificate (e.g., self-signed or private CA)
dbsafe plan --host mydb.example.com --tls=custom --tls-ca=/path/to/ca.pem \
  "ALTER TABLE events DROP COLUMN legacy_col"

TLS modes: disabled · preferred · required · skip-verify · custom

AWS tool compatibility:

Service gh-ost pt-osc
Amazon RDS ✅ (needs --allow-on-master --assume-rbr)
Aurora MySQL ❌ (incompatible — storage-layer replication)

Config file with TLS:

connections:
  default:
    host: mydb.rds.amazonaws.com
    port: 3306
    user: dbsafe
    database: myapp
    tls: required        # or: preferred, skip-verify, custom
    tls_ca: /path/ca.pem # only needed when tls: custom

Aurora privilegesREPLICATION CLIENT returns empty on Aurora; use PROCESS instead:

CREATE USER 'dbsafe'@'%' IDENTIFIED BY '<password>';
GRANT SELECT, PROCESS ON *.* TO 'dbsafe'@'%';

⚙️ Configuration

Location: ~/.dbsafe/config.yaml

connections:
  default:
    host: 127.0.0.1
    port: 3306
    user: dbsafe
    database: myapp

defaults:
  chunk_size: 10000
  format: text   # text | plain | json | markdown
dbsafe config init   # create interactively
dbsafe config show   # display current config

🧪 Testing

See TESTING.md for the full guide. Quick reference:

go test ./...                          # unit tests (~2s)
./scripts/run-integration-tests.sh    # integration tests with real MySQL
go test -bench=. -benchmem ./internal/...  # benchmarks

Integration tests verified against MySQL 8.0 standalone and MySQL 8.4 LTS. See TESTING.md for Apple Silicon / ARM64 container notes.


🤝 Contributing

  1. 🍴 Fork the repo
  2. 🌿 Create a feature branch
  3. ✅ Add tests
  4. 🚀 Submit a PR

📄 License

Apache 2.0 — see LICENSE.


Made with ☕ and ❤️ for safer database operations

⭐ Star on GitHub🐛 Report Bug💡 Request Feature

About

Pre-execution safety analysis for MySQL DDL/DML operations.

Topics

Resources

License

Stars

Watchers

Forks

Contributors