Ran into an issue with flyway
script executing an alter table
statement while Postgres auto-vacuum
for the same table was in progress.
As tables grow, Postgres runs the auto-vacuum
for tables periodically. The flyway script was stuck waiting for the table lock to be released.
To avoid this issue, one can disable the auto-vacuum
before the flyway migration and re-enable it after migration is finished using beforeMigrate.sql
and afterMigrate.sql
.
Last active
February 19, 2025 19:59
-
-
Save pavelfomin/745c2caf2f9c912b422ff90c4a6c39b1 to your computer and use it in GitHub Desktop.
Flyway and Postgres auto-vacuum
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Re-enable autovacuum | |
DO $$ | |
DECLARE | |
tbl RECORD; | |
BEGIN | |
FOR tbl IN | |
SELECT table_schema, table_name | |
FROM information_schema.tables | |
WHERE table_schema = 'foobar' | |
AND table_type = 'BASE TABLE' | |
LOOP | |
EXECUTE format('ALTER TABLE %I.%I SET (autovacuum_enabled = on);', tbl.table_schema, tbl.table_name); | |
END LOOP; | |
END $$; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Disable autovacuum for the duration of the migration | |
DO $$ | |
DECLARE | |
tbl RECORD; | |
BEGIN | |
FOR tbl IN | |
SELECT table_schema, table_name | |
FROM information_schema.tables | |
WHERE table_schema = 'foobar' | |
AND table_type = 'BASE TABLE' | |
LOOP | |
EXECUTE format('ALTER TABLE %I.%I SET (autovacuum_enabled = off);', tbl.table_schema, tbl.table_name); | |
END LOOP; | |
END $$; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Other useful things that can be added to afterMigrate.sql.
Change the owner of all new tables created by the service account and grant read-only access