Rollback missing some changesets

I am confused about how rollback works.

I have the following scenario:

  1. Using helm I install a release containing two liquibase changesets (one with some database table creations and one with a tagDatabase changeset) like:
    <include file="db/0.1.0-create-schema.sql"/>
    <changeSet author="trym" id="6"><tagDatabase tag="v0.1.0"/></changeSet>
  1. I upgrade the helm release now with four changesets (two from previously and two similar) like:
    <include file="db/0.1.0-create-schema.sql"/>
    <changeSet author="trym" id="6"><tagDatabase tag="v0.1.0"/></changeSet>

    <include file="db/0.2.0-create-testtable.sql"/>
    <changeSet author="trym" id="8"><tagDatabase tag="v0.2.0"/></changeSet>
  1. Finally I do a helm rollback of the release to the first revision. Because my application looks at the latest tagDatabase in the changelog file and rolls back to it using the liquibase/liquibase-standard/src/main/java/liquibase/Liquibase.java at master · liquibase/liquibase · GitHub (in this case tag=v0.1.0) everything should be fine. Except it is not. Because the changeset id:6 is rolled back as needed but the changeset id:7 is not rolled back :frowning:

It seems like the rollback only looks in the changeLog file and not in the database. Is that correctly understood? Are there ways to let the Liquibase class synchronize its state with the database, so the rollback is complete (including the changeset id:7)?

Thanks for any input regarding this.

With the assumption that changeset 7 is in db/0.2.0-create-testtable.sql…

Based upon what I am seeing in your master changelog, all changsets in “db/0.2.0-create-testtable.sql” should be rolled-back when you “rollback v0.1.0”.

Please provide the log output for both the update and the rollback commands, with sql-log-level=INFO so all sql statements are shown.

Thanks for your input and yes changeset 7 is in db/0.2.0-create-testtable.sql.

I have tried two things:

  1. liquibase.rollback(liquibase.listUnexpectedChangeSets(…).size())
  2. set liquibase.sql.logLevel=FINE (when doing rollback to a tag)

Regarding 1) The changeset 6 and 5 are rolled back (known in the changeLog.xml file) and not the changeset 8 and 7 (known in the database (as unexpected changesets))

Regarding 2) The following should give a hint of what is happening:
Scenario step 2 logging extract:

Running Changeset: db/0.2.0-create-testtable.sql::7::trym
2024-09-17 06:23:32,238 FINE  [liq.executor] (main) Changeset db/0.2.0-create-testtable.sql::7::trym
2024-09-17 06:23:32,239 FINE  [liq.executor] (main) create testtable
2024-09-17 06:23:32,244 FINE  [liq.executor] (main) Executing Statement: create table firmware.TestTable (
            requireUpdate boolean not null
            )
2024-09-17 06:23:32,245 FINE  [liq.executor] (main) create table firmware.TestTable (
            requireUpdate boolean not null
            )
2024-09-17 06:23:32,246 FINE  [liq.executor] (main) 0 row(s) affected
2024-09-17 06:23:32,247 INFO  [liq.changelog] (main) Custom SQL executed
2024-09-17 06:23:32,249 INFO  [liq.changelog] (main) ChangeSet db/0.2.0-create-testtable.sql::7::trym ran successfully in 11ms
2024-09-17 06:23:32,251 FINE  [liq.executor] (main) INSERT INTO public.databasechangelog (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, MD5SUM, DESCRIPTION, COMMENTS, EXECTYPE, CONTEXTS, LABELS, LIQUIBASE, DEPLOYMENT_ID) VALUES ('7', 'trym', 'db/0.2.0-create-testtable.sql', NOW(), 4, '9:6bb7b040affac50dbfd7ac3a68784ba2', 'sql', 'create testtable', 'EXECUTED', NULL, NULL, '4.27.0', '6554212215')
2024-09-17 06:23:32,252 FINE  [liq.executor] (main) 1 row(s) affected
2024-09-17 06:23:32,253 FINE  [liq.executor] (main) Changelog query completed.
Running Changeset: db/changeLog.xml::8::trym
2024-09-17 06:23:32,257 FINE  [liq.executor] (main) Changeset db/changeLog.xml::8::trym
2024-09-17 06:23:32,258 INFO  [liq.changelog] (main) Tag 'v0.2.0' applied to database
2024-09-17 06:23:32,259 INFO  [liq.changelog] (main) ChangeSet db/changeLog.xml::8::trym ran successfully in 2ms
2024-09-17 06:23:32,260 FINE  [liq.executor] (main) INSERT INTO public.databasechangelog (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, MD5SUM, DESCRIPTION, COMMENTS, EXECTYPE, CONTEXTS, LABELS, LIQUIBASE, DEPLOYMENT_ID, TAG) VALUES ('8', 'trym', 'db/changeLog.xml', NOW(), 5, '9:a59968a2edb9a506fb67435b3ec695a3', 'tagDatabase', '', 'EXECUTED', NULL, NULL, '4.27.0', '6554212215', 'v0.2.0')

Scenario step 3 logging:
Notice that I have added logging of (the comments in):

  • liquibase.getDatabaseChangeLog().getChangeSets()
  • liquibase.listUnexpectedChangeSets()
2024-09-17 06:26:44,734 WARN  [com.def.sec.fir.ser.MigrationService] (main) 2. What changeSets do we know [create user postgresql, create user h2, create schema postgresql, create schema h2, create initial tables, null]
2024-09-17 06:26:44,736 WARN  [com.def.sec.fir.ser.MigrationService] (main) 2. Unexpected changesets [create testtable, null]
...
Rolling Back Changeset: db/changeLog.xml::6::trym
2024-09-17 06:26:44,782 FINE  [liq.executor] (main) Rolling Back ChangeSet: db/changeLog.xml::6::trym
2024-09-17 06:26:44,786 FINE  [liq.executor] (main) DELETE FROM public.databasechangelog WHERE ID = '6' AND AUTHOR = 'trym' AND FILENAME = 'db/changeLog.xml'
2024-09-17 06:26:44,787 FINE  [liq.executor] (main) 1 row(s) affected
2024-09-17 06:26:44,788 FINE  [liq.executor] (main) Changelog query completed.
2024-09-17 06:26:44,791 INFO  [liq.command] (main) Rollback command completed successfully.

I am uncertain that my quest is possible at all. Are the rollback statements stored in the database (databasechangelog)? Otherwise I would think it hard to rollback the “unexpected changesets”.

Thanks for further input.

I am realizing that I am on a wrong path. Helm will have both applications running at the same time, so I need my migrations to be backwards compatible and not do any rollback at all. Thanks for your time anyway.