Skip to content

SQL schema operations

Run migrations as a deployment step when kernel replicas must start without applying versioned DDL. Use the same Chronicle Server build and storage configuration for the migration job and the replicas. These operations support PostgreSQL, SQL Server, and SQLite.

Run the server executable once with --migrate-only:

Terminal window
./Cratis.Chronicle.Server --migrate-only \
--event-store orders --namespace production

This process does not start Orleans, cluster membership, or HTTP listeners. It uses the configured Schema connection identity, creates missing databases and schemas only when Storage.CreateIfMissing permits it, and applies migrations under Chronicle’s existing per-database schema locks.

The operation visits:

  • The cluster database.
  • The System event store and its Default namespace.
  • Every registered event store and namespace, plus Default for each store.
  • Additional stores supplied with repeatable --event-store flags. Repeatable --namespace flags apply to each explicitly supplied store.
  • Namespace and jobs migrations, the event-log, system, outbox and shared named-tag tables, and existing sequence tables, including inboxes.
  • Read-model databases, without creating arbitrary read-model tables.

Explicit stores and namespaces are registered so subsequent kernel boots can discover them. Re-running the operation is supported. Applied migration identifiers unknown to the current build are reported but do not cause verification to fail.

For containers, set Cratis__Chronicle__Storage__SchemaAction=MigrateAndExit instead of passing --migrate-only. The command-line action takes precedence over the configured action.

Run a read-only schema probe:

Terminal window
./Cratis.Chronicle.Server --verify-schema \
--event-store orders --namespace production

Or set Cratis__Chronicle__Storage__SchemaAction=VerifyAndExit. Verification reads history and table metadata; it does not register stores, acquire schema migration locks, create databases or schemas, or apply migrations. It checks versioned EF schemas and the presence of well-known sequence tables, not future dynamically shaped read-model or constraint tables.

After a successful migration job, configure normal replicas with:

Terminal window
export Cratis__Chronicle__Storage__SchemaMode=Verify
./Cratis.Chronicle.Server

SchemaMode defaults to Migrate, preserving migration-on-access behavior. Verify disables database and schema creation regardless of CreateIfMissing. Before accepting traffic, startup checks the cluster, System event-store, Default namespace and jobs schemas. Later versioned-schema accesses also fail if migrations are pending, including jobs initialization. Dynamically shaped tables still use their existing per-table path; this is not a blanket DDL prohibition.

Do not set SchemaAction on normal replicas: any non-None action exits instead of running the server. MongoDB and InMemory schema actions are successful no-ops; normal startup warns when SchemaMode=Verify is configured for them.

CodeMeaning
0Migration completed, verification is current, or storage has no versioned schema.
2Verification found a missing database, schema, required table or pending migration.
3A database schema lock could not be acquired before its timeout.
4Configuration is invalid, or migration needs a database that creation policy does not permit Chronicle to create.
1An unexpected error occurred.

Structured logs identify the logical scope, database, pending migrations, elapsed time and final exit code. Correct the reported configuration or run the migration job before retrying; do not treat a timeout as success.

Use a Job ahead of the replica rollout. The referenced secrets must contain the appropriate Cratis__Chronicle__Storage__* environment variables. Use the same pinned server image for both resources; the image below illustrates the configuration.

apiVersion: batch/v1
kind: Job
metadata:
name: chronicle-migrate
spec:
backoffLimit: 0
template:
spec:
restartPolicy: Never
containers:
- name: migrate
image: cratis/chronicle:latest
args: ["--migrate-only", "--event-store", "orders", "--namespace", "production"]
envFrom:
- secretRef:
name: chronicle-schema-storage

Wait for this Job to complete successfully before rolling out replicas. A failed or timed-out Job must block the rollout. Each server container then uses the runtime storage configuration and Verify policy:

envFrom:
- secretRef:
name: chronicle-runtime-storage
env:
- name: Cratis__Chronicle__Storage__SchemaMode
value: Verify
- name: Cratis__Chronicle__Storage__SchemaAction
value: None

The runtime identity still needs permissions for Chronicle’s dynamic per-table operations. In Verify mode, these tables are still created when first used:

  • Event-sequence tables for sequences that did not exist when --migrate-only ran.
  • Unique-constraint tables.
  • Read-model tables, including the per-generation tables created when a projection is rebuilt.

Every other schema object comes from versioned migrations, which --migrate-only applies and Verify checks.

Replicas from the previous release keep running against the migrated schema during a rollout. They ignore migrations they do not know, so a rollout stays safe as long as each release only adds tables, columns and indexes. Keep schema connection resolution consistent with the storage connection resolution configuration.