PostgreSQL search path not restored properly after migrations when auto-comit == false.
See original GitHub issueWhich version and edition of Flyway are you using?
Flyway 5.0.7.
If this is not the latest version, can you reproduce the issue with the latest one as well?
(Many bugs are fixed in newer releases and upgrading will often resolve the issue)
Initially noticed with 5.0.5, repeated with 5.0.7. Seems problematic with current code in master (only from code inspection, I haven’t actually tried it).
Which client are you using? (Command-line, Java API, Maven plugin, Gradle plugin)
Java API.
Which database are you using (type & version)?
PostgreSQL 9.6
Which operating system are you using?
Windows 10.
What did you do?
(Please include the content causing the issue, any relevant configuration settings, the SQL statement that failed (if relevant) and the command you ran.)
Migrating multiple db schemas via multiple Flyway
instances (using same DataSource
instance - same database user, same database config etc.).
Relevant part of code:
final Flyway flyway = new Flyway();
flyway.setDataSource(dataSource);
flyway.setTable("flyway_metadata");
final String schemaName = dbSchema().getName();
flyway.setLocations("db.migration." + schemaName);
flyway.setSchemas(schemaName);
flyway.migrate();
Code above is common for several modules/classes, all using same (Spring-injected) DataSource
instance, and each its own db schema (dbSchema() returns jOOQ Schema
instance).
We’re running database migrations for all system modules upon system startup, sequentially (no parallel execution). Several db schemas contain views with same name (v_output_data
). Typical db migration creating v_output_data
view (repeatable migration) is of following form:
drop view if exists v_output_data cascade;
create view v_output_data as
<defining select>;
We’re using drop
+ create
instead of create or replace
since PostgreSQL doesn’t allow reducing number/changing type of view columns via create or replace
.
What did you expect to see?
The expectation was that DB migrations for each schema were completely isolated from each other (and hence that drop view
was perfectly safe even for newly created schemas).
What did you see instead?
In this specific scenario, we already had one existing schema (let’s call it A
) in the DB with existing view v_output_data
(and no further migrations to be applied) and one new schema (B
) with repeatable migration for view creation (formed as above - drop view
is redundant for first run, but was there for consistency and future use).
What happened was following:
b.v_output_data
was created as expecteda.v_output_data
was dropped - this was not expected!
After some debugging we found out that the problem is that restoring of current schema in DbMigrate.migrate()
(connectionUserObjects.restoreCurrentSchema()
in finally
block at the end of the method) is executed non-transactionally. PostgreSQL’s set search_path
is transaction-aware.
The other important piece of the puzzle is the fact that for PG current schema is actually set by prepending desired schema name to existing search path (PostgreSQLConnection.changeCurrentSchemaTo()
).
Finally, we have configured our data source not to use auto-commit, and all non-transactional changes are lost once connection is closed (which happens in finally
block near the end of Flyway.execute()
, when Database
object is closed).
In our case, migrations for schema A
were checked first (no migration needed, but search path transactionally set to start with A
and not restored properly). After that, migrations for schema B
were appied, with search path set to B,A,<default-search-path>
. At this point, drop view
in migration script intended for B
dropped the view from A
(since the view has not yet been created in B
).
I’ve checked current state of related code here on GitHub, and although it is refactored quite a bit, the problem seems to still be there (restoring is done in Connection.close()
, still no transaction).
Issue Analytics
- State:
- Created 6 years ago
- Comments:11 (4 by maintainers)
Just tried the demo project linked above (https://github.com/jezovuk/DemoForFlywayIssue1959), with Flyway 6.3.2 & 6.3.3. Both seem to work fine.
https://github.com/jezovuk/DemoForFlywayIssue1959