Liquibase — Cheat Sheet

Tags: liquibase, database, migrations, ci-cd, sql, xml, yaml

Level: intermediate

TL;DR: Liquibase is an open-source database schema change management tool that enables trackable, version-controlled, and repeatable database migrations across multiple environments.

Key concepts

Uses a changelog file (supported in XML, YAML, JSON, or SQL formats) to define database changes sequentially.

Each change is defined as a changeset, uniquely identified by an id, an author, and the file path.

Tracks executed changesets in the DATABASECHANGELOG table to prevent applying the same change twice.

Uses the DATABASECHANGELOGLOCK table to ensure only one Liquibase instance runs migrations at any given time, preventing race conditions.

Supports database-agnostic changes when using XML/YAML/JSON, automatically translating them into platform-specific SQL.

Enables dry runs and SQL previews using commands like updateSql to review changes before applying them.

Allows defining rollback statements to revert changes if a deployment fails or needs to be undone.

Integrates seamlessly with CI/CD pipelines, Spring Boot, Maven, Gradle, and Docker.

Typical questions and ready answers

Q: How does Liquibase keep track of what has already been executed?R: It reads the DATABASECHANGELOG table. Every time a changeset runs successfully, it inserts a record with the changeset's ID, author, and MD5 checksum. Before running migrations, Liquibase checks this table and skips anything already applied.

Q: What happens if I modify an already executed changeset?R: Liquibase will calculate a new MD5 checksum, compare it to the one stored in DATABASECHANGELOG, and throw a validation failure, blocking the migration. Once executed, changesets should be considered immutable.

Q: Can we use plain SQL with Liquibase instead of XML or YAML?R: Yes, formatted SQL changelogs are fully supported. We just need to add specific comments like --changeset author:id to demarcate the changesets.

Q: What happens if a database migration fails halfway through?R: Liquibase stops execution. If the database supports transactional DDL (like PostgreSQL), it rolls back the current changeset. If not (like MySQL), partial changes might remain, and the DATABASECHANGELOGLOCK might stay locked, requiring manual intervention.

Pitfalls and common mistakes

Modifying a previously executed changeset instead of creating a new one to apply corrections (triggers checksum errors).

Putting multiple DDL statements in a single changeset without verifying if the target database supports transactional DDL, risking partial updates.

Forgetting to provide explicit rollback instructions for destructive operations (like dropTable) or raw SQL, making rollback operations impossible.

Leaving the DATABASECHANGELOGLOCK table locked after a crashed process, requiring manual release via CLI (releaseLocks) or direct SQL update.

Snippets and commands

<!-- Example XML Changelog -->
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.0.xsd">
    <changeSet id="1" author="umberto">
        <createTable tableName="users">
            <column name="id" type="int" autoIncrement="true">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="email" type="varchar(255)">
                <constraints nullable="false" unique="true"/>
            </column>
        </createTable>
    </changeSet>
</databaseChangeLog>

SQL

```-- Example Formatted SQL Changelog

-- liquibase formatted sql

-- changeset umberto:2

ALTER TABLE users ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;

-- rollback ALTER TABLE users DROP COLUMN created_at;

Useful CLI commands

liquibase update # Applies all pending changesets

liquibase updateSql # Outputs the SQL that would be executed (dry run)

liquibase rollbackCount 1 # Rolls back the last applied changeset

liquibase status # Lists pending changesets

liquibase releaseLocks # Releases the lock in DATABASECHANGELOGLOCK

liquibase clearCheckSums # Clears all checksums, forcing recalculation on next run

```

Jarvis Interviews
Jarvis