Skip to content

feat(store): improve SQL migrations - #2358

Open
juan518munoz wants to merge 6 commits into
nextfrom
jmunoz-sql-migrations
Open

feat(store): improve SQL migrations#2358
juan518munoz wants to merge 6 commits into
nextfrom
jmunoz-sql-migrations

Conversation

@juan518munoz

@juan518munoz juan518munoz commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Closes #2346

  • Froze store.sql as migrations/0001_init.sql. Schema changes are appended as new files, no longer patched into an existing one.
  • Pinned each migration's fingerprint in PINNED_SCHEMA_HASHES and made it the runtime check. The previous check is now test only.
  • Rewrote normalize_sql as a quote-aware scanner. Inline column comments are now free to edit, and three cases where different schemas shared a digest no longer do.
  • apply_migrations handles every SchemaVersion arm. A store from a newer client reports SchemaTooNew rather than an opaque DatabaseTooFarAhead.
  • A failed migration no longer prints the whole schema to the terminal.
  • Added scripts/check-migrations.sh and a CI job that rejects any edit to a released migration.

Notes

#2304 already moved the hash from the script's bytes to the materialized schema.

@igamigo igamigo changed the title chore: improve sql migrations feat(store): improve SQL migrations Aug 5, 2026
@igamigo
igamigo marked this pull request as ready for review August 5, 2026 22:18

@igamigo igamigo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good so far. One thing we should do before closing the issue is this point from the issue:

  • Back up the database before migration.

We should look into backing up the store, migrating it, and once we know it has passed (by checking the hashes), delete the backup. If anything errors in the middle, we roll back the upgrade and then report the error. We could decide to do this in a separate PR.

Another thing that would be good to validate is whether the first migration is applied on a fresh file and that there is no way for a sqlite database to be applied the 0001 migration

Comment on lines +43 to +52
/// Renders a migration failure without reproducing the migration script.
pub fn describe_migration_error(err: &MigrationError) -> String {
match err {
MigrationError::RusqliteError { err, .. } => describe_sqlite_error(err),
MigrationError::ForeignKeyCheck(violations) => {
format!("{} foreign key violation(s) after applying the migration", violations.len())
},
other => other.to_string(),
}
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Let's just inline this function where it's called (it's only one place AFAICT)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 0e10af0

Comment on lines 173 to 175
/// Rewrites the SQL text stored for a schema object into a form that ignores differences `SQLite`
/// itself ignores, so cosmetic edits do not change the fingerprint.
fn normalize_sql(sql: &str) -> String {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's revert these changes. I don't think it's code worth maintaining as it becomes instantly quite more complicated. A solution could be to introduce a SQL linter so the normalization is even more trivial.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted

0e10af0

Comment on lines 120 to 131

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I think we can do is verify that the hash and check that it's indeed as we expect

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now follow node's procedure of checking migrations. At startup, the MigrationBuilder derives hashes by replaying the migrations, and checks them.

0e10af0

@igamigo
igamigo requested a review from gabrielbosio August 6, 2026 03:28
@juan518munoz

Copy link
Copy Markdown
Collaborator Author

We should look into backing up the store, migrating it, and once we know it has passed (by checking the hashes), delete the backup. If anything errors in the middle, we roll back the upgrade and then report the error. We could decide to do this in a separate PR.

Another thing that would be good to validate is whether the first migration is applied on a fresh file and that there is no way for a sqlite database to be applied the 0001 migration

This is now handled as of 0e10af0

Comment thread scripts/check-migrations.sh Outdated
exit 0
fi

>&2 echo "The following released migrations were modified, renamed or deleted:"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the diff is compared against the base branch then a migration the script is comparing to might not be released yet:

Suggested change
>&2 echo "The following released migrations were modified, renamed or deleted:"
>&2 echo "The following merged migrations were modified, renamed or deleted:"

@juan518munoz juan518munoz Aug 7, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added suggestion in 4f4dd5d

Comment thread crates/sqlite-store/src/db_management/backup.rs
@gabrielbosio

gabrielbosio commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

If I am correct, merging this PR would cause any future change in SQL store database to force the addition of a migration script. Do we want this once we merge it to next, should we wait after the 0.16 release or should we disable the migration freeze for now? If we go with the latter approach, maybe it would not be even necessary to disable the entire migration freeze logic but to only disable the migration check job for now.

@gabrielbosio

gabrielbosio commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

If I am correct, merging this PR would cause any future change in SQL store database to force the addition of a migration script. Do we want this once we merge it to next, should we wait after the 0.16 release or should we disable the migration freeze for now? If we go with the latter approach, maybe it would not be even necessary to disable the entire migration freeze logic but to only disable the migration check job for now.

Let's leave this as it is right now and skip the migration check job in another PR with a new label (analogous to what no changelog is being used for). We can handle changes in the SQL store schema by changing the migration hash too for now.

@juan518munoz

Copy link
Copy Markdown
Collaborator Author

If I am correct, merging this PR would cause any future change in SQL store database to force the addition of a migration script. Do we want this once we merge it to next, should we wait after the 0.16 release or should we disable the migration freeze for now? If we go with the latter approach, maybe it would not be even necessary to disable the entire migration freeze logic but to only disable the migration check job for now.

Let's leave this as it is right now and skip the migration check job in another PR with a new label (analogous to what no changelog is being used for). We can handle changes in the SQL store schema by changing the migration hash too for now.

#2368

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SQL store hardening - Migrations

3 participants