Skip to content

nethalo/dbsafe

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

126 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

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 privileges β€” REPLICATION 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