Liquibase guidelines

1. The main points

Please be true to these rules:

  1. If a changeset has been released, it is set in stone. Do not alter the changeset for any reason.
    • The only way to adapt a changeset, or to rollback, is by creating a new changeset.
  2. Put your changesets in a folder, with the version of the next release.
    • This ensures us that changeset are executed in the same order for everyone.


2. How to avoid having to drop the entire schema

With great power comes great responsibility.

Liquibase is capable of generating scripts to bring the database from any old state to the newest state. However, this is only possible

  • when the database is generated by Liquibase and not altered manually.
  • once they have been executed in the database, changesets cannot be altered anymore in the xml

Why is this so important?

In order for Liquibase to validate that neither the database, nor the executed changesets, have been altered, Liquibase generates hashes of every changeset.
When a changeset is executed in the database, its hash is persisted in the database.
Before determing how the database should be updated, Liquibase compares the hashes, calculated from the xml, with the hashed persisted in the db. If these don't correspond, Liquibase cannot determine what needs to be updated.

What to do when Liquibase says that changesets have been altered?

In that case, we can only

  • drop the entire schema and recreate it
  • alter the database and hashes manually, which is very error-prone.
  • revert the changes done to the xml files

3. Order of execution

Example:

  1. Stijn creates a database with Liquibase.
    1. File a.xml contains a changeset: "create table X".
    2. File b.xml contains another changeset: "rename column in table X"
  2. He adds a changeset: "drop table X".
    1. He inserts this changeset right after "create table X", in file a.xml.
  3. Stijn asks Liquibase to update the database.
    1. Liquibase discovers that only one changeset has not been executed yet (drop table X), and executes it.
  4. Mathias runs Liquibase.
    1. He gets an error: "table X does not exist".

How is this possible?

In the master file of Liquibase, it is defined that file a.xml should be run before b.xml.

The order of execution on a clean (or very old) database is:

  1. File a.xml
    1. Create table X
    2. Drop table X
  2. File b.xml
    1. Alter column of table X => ERROR

How to avoid this situation?

Create a folder per release.


In our example, we would get:

  1. 1.0.0/a.xml
    1. Create table X
  2. 1.0.0/b.xml
    1. Alter column of table X
  3. 2.0.0/a.xml
    1. Drop table X

Now, changesets are always executed in the correct order.