system-table-change
System Table Schema Change Checklist
When adding, removing, or modifying columns or indexes on a system table, multiple files and golden test artifacts must be updated in lockstep. Missing any of these causes test failures that can be confusing to debug.
1. Schema Definition
Update the table's schema string and descriptor literal in:
pkg/sql/catalog/systemschema/system.go- The
CREATE TABLEschema string (e.g.,StatementDiagnosticsRequestsTableSchema) - The descriptor literal (e.g.,
StatementDiagnosticsRequestsTable): columns, column IDs, family column names/IDs, index store column names/IDs,NextColumnID NextColumnIDmust be max(column IDs) + 1- When adding/removing columns, update both
ColumnNamesandColumnIDsin the family descriptor - If the column should be stored in a secondary index, update both the schema string's
STORINGclause and the descriptor literal'sStoreColumnNames/StoreColumnIDs
- The
2. New Table Registration (skip if modifying existing table)
If creating a brand new system table, register it in these additional files:
-
pkg/sql/sem/catconstants/constants.go- Add a SystemTableName constant for the new table
-
pkg/sql/catalog/catprivilege/system.go- Register privileges (read-write, read-only, etc.) for the table
-
pkg/sql/catalog/bootstrap/metadata.go- Add the table descriptor to the bootstrap metadata
-
pkg/backup/system_schema.go- Define backup/restore behavior for the table
-
pkg/cli/zip_table_registry.go- Decide whether the table should be included in
cockroach debug zipoutput and register it if so
- Decide whether the table should be included in
3. Version Gate
-
pkg/clusterversion/cockroach_versions.go- Add a new version constant (e.g.,
V26_2_MyChange) - Add the version mapping in
versionTable(must use evenInternalvalues, incrementing by 2)
- Add a new version constant (e.g.,
-
pkg/sql/catalog/systemschema/system.go- Update
SystemDatabaseSchemaBootstrapVersionto your new version constant
- Update
4. Migration
pkg/upgrade/upgrades/- Create a migration file (e.g.,
v26_2_my_change.go). For new tables, this usesCREATE TABLE. For existing tables, this usesALTER TABLE/CREATE INDEX. - Create a migration test file (e.g.,
v26_2_my_change_test.go) with the old descriptor and validation - Register the migration in
upgrades.go - Add the old table descriptor constructor to
schema_changes.goif needed (existing tables only) - Update
helpers_test.goif adding new helper functions - Run
./dev gen bazelif adding new files
- Create a migration file (e.g.,
5. Golden Files (must regenerate, not manually edit)
These files contain serialized representations of the schema and must be regenerated after schema changes. Update hashes first, then run tests with --rewrite.
Bootstrap test data
pkg/sql/catalog/bootstrap/testdata/testdata- Contains
system hash=<sha256>andtenant hash=<sha256>followed by KV data - Update pattern: Run the test once, grep for "Unexpected hash" in the output to get both new hashes, update both hashes in the file, then re-run with
--rewriteto regenerate the KV data - Test:
./dev test pkg/sql/catalog/bootstrap -f TestInitialValuesToString -v --rewrite
- Contains
Bootstrap schema golden files
pkg/sql/catalog/systemschema_test/testdata/bootstrap_systempkg/sql/catalog/systemschema_test/testdata/bootstrap_tenant- Contain SQL schema output and JSON descriptor blobs
- Test:
./dev test pkg/sql/catalog/systemschema_test -f TestValidateSystemSchemaAfterBootStrap -v --rewrite
Logic test golden files
pkg/sql/logictest/testdata/logic_test/pg_catalog— pg_catalog column metadatapkg/sql/logictest/testdata/logic_test/crdb_internal_catalog— internal catalog metadata- Test:
./dev testlogic --files=pg_catalog --rewrite - Test:
./dev testlogic --files=crdb_internal_catalog --rewrite
- Test:
Initial bootstrap keys and catalog cache test data
-
pkg/sql/tests/testdata/initial_keys— initial bootstrap keys- Test:
./dev test pkg/sql/tests -f TestInitialKeys -v --rewrite
- Test:
-
pkg/sql/catalog/internal/catkv/testdata/testdata_app— catalog cache test data for app tenant -
pkg/sql/catalog/internal/catkv/testdata/testdata_system— catalog cache test data for system tenant- Test:
./dev test pkg/sql/catalog/internal/catkv -v --rewrite
- Test:
Additional golden files for new tables
When adding a new system table, these additional golden files may need regeneration:
-
pkg/sql/logictest/testdata/logic_test/information_schema— information_schema metadata- Test:
./dev testlogic --files=information_schema --rewrite
- Test:
-
pkg/sql/logictest/testdata/logic_test/system— system table tests- Test:
./dev testlogic --files=system --rewrite
- Test:
-
pkg/cli/testdata/doctor/test_examine_cluster*— cluster doctor examination test data- Test:
./dev test pkg/cli -f TestDoctor -v --rewrite
- Test:
-
pkg/ccl/spanconfigccl/spanconfigreconcilerccl/testdata/— span config reconciler test data- Test:
./dev test pkg/ccl/spanconfigccl/spanconfigreconcilerccl -v --rewrite
- Test:
Previous-release bootstrap data (only if changing an existing release's schema)
pkg/sql/catalog/bootstrap/data/{version}_system.keyspkg/sql/catalog/bootstrap/data/{version}_system.sha256pkg/sql/catalog/bootstrap/data/{version}_tenant.keyspkg/sql/catalog/bootstrap/data/{version}_tenant.sha256- These are for hardcoded previous release versions, NOT the current
Latest - Only need updating if you're modifying a released schema (rare)
- These are for hardcoded previous release versions, NOT the current
6. Documentation
Adding a version constant changes the version cluster setting's default value, which is reflected in generated settings docs. Regenerate with:
./dev gen docs
7. Runtime Version Gating
If the schema change adds a column/index used at runtime, gate usage on the version:
if settings.Version.IsActive(ctx, clusterversion.V26_2_MyChange) {
// Use the new column/index
}
This ensures mixed-version clusters work during rolling upgrades.
8. Verification
Re-run the tests from Section 5 without --rewrite to confirm everything passes. Also run your migration test:
./dev test pkg/upgrade/upgrades -f TestMyMigration -v
9. Rebase Conflicts
Golden files frequently conflict during rebases because multiple PRs change system tables concurrently. The resolution pattern:
- Accept either side of the conflict (content doesn't matter)
- Regenerate by running the tests with
--rewrite - Update hashes in
bootstrap/testdata/testdata(run test, grep "Unexpected hash", update, re-run with--rewrite)
Never try to manually merge golden file content — always regenerate.