Skip to content

Database Management

HoloMUSH uses PostgreSQL as its primary data store. This guide covers database setup, migrations, and maintenance.

  • PostgreSQL 18 or later
  • A database user with CREATE privileges
  • The pg_trgm extension (for fuzzy search)

HoloMUSH uses golang-migrate for schema management. Migrations are embedded in the binary and run automatically on startup, or can be managed manually.

Terminal window
# Apply all pending migrations
holomush migrate up
# Preview migrations without executing
holomush migrate up --dry-run
# Check current migration status
holomush migrate status
# Rollback one migration
holomush migrate down
# Force version (for dirty state recovery)
holomush migrate force 7

By default, HoloMUSH runs migrations automatically on startup. This can be controlled with environment variables:

Terminal window
# Disable automatic migrations
HOLOMUSH_DB_AUTO_MIGRATE=false
# Run migrations manually
holomush migrate up

For creating new migration files, see the Contributing Guide.

If migrating from an older HoloMUSH version with an existing schema:

Terminal window
psql -d holomush -f scripts/bootstrap-migrations.sql

This marks all migrations as applied without running them.

Configure the database connection via environment variables:

VariableDescriptionDefault
DATABASE_URLFull PostgreSQL connection URLRequired

Example connection URL:

Terminal window
DATABASE_URL="postgres://holomush:secret@localhost:5432/holomush?sslmode=require"
Terminal window
# Full database dump
pg_dump -Fc holomush > holomush_$(date +%Y%m%d_%H%M%S).dump
# Schema only
pg_dump -Fc --schema-only holomush > holomush_schema.dump
# Data only
pg_dump -Fc --data-only holomush > holomush_data.dump
Terminal window
# Restore full backup
pg_restore -d holomush holomush_backup.dump
# Restore to new database
createdb holomush_restored
pg_restore -d holomush_restored holomush_backup.dump

If a migration fails partway through, the database may be in a “dirty” state:

Terminal window
# Check current state
holomush migrate status
# If dirty, fix manually then force version
holomush migrate force 6

Check PostgreSQL is running and accessible:

Terminal window
psql $DATABASE_URL -c "SELECT 1"

Verify the pg_trgm extension is available:

CREATE EXTENSION IF NOT EXISTS pg_trgm;

Migration commands return structured error codes to help diagnose issues.

CodeMeaningCommon CausesRemediation
MIGRATION_SOURCE_FAILEDFailed to read embedded migration filesCorrupted binary, missing migrationsRebuild the binary
MIGRATION_INIT_FAILEDFailed to connect to database for migrationsInvalid DATABASE_URL, database offlineCheck connection string, verify PostgreSQL is running
MIGRATION_UP_FAILEDFailed to apply pending migrationsSQL syntax error, constraint violation, dirty stateCheck migration SQL, resolve conflicts, use migrate force if dirty
MIGRATION_DOWN_FAILEDFailed to rollback migrationsSQL error in down migration, missing tableCheck down migration SQL, verify schema state
MIGRATION_STEPS_FAILEDFailed to apply/rollback specific stepsSame as UP/DOWN errorsCheck specific migration file
MIGRATION_VERSION_FAILEDFailed to read current versionDatabase connection lost, schema_migrations missingCheck connection, run bootstrap if needed
MIGRATION_FORCE_FAILEDFailed to force-set versionDatabase connection lostCheck connection
MIGRATION_CLOSE_FAILEDFailed to close migrator cleanlyConnection already closedUsually safe to ignore
CodeMeaningCommon CausesRemediation
MIGRATION_VERSION_CHECK_FAILEDMigration applied but version check failedDatabase connection dropped during operationRun migrate status to verify actual state
CONFIG_INVALIDMissing required configurationDATABASE_URL not setSet DATABASE_URL environment variable
INVALID_VERSIONInvalid version number for force commandNon-integer input, negative numberUse positive integer (e.g., migrate force 6)

Errors include context to help diagnose issues:

MIGRATION_UP_FAILED: migration failed
operation: apply migration 7
error: pq: relation "objects" already exists

The nested context shows:

  • Error code: Quick identification of failure type
  • Operation: What the system was trying to do
  • Error: Underlying database or system error