Fixing and Enforcing Liquibase Rollbacks?

Our team has been using Liquibase for a while and we recently ran into an issue with rollbacks.  We want to rollback to a particular tag in the databasechangelog table.  Unfortunately, we were not diligent in ensuring that all or commands had corresponding commands.  Based on this predicament, I have a few questions:

  1. What is the recommended method of fixing changesets that have already been applied and cannot be rolled back?
  • Can I just delete the relevant entries in the databasechangelog table, update my changesets in my changelogs and then rerun Liquibase?  I know if I change them now, the checksum will fail.
  • Is there a method for telling Liquibase to fail if rollbacks cannot be achieved?
    • If there isn't, I think that this would be a nice to have feature.

    We have not upgraded to Liquibase 2.0 yet, so please keep that in mind when responding.



    1. You could remove the entries in the databasechangelog table without any problem and rerun liquibase.  But why you need to do it? Is it not simple comment out the non-necessary change sets in the xml or ever delete it? Rollback generates scripts based on the xml file, not on the table’s entries. 

     

    1. AFAIK Liquibase does not restrict to get rollback required. I suggest to file it as a wish in JIRA.


    Cheers, Oleg


    You can add tags even now, they are not included in the checksum calculation.

    Nice.  That might be worth making more prominent in the manual.

    Best,
    Laird

    You wouldn’t want to remove records from the databasechangelog table because you want liquibase to know that they were executed so it can generate rollback commands (assuming you are trying to do a rollback or rollbackSql command).  You can add tags even now, they are not included in the checksum calculation.  If you have a changeset that doesn’t need rollback, you can just use an empty tag.


    There is a futureRollbackSQL command you can run which will output the SQL needed to rollback a fully updated database to the current state which can be used to check that you have proper rollback tags.  


    As far as forcing them, you could create a custom changeset parser (liquibase.org/extensions) that extends the default XML parser and simply adds an additional validation of the created DatabaseChangeLog object to ensure that all changeSets have rollbacks that exist or can be generated.


    Nathan 

    I agree.  Knowing the rollback tags are not considered in the checksum calculation is a feature worth publishing.  This solves my problem beautifully!

    So, Nathan, just to be clear, does this mean all of the following are true:

    • Because rollback tags aren’t part of the checksum, I can add them to existing changesets
    • If I add rollback tags to my changesets, and then ask Liquibase to perform a rollback, Liquibase will use my recently-added rollbacks to perform the actual rollback
    • If I keep changing my rollback tags (no idea why I would) then it’s possible I could hose the database: I could do a rollback, an update, change my rollback tags to do something outrageous, do another rollback–and be in a strange, unversioned state
    Just looking for the edge cases here.

    Thanks,
    Laird

    Yes, you can add them to existing changesets and/or modify rollback statements.  If/when you perform a rollback, the current rollback statement from the changelog will be executed, not as it existed when the changeset was first executed.


    Wheter you could break your database with changing rollbacks is somewhat up to how you write you rollback, but I don’t think in practice it should really be a problem. The rollback statement should be targeted simply to undo what the original changeset did.  If you diverge from that and start doing other things in the rollback, you could get into an odd state if you aren’t correctly rolling back the changeSet, but if you later find that your rollback isn’t right, you can always change it :slight_smile:

    Nathan