liquibase-percona icon indicating copy to clipboard operation
liquibase-percona copied to clipboard

`liquibase.percona.failIfNoPT` option doesn't fail the application startup in Spring Boot

Open missingdays opened this issue 4 years ago • 4 comments
trafficstars

Steps to reproduce:

  1. Have pt-online-schema-change not installed on your machine
  2. Have a changeset that requires percona, in my case
    <changeSet id="01" author="Evgeny Bovykin">
        <addColumn tableName="Entity"
                   xmlns:liquibasePercona="http://www.liquibase.org/xml/ns/dbchangelog-ext/liquibase-percona"
                   liquibasePercona:usePercona="true">
            <column name="no-downtime-column" type="varchar(255)"/>
        </addColumn>
    </changeSet>
  1. Set liquibase.percona.failIfNoPT System property to true

Excepted result: Application startup is failed

Actual result: Application starts as normal, without any warnings or errors in the log

Log output:

{"time":"2021-07-01T16:35:04.315+02:00","msg":"Set default schema name to PUBLIC","logger":"liquibase.database","thread":"main","level":"INFO"}
{"time":"2021-07-01T16:35:04.635+02:00","msg":"Successfully acquired change log lock","logger":"liquibase.lockservice","thread":"main","level":"INFO"}
{"time":"2021-07-01T16:35:05.199+02:00","msg":"Creating database history table with name: PUBLIC.DATABASECHANGELOG","logger":"liquibase.changelog","thread":"main","level":"INFO"}
{"time":"2021-07-01T16:35:05.208+02:00","msg":"Reading from PUBLIC.DATABASECHANGELOG","logger":"liquibase.changelog","thread":"main","level":"INFO"}
{"time":"2021-07-01T16:35:05.336+02:00","msg":"Successfully released change log lock","logger":"liquibase.lockservice","thread":"main","level":"INFO"}
{"time":"2021-07-01T16:35:05.347+02:00","msg":"Successfully acquired change log lock","logger":"liquibase.lockservice","thread":"main","level":"INFO"}
Skipping auto-registration
{"time":"2021-07-01T16:35:05.348+02:00","msg":"Skipping auto-registration","logger":"liquibase.hub","thread":"main","level":"WARN"}
{"time":"2021-07-01T16:35:05.379+02:00","msg":"Table entity created","logger":"liquibase.changelog","thread":"main","level":"INFO"}
...
{"time":"2021-07-01T16:35:05.442+02:00","msg":"Columns no-downtime-column(varchar(255)) added to Entity","logger":"liquibase.changelog","thread":"main","level":"INFO"}
{"time":"2021-07-01T16:35:05.446+02:00","msg":"ChangeSet db/changelog/db.no-downtime-example.xml::01::Evgeny Bovykin ran successfully in 29ms","logger":"liquibase.changelog","thread":"main","level":"INFO"}

Interestingly, if I don't set liquibase.percona.failIfNoPT and it defaults to false, a warning is logged

{"time":"2021-07-01T16:35:05.262+02:00","msg":"Not using percona toolkit, because it is not available!","logger":"liquibase.ext","thread":"main","level":"WARN"}

missingdays avatar Jul 01 '21 14:07 missingdays

I've just created a integration test and the property seems to be working fine: If liquibase.percona.failIfNoPT is set to true, then the liquibase update fails with the following messages:

[ERROR] Failed to execute goal org.liquibase:liquibase-maven-plugin:4.4.0:update (update) on project liquibase-percona-it-addColumnFailIfNoPT: 
[ERROR] Error setting up or running Liquibase:
[ERROR] java.lang.RuntimeException: No percona toolkit found!

Note, that I used maven and liquibase-maven-plugin to run the update.

Which framework do you use to integrate liquibase? Is it something like Spring Boot? How do you set the system property? When do you set the system property?

When no PT is found, I simply throw a RuntimeException, which should fail the update at this moment: https://github.com/liquibase/liquibase-percona/blob/a7856975246dc8892d5a799b6ab540e4e1c72515/src/main/java/liquibase/ext/percona/PerconaChangeUtil.java#L117-L120

So, you should either see the RuntimeException or the log entry...

adangel avatar Jul 09 '21 14:07 adangel

Which framework do you use to integrate liquibase? Is it something like Spring Boot?

Yes, I use Spring boot

How do you set the system property?

For testing purposes, I use System.setProperty(...)

When do you set the system property?

Before starting the application

@SpringBootApplication
class Application

fun main(args: Array<String>) {
    System.setProperty("liquibase.percona.failIfNoPT", "true");
    runApplication<Application>(*args)
}

I also tried with the command line argument, -Dliquibase.percona.failIfNoPT=true, to the same effect.

missingdays avatar Jul 09 '21 14:07 missingdays

@adangel hi, any updates on this issue? I'd really like to try the percona out in our project, but this issue is a blocker for me

missingdays avatar Aug 09 '21 14:08 missingdays

@missingdays Still can't reproduce the problem - for me it works like a charm. Please see the attached sample spring boot project and the README.md file inside: spring-boot-liquibase-sample.zip All combinations work. Setting from Java in Application via System.setProperty and from outside. Please note, that you need to specify -D before -jar when providing the property on the commandline, e.g. java -Dliquibase.percona.failIfNoPT=true -jar target/spring-boot-liquibase-0.0.1-SNAPSHOT.jar. Otherwise the property won't have any affect.

Pitfalls: When you run the unit tests the application context is started. If you don't use a separate db connection, then it will just run liquibase against the very same database and without the failIfNoPT property set. So when you start it another time, the changes have already been applied. So make sure to double check the database before each try.

Please modify my sample project until it fails. Thanks.

adangel avatar Aug 13 '21 09:08 adangel