Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move migration table updating SQL into a migration transaction #6727

Merged
merged 6 commits into from Mar 29, 2021

Conversation

xtremerui
Copy link
Contributor

@xtremerui xtremerui commented Mar 24, 2021

What does this PR accomplish?

Bug Fix | Feature | Documentation

Fix #6695

Changes proposed by this PR:

we should not rely on Go to execute the SQL to update migrations_history table as the process could be killed before it could run the query, which will make Concourse lost track of migration state (it relies on the entry in migrations_history table).

Instead, we could put the SQL into each migration itself. In this way if the migration is done, the migrations_history table is guaranteed to be updated.

Notes to reviewer:

we have tried to intercept the os kill signal so Go could run a clean up but it seems Go could only catch syscall.SIGTERM (gracefully shutdown with draining). It can't catch syscall.SIGKILL, unfortunatelly.

Release Note

Fix a bug where a completed migration was not recorded in migrations_history table

Contributor Checklist

  • Followed [Code of conduct], [Contributing Guide] & avoided [Anti-patterns]
  • [Signed] all commits
  • Added tests (Unit and/or Integration)
  • Added release note (Optional)

Reviewer Checklist

  • Code reviewed
  • Tests reviewed
  • Release notes reviewed
  • PR acceptance performed

Signed-off-by: Rui Yang <ruiya@vmware.com>
@aoldershaw
Copy link
Contributor

It seems like it could be pretty easy to make mistakes if we need to put the INSERT INTO migrations_history line in each transaction, especially when reordering migrations. We could probably add a test for this to ensure things stay correct, but I wonder if there's a better way.

What if we just enforced all migrations to run in a transaction? In runMigration, we start a new transaction, and get rid of the BEGIN/COMMIT in each of the SQL transactions. In the go transactions, we could pass in the db.Tx rather than the db.Conn, and remove the start/rollback/commit logic from each transaction.

This is more restrictive in that we can no longer choose to run a migration outside of a transaction, but I'm not too sure what use-cases there are for doing so anyway - looks like all our migrations (besides empty ones) use a transaction.

Does that make sense?

Rui Yang and others added 5 commits March 25, 2021 12:30
it now creates the transaction first and pass it to go/sql migration
instead of creating a transaction in their own

Co-authored-by: Bohan Chen <bochen@pivotal.io>
Signed-off-by: Rui Yang <ruiya@vmware.com>
Co-authored-by: Bohan Chen <bochen@pivotal.io>
Signed-off-by: Rui Yang <ruiya@vmware.com>
delete "BEGIN;" "COMMIT;" and remove indent

Co-authored-by: Bohan Chen <bochen@pivotal.io>
Signed-off-by: Rui Yang <ruiya@vmware.com>
Co-authored-by: Bohan Chen <bochen@pivotal.io>
Signed-off-by: Rui Yang <ruiya@vmware.com>
Co-authored-by: Bohan Chen <bochen@pivotal.io>
Signed-off-by: Rui Yang <ruiya@vmware.com>
@xtremerui xtremerui marked this pull request as ready for review March 25, 2021 19:59
@xtremerui xtremerui requested a review from a team as a code owner March 25, 2021 19:59
@xtremerui
Copy link
Contributor Author

@aoldershaw we have updated the PR so that migrator use a tx instead of conn. All .go and .sql migrations has to be updated accordingly. We removed BEGIN;COMMIT; from sql migration and removed Commit() Rollback() in go migration. For you convinient you could view the changes by commit to skip the migrations file changes.

@xtremerui xtremerui added the bug label Mar 25, 2021
@vito
Copy link
Member

vito commented Mar 26, 2021

This is more restrictive in that we can no longer choose to run a migration outside of a transaction, but I'm not too sure what use-cases there are for doing so anyway - looks like all our migrations (besides empty ones) use a transaction.

This came up in retro and I brought up needing to be able to do this, but I don't think we need to anymore. The migration that needed it before has since been squashed into the new initial schema.

There was a time when we had to do an ALTER TYPE ... ADD VALUE, which can't be run in a transaction in PostgreSQL 9.5.

ALTER TYPE ... ADD VALUE (the form that adds a new value to an enum type) cannot be executed inside a transaction block.

But as of Postgres 12, it can!

If ALTER TYPE ... ADD VALUE (the form that adds a new value to an enum type) is executed inside a transaction block, the new value cannot be used until after the transaction has been committed.

I actually looked into this recently and I'm fairly certain this was the only type of query that could not be run in a transaction. Given that we don't do this often (last time we did it was to add another volume/container state iirc), if/when it does come up again I'd rather take that as an opportunity to raise the minimum version to 12 so we can leverage more shiny new features.

So I'm good with just forcing transactions everywhere. 👍

Copy link
Contributor

@aoldershaw aoldershaw left a comment

Choose a reason for hiding this comment

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

LGTM

@xtremerui xtremerui merged commit c0e3a7f into master Mar 29, 2021
@xtremerui xtremerui deleted the issue/6696-migration-terminated branch March 29, 2021 14:17
@chenbh chenbh added the release/undocumented This didn't warrant being documented or put in release notes. label Apr 7, 2021
aoldershaw pushed a commit that referenced this pull request Apr 8, 2021
#6727 wraps all migrations in a transaction, and we
can't start a transaction within another

Signed-off-by: Aidan Oldershaw <aoldershaw@pivotal.io>
Co-authored-by: Esteban Foronda <eforonda@vmware.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug release/undocumented This didn't warrant being documented or put in release notes.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Database Migration is not rolled back if insert into migration table failed
4 participants