Repository navigation
Releases: muandane/grizzle
Release list
v0.2.0 - Observability, Safety & Production Hardening
Overview
Grizzle v0.2.0 brings production-grade observability, high-concurrency safety guards, multi-tenant automation, hot-path engine performance improvements, and the official Grizzle GitHub Action for CI/CD pipelines.
🛡️ Lock Contention Pre-Flight & Gating
- Active Lock Contention Inspection: Queries
pg_locksandpg_stat_activityto detect long-running transactions and queries on target tables before executing DDL steps requiring strong table locks (AccessExclusiveLock,ShareUpdateExclusiveLock). - Advisory Warnings & Fail-on-Contention: Defaults to actionable advisory logs with conflicting PIDs, usernames, running queries, and durations. When
--fail-on-contentionis enabled, retries with exponential backoff up toLockTimeout, failing closed withLockContentionErrorif contention does not clear.
🌐 External Dev Database URL for Shadow Compilation
- Non-Privileged Production Users: Compile declarative shadow schemas against an external development database (
--dev-url/Options.DevDatabaseURL), eliminating the requirement forCREATE SCHEMAprivileges on restricted live target databases. - Fail-Closed Operator Guidance: When target database users lack schema creation privileges and no dev URL is configured, Grizzle returns actionable guidance citing
--dev-urlandGRANT CREATE ON DATABASEwith zero silent fallbacks.
📊 OpenTelemetry Observability & Zero-Lock Readiness Probes
- Dedicated
otelgrizzlePackage: Zero-dependency core with first-class OTel metrics ingithub.com/muandane/grizzle/otelgrizzle:migration_duration_seconds(Float64Histogram): labeled bydialectandstatus(applied,failed,noop).drift_detected(Int64Counter): counter for detected schema drift and hash mismatches.lock_wait_seconds(Float64Histogram): time spent acquiring database locks.
- Zero-Lock Readiness Probe (
grizzle.IsReady): High-throughput health/readiness probe for Kubernetes pods inspectinggrizzle_historywithout holding advisory locks, table mutations, or schema drift.
🔄 Composite Primary Key Keyset Backfill
-
$N$ -Column Composite Primary Keys: Generalizes expand/contract keyset pagination using SQL row-value comparisons(pk1, ..., pkN) > ($1, ..., $N)and tupleINbatches across PostgreSQL and SQLite. - Index Verification & Resumption: Verifies index ordering before keyset traversal begins and seamlessly resumes interrupted backfills without duplicating or skipping rows.
- 53% Allocation Reduction: Hoisted scan pointers and pre-allocated parameter builders boosted backfill throughput to 51,644 rows/sec.
🏢 Multi-Tenant Schema Patterns
- Dynamic Schema Discovery (
--target-schema-pattern): Automatically discovers and synchronizes PostgreSQL schemas matching LIKE patterns (e.g.tenant_%) in deterministic alphabetical order. - System & Internal Isolation: Automatically excludes PostgreSQL internal schemas (
pg_%,information_schema) and Grizzle shadow schemas (_grizzle%). Schema additions and removals participate inPlan.Hash()for drift protection.
⚡ Official Composite GitHub Action (action.yml)
- Native CI/CD Automation: Run
lint,check,plan,diff, andapplyin GitHub Actions workflows with zero Go toolchain overhead. - Fast Pre-Built Binaries: Automatically downloads native pre-compiled release binaries for Linux (amd64/arm64), macOS, and Windows in under 1 second.
- GitHub Workflow Annotations: Passes
--githubfor inline PR review annotations (::notice,::error).
🔍 Expanded Declarative SQL Linter
docs/LINTER_SPEC.md: Comprehensive review specification defining 80+ schema rules across table design, foreign keys, index hygiene, and security.- Initial Strict Rules: Shipped
L014(PrimaryKeyTypeAllowlist),L022(DisallowReservedKeywords),L044(RequireBooleanDefault),L047(DisallowDuplicateIndex), andL048(DisallowRedundantPrefixIndex) with--profile strictand.grizzle.yamlconfiguration.
🧪 Nix-Native Concurrency & Chaos Stress Testing
- Added automated chaos and concurrency scenarios in
test/scenarios/with registereddevenvcommands:scenario-race: 50 parallel goroutines verifying advisory locking and zero dirty state.scenario-contention: Pre-flight lock contention detection under simulated long-running queries.scenario-chaos: Mid-flight process termination and transaction rollback verification.
What's Changed (Pull Requests)
- feat(exec): external dev database URL for shadow compilation (#55) by @muandane in #55
- feat(exec): composite primary key keyset backfill (#56) by @muandane in #56
- feat(schema): multi-tenant schema patterns via pg_namespace discovery (#57) by @muandane in #57
- feat(exec): lock contention pre-flight with backoff retry (#58) by @muandane in #58
- feat(metrics): otelgrizzle metrics and zero-lock readiness probe (#59) by @muandane in #59
- feat(devenv): add nix-native test scenarios and benchmarks (#61) by @muandane in #61
- feat(ci): add official GitHub Action and update CHANGELOG for v0.2.0 (#63) by @muandane in #63
Full Changelog: v0.1.0...v0.2.0
Installation
GitHub Actions
- uses: actions/checkout@v7
- uses: muandane/grizzle@v0.2.0
with:
command: lint
schema: schema.sql
strict: trueGo CLI
go install github.com/muandane/grizzle/cmd/grizzle@v0.2.0Go Modules
go get github.com/muandane/grizzle@v0.2.0
go get github.com/muandane/grizzle/otelgrizzle@v0.2.0Pre-Built Binaries
Pre-built standalone binaries for Linux, macOS (Darwin), and Windows (amd64 / arm64) are available in the assets below. Verify integrity using checksums.txt.
v0.1.0 - General Availability
Grizzle v0.1.0 - General Availability (GA)
We are thrilled to announce the General Availability (GA) release of Grizzle v0.1.0 — declarative, zero-downtime database schema migrations for Go, PostgreSQL, and SQLite.
Grizzle replaces error-prone sequential migration scripts with declarative schema management: you declare your desired schema in standard SQL, and Grizzle computes minimal, ordered, and safe DDL migration plans to transition your database to the target state.
Key Highlights
🎯 Declarative Schema Migrations
- Single Source of Truth: Define your desired schema using clean SQL declarations (
CREATE TABLE,CREATE INDEX,CREATE TYPE, etc.). - Diff-Driven Execution: Grizzle reverse-engineers the live database catalog, diffs it against your desired schema, and plans the precise topological sequence of non-destructive mutations required.
- Frozen Plan Hashing: SHA-256 plan digests (
Plan.Hash()) guarantee migration determinism, drift protection, and tamper verification.
🛡️ Production & Zero-Downtime Safety
- Non-Blocking Indexing: Automated
CREATE INDEX CONCURRENTLYin PostgreSQL and safe 12-step rebuilds in SQLite. Interrupted builds automatically drop invalid indices (indisvalid=false) and rebuild cleanly. - PgBouncer & Connection Pooler Safety: Fast failover (<10ms) detection of transaction-pooling / PgBouncer environments to prevent advisory lock hanging.
- Deadlock & Block Avoidance: Enforces statement and lock timeouts (
statement_timeout,lock_timeout) across all transactional steps. - Crash Recovery & Prior-Failure Gating: Stale table cleanup (
_grizzle_new_*,_grizzle_tmp_*) and fail-closed boot protection (ErrPriorFailureBlocked) with operational escape hatches (grizzle repair,WithAllowResumePartial).
📦 Multi-Format Migration Exporters
Export declarative plans to static migration files compatible with existing migration runners:
golang-migrate(--format migrate/--format golang-migrate): Paired companion artifacts ({timestamp}_{name}.up.sqland{timestamp}_{name}.down.sql) with automatic reverse-down generation.goose(--format goose): Single-file-- +goose Up/-- +goose Downscripts.atlas(--format atlas): Atlas-compatible directory format.- Standard SQL (
--format sql): Raw up/down SQL files.
🗄️ Comprehensive Database Object Coverage
- PostgreSQL:
- Tables, columns, generated columns, defaults, check constraints, foreign keys.
- Custom types: Enums (with safe in-place values and renames), composite types (
ALTER TYPE ... ATTRIBUTE), and range types. - Views, materialized views, triggers, and PL/pgSQL functions.
- Standalone and owned sequences (
INCREMENT BY,MINVALUE,MAXVALUE,CYCLE,OWNED BY). - Row Level Security (RLS) policies and PostgreSQL role grants.
- Multi-schema targeting and schema qualify rewrites (
TargetSchemas).
- SQLite:
- Embedded SQLite support with foreign-key preservation and transaction-safe table rebuilds.
- Attached database support.
🛠️ Operational CLI Lifecycle
grizzle status: Detailed synchronization report and history summary (human-readable and--json).grizzle history: Audit recorded migrations with sort and limit controls.grizzle baseline: Baseline pre-existing production databases without executing DDL.grizzle repair: Mark interrupted or failed migrations as resolved with operator notes.grizzle dump: Reverse-engineer live database catalogs into canonical DDL.grizzle lint: Static DDL linter with configurable safety rules and inline directive suppression (-- grizzle:lint-ignore).
🔌 In-Process Boot Auto-Migration & Observability
- Embeddable Go library (
grizzle.Sync(ctx, db, opts...)) for zero-ops service boots. - OpenTelemetry instrumentation package:
github.com/muandane/grizzle/otelgrizzlefor distributed traces across DDL planning and execution phases.
What's Changed in v0.1.0 (Since v0.1.0-rc5)
- feat(export): Added
golang-migrateexport format with paired.up.sqland.down.sqlartifacts (#54). - feat(postgres): Added fast detection of transaction pooling (PgBouncer) during advisory lock acquisition (
ErrTransactionPooling). - test(plan): Frozen
Plan.Hash()contract and added comprehensive golden tests covering all 71ChangeTypestep kinds. - test(failover): Added SQLite stale rebuild cleanup and enriched
ErrPriorFailureBlockedoperator guidance. - test(api): Audited root package boundaries to ensure zero internal type leaks and preserved
Options.TargetSchemabackward compatibility. - ci(matrix): Fully certified against PostgreSQL 14, 15, 16, 17, and 18 multi-version test matrix.
Installation
Go CLI
go install github.com/muandane/grizzle/cmd/grizzle@v0.1.0Go Library
go get github.com/muandane/grizzle@v0.1.0
go get github.com/muandane/grizzle/otelgrizzle@v0.1.0Pre-Built Binaries
Pre-built binaries for Linux, macOS (Darwin), and Windows (amd64 / arm64) are available in the assets below.
Verify integrity using checksums.txt.
v0.1.0-rc5
Changelog
- ec87caf fix(postgres): rewrite target schema qualifiers in single-schema shadow compilation
v0.1.0-rc4
Changelog
- a65669c chore(release): prepare v0.1.0-rc4
- 8a99732 feat(lifecycle): implement operational lifecycle, onboarding tooling, and developer ergonomics (#53)
- d1964ba feat(sync): harden in-process auto-migration boot path and test suite (#52)
- dd019f7 fix(ci): stabilize warm boot latency check and polish readme
v0.1.0-rc3
Changelog
- 29a84e8 Fix DBA review issues (#43)
- 6e62e58 Merge pull request #28 from muandane/chore/goreleaser-formats
- 089c84e chore(goreleaser): rename archives.format to formats
- 425d532 chore(release): prepare v0.1.0-rc3
- 8bc8f49 feat(postgres): manage owned sequences and standalone CREATE SEQUENCE (#29)
- ad8a183 feat: expression normalization to cut false diffs (#30) and ALTER POLICY role evolution (#33)
- ff90df7 feat: function signature ordering (#40), SQLite parity lint (#42), and SeedSQL idempotency (#32)
- 6500ef2 feat: shadow compile error hints, static lint rules, and ALTER POLICY drift
- a58d045 feat: user-defined types (range, composite, enum renames) and partition hazard polish (#37, #38, #39, #41)
- 36355b2 fix(schema): gate index header and predicate normalization on index definitions
- 4fc77f5 fix: remediate delegated review findings across P0-P3
- c99e78b refactor: apply modern Go ergonomics and address code review findings
- 7dd683d test(bench): expand benchmark suite and fix testing.TB context initialization
v0.1.0-rc2 — Managed surface + RolesSQL/CatalogSQL
Grizzle v0.1.0-rc2
Second release candidate — managed-surface parity plus RolesSQL / CatalogSQL side-channel contracts.
Full changelog:
CHANGELOG.md· Docs: README · SAFETY · SPEC
Highlights
| Area | What shipped |
|---|---|
| Managed surface | Extensions, RLS/policies, functions, procedures, aggregates, triggers, views/matviews, domains, and COMMENT ON are now declarative (diff + apply), not just protected |
| RolesSQL | CREATE ROLE / GRANT side-channel (--roles / Options.RolesSQL); marker-narrow drops; AllowRevoke / AllowDropRole |
| CatalogSQL | Publications + event triggers (--catalog / Options.CatalogSQL); marker-narrow drops |
| SQLite | Named/inline CHECK constraints introspected, emitted on rebuild, and diffed (AllowDropCheck) |
| Safety / plan | Stricter Plan.Hash(); lock/shadow identity no longer in plan artifacts; DryRunVerifyPlan; GENERATED_REWRITE is CRITICAL |
Breaking changes (from rc.1)
- Plan hash format —
Plan.Hash()now includesDropPolicy,NonConcurrentIndexes, andSchemaSQL. Previously approved plan artifacts failExpectedHash/ envelope checks (ErrPlanDrift). Re-plan and re-approve. - Plan artifact shape —
lock_id,lock_namespace,shadow_schema, andoptions_digestare removed from the plan document. Lock identity is derived at apply time; shadow schemas are ephemeral per run. GENERATED_REWRITEis CRITICAL — generated-column rewrites require explicitAcceptHazards: GENERATED_REWRITE.- Former “protected” objects are managed — drifted views/triggers/functions/etc. now emit plan steps; live-only objects become drops gated by the new
AllowDrop*flags and hazard codes.
Notable additions
- COMMENT ON — table/column comments via
obj_description/col_description; clear emitsCOMMENT_CLEAR(NOTICE) - Procedures & aggregates — procedures like functions; aggregates reconstructed from
pg_aggregate(DROP+CREATE); shareAllowDropFunction+DROP_FUNCTION - Domains — base type / nullability / default / CHECK; retype is DROP+CREATE; live drops need
AllowDropDomain+DROP_DOMAIN - Extensions / RLS / functions / triggers / views — full declarative sync with corresponding
AllowDrop*gates - Lint L008 / L009 — RLS enabled without policies (WARNING); DML in
SchemaSQL(ERROR — useSeedSQL) DryRunVerifyPlan— dry-run an approved plan artifact with envelope + live re-diff; CLIapply --dry-run --plangrizzle.ErrHistoryRecord— typed non-fatal error when DDL applied but history write failed- Export Down — goose reversals for policy/RLS/function/trigger/view steps (extension create irreversible by design)
Side channels
# Privileges (PostgreSQL)
grizzle plan --schema schema.sql --roles roles.sql --out plan.json
grizzle apply --plan plan.json
# Cluster catalog: publications + event triggers (PostgreSQL)
grizzle plan --schema schema.sql --catalog catalog.sql --out plan.jsonSee examples/roles-grants/ and examples/catalog-sync/.
CLI at a glance
grizzle plan --schema schema.sql --out plan.json
grizzle apply --plan plan.json [--accept-hazard CODE ...]
grizzle check --schema schema.sql
grizzle lint --schema schema.sql # L001–L009
grizzle apply --dry-run --plan plan.json # envelope + live re-diffExit codes: 0 ok · 1 error · 2 hazard blocked · 3 plan drift · 4 schema drift
Tested engines
PostgreSQL 14–18 · SQLite (embedded)
Install
Download a binary below for your OS/arch, or:
go install github.com/muandane/grizzle/cmd/grizzle@v0.1.0-rc2Status
Pre-release (rc2). API may still shift before v0.1.0 final. Please file issues for regressions.
v0.1.0-rc.1 — First release candidate
Grizzle v0.1.0-rc.1
First public release candidate of Grizzle — a declarative schema migration engine for PostgreSQL and SQLite with hazard gating, plan approval, and multi-pod safety.
Full changelog:
CHANGELOG.md· Docs: README · SAFETY · SPEC
Highlights
| Area | What shipped |
|---|---|
| PostgreSQL | Multi-schema, partitions (RANGE/LIST/HASH), partial/functional indexes, generated columns, CHECK constraints (NOT VALID → VALIDATE), concurrent indexes |
| SQLite | 12-step rebuild with trigger/view preservation, keyset batch copy, savepoint FK checks |
| Safety | Default-deny drops, hazard gates (AcceptHazards), unmanaged dependency protection (views/triggers/functions), session advisory locks + retry |
| CLI | plan / apply / check / lint / seed / export (sql, goose, atlas) |
| DX | Dry-run sandbox, lifecycle hooks, idempotent seeds, expand/contract + --rename (experimental) |
CLI at a glance
grizzle plan --schema schema.sql --out plan.json
grizzle apply --plan plan.json [--accept-hazard CODE ...]
grizzle check --schema schema.sql # CI drift gate
grizzle lint --schema schema.sql # L001–L007
grizzle apply --dry-run # live rollback sandbox
grizzle seed --seed seed.sqlExit codes: 0 ok · 1 error · 2 hazard blocked · 3 plan drift · 4 schema drift
Notable features in this RC
- Declarative CHECK constraints (Postgres) — staged like FKs; drops gated by
AllowDropCheck - Schema lint L001–L007 — including CHECK naming / duplicates / anonymous names
- Unmanaged fidelity — function/procedure deps via
pg_depend+ remediation hints - ZDM CLI —
--expand-contract, repeatable--rename old=new(seeexamples/expand-contract) - Dry-run, hooks, seed, lock retry — production-oriented apply path
Tested engines
PostgreSQL 14–18 · SQLite (embedded)
Install
Download a binary below for your OS/arch, or:
go install github.com/muandane/grizzle/cmd/grizzle@v0.1.0-rc.1Breaking notes (vs early prototypes)
- Module path is
github.com/muandane/grizzle Options.ExpectedHashremoved — pass approval hash viaApplyOpts.ExpectedHash
Status
Pre-release (rc.1). API may still shift before v0.1.0 final. Please file issues for regressions.