cockroachdb/cockroach
Migration context
CockroachDB ships rolling upgrades. The system is in a constantly partial state: at any time, some clusters are mid-upgrade, some are pinned to a past version, and some are running the upgrade-in-progress migration jobs. Several long-running migrations dominate this story today.
In-progress and recent migrations
Schema-changer migration
The repo currently contains both the legacy schema changer (pkg/sql/schema_changer.go) and the declarative one (pkg/sql/schemachanger/). Statements gradually move from the legacy to the declarative path; the cluster-version constants in pkg/clusterversion/cockroach_versions.go gate when each new statement uses the declarative path. As of recent commits a document inside pkg/sql/ describes both architectures explicitly.
Store-liveness leases
Replacing epoch-based leases (pkg/kv/kvserver/liveness/) with store-liveness leases (pkg/kv/kvserver/storeliveness/, pkg/raft/raftstoreliveness/) is staged. Mixed clusters can have a mix of lease types per range; the replicate_queue and lease_queue cooperate to upgrade ranges as soon as it is safe.
Disaggregated storage
pkg/storage/shared_storage.go and pkg/cloud/ are introducing shared object storage as a backing for L5/L6 SSTs. The migration is opt-in per store; the engine ratchets through a Pebble format-major version when shared storage is enabled.
Span config v2
The reconciler (pkg/spanconfig/spanconfigreconciler/) replaced gossip-based system-config delivery years ago, but the per-tenant story continues to evolve as new descriptor types (functions, schedules, types) are added.
LDR (logical replication)
pkg/crosscluster/logical/ is in active development. New features land behind cluster-version gates so older standby tenants do not crash on new event types.
Constraints every migration respects
- Idempotent — a migration must be safe to retry. A node crash mid-migration must not leave broken state.
- Resumable — progress is recorded in
system.migrations(pkg/upgrade/migrationstable/) so a successor can pick up. - Forward-compatible — old binaries must tolerate new wire fields (use
reservedand never reuse field tags). - Backward-incompatible only after a fence — once a feature is gated on
Vxx_yFoo, behavior may change afterVxx_yFoois active. Before that, the new code must be a no-op or behave like the old one.
Patterns
- New system table → add to bootstrap (
pkg/sql/catalog/bootstrap/), write a migration inpkg/upgrade/upgrades/to populate existing clusters, gate readers on the cluster version. - New SQL behavior → add a new cluster-version constant, wrap the new path in
if cv.IsActive(...), and write a logictest config that runs against the previous version too. - Wire-format change → introduce the new field, mark callers to skip it on old peers, and remove the old field only in a later release.
Where migrations live
pkg/upgrade/upgrades/— one Go file per migration, registered in the package'sinit().pkg/upgrade/migrationstable/— schema and helpers forsystem.migrations.pkg/upgrade/upgrademanager/— runs migrations in order.pkg/upgrade/upgradejob/— the job resumer that wraps a migration.
Related pages
- systems/cluster-version-and-upgrade — gating contract.
- lore — historical context for these migrations.
- How to contribute / patterns and conventions.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.