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 ```bash 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+): ```bash git clone https://github.com/nethalo/dbsafe.git && cd dbsafe && make build ``` --- ## ๐Ÿš€ Quick Start ```sql -- 1. Create a read-only MySQL user CREATE USER 'dbsafe'@'%' IDENTIFIED BY ''; GRANT SELECT, PROCESS, REPLICATION CLIENT ON *.* TO 'dbsafe'@'%'; ``` ```bash # 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: ```bash dbsafe plan "ALTER TABLE orders ADD INDEX idx_created (created_at)" ``` ![DDL analysis: ADD INDEX on orders](assets/dbsafe-add-index.png) --- **CHANGE COLUMN** โ€” detects rename-only (INPLACE) vs type change (COPY) using live schema: ```bash dbsafe plan "ALTER TABLE orders CHANGE COLUMN total_amount amount DECIMAL(14,4)" ``` ![CHANGE COLUMN: type change detected as COPY/DANGEROUS](assets/dbsafe-change-column.png) --- **DML with chunked script generation** โ€” safe batched deletes for large tables: ```bash dbsafe plan "DELETE FROM audit_log WHERE created_at < '2025-06-01'" ``` ![DML analysis: chunked DELETE script](assets/dbsafe-dml-chunked.png) --- **JSON output** for CI/CD pipelines: ```bash dbsafe plan --format json "ALTER TABLE customers DROP COLUMN phone" | jq . ``` ![JSON output for CI/CD](assets/dbsafe-json-output.png) --- **Idempotent wrapper** โ€” safe to re-run; outputs a stored procedure with IF NOT EXISTS guard: ```bash dbsafe plan --idempotent "ALTER TABLE orders ADD COLUMN email VARCHAR(255)" ``` ![Idempotent SP wrapper](assets/dbsafe-idempotent.png) --- **From a file:** ```bash 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: ```bash # 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**: ```yaml 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: ```sql CREATE USER 'dbsafe'@'%' IDENTIFIED BY ''; GRANT SELECT, PROCESS ON *.* TO 'dbsafe'@'%'; ``` --- ## โš™๏ธ Configuration Location: `~/.dbsafe/config.yaml` ```yaml connections: default: host: 127.0.0.1 port: 3306 user: dbsafe database: myapp defaults: chunk_size: 10000 format: text # text | plain | json | markdown ``` ```bash dbsafe config init # create interactively dbsafe config show # display current config ``` --- ## ๐Ÿงช Testing See [TESTING.md](TESTING.md) for the full guide. Quick reference: ```bash 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](LICENSE). ---

Made with โ˜• and โค๏ธ for safer database operations

โญ Star on GitHub โ€ข ๐Ÿ› Report Bug โ€ข ๐Ÿ’ก Request Feature