What is Liquibase and why use it?
Tutorial Series
This series works through the steps for finally bringing relational databases into the DevOps fold. The end goal is to include schema, code and data changes for relational databases into CI/CD pipelines in Azure or GitLab. This whole process relies on Liquibase to keep the databases updated.
DevOps for Databases
- What is Liquibase and why use it? ← You are here.
- Getting Started with Liquibase (Working on it!)
- Liquibase in Azure Pipelines (Working on it!)
- Advanced Scenarios with Liquibase (Working on it!)
Ready to get started with DevOps for databases? Let’s dive into it!
Introduction
Most development team are already storing their code into source control. However, you will rarely find the scripts for database schema, code or data changes in the source control.
In fact, many teams are still relying on manual and opaque processes to manage these changes in their relational databases. I’ve found this to be especially true for teams overseeing legacy systems.
While trying to build transparency and consistency in these database processes, I was introduced to Liquibase. In a nutshell, Liquibase tracks and applies database changes in such a way that we can automate them as part of a CI/CD pipeline.
Finally, we can bring relational databases into the DevOps fold!
What is Liquibase?
Liquibase is a Java-based tool that tracks and applies database changes. It is open-source and licensed under the Apache 2.0 license.
The database changes can be anything from managing tables, columns, constraints, views or stored procedures (create/drop) to managing data (insert/update/delete). These changes are defined in text files using either XML, YAML, JSON or SQL formats. Liquibase will automatically generate the database-specific SQL for you when applying changes defined in non-SQL formats. Some changes using non-SQL formats require a license of their paid offering, Liquibase Pro. For example, you won’t be able to update packages, triggers or functions using non-SQL formats (XML, YAML or JSON).
That’s a bit of a moot point since you can always implement them for free using formatted SQL files. You can read more about which changes are available in either Liquibase Community or Liquibase Pro in their docs.
Liquibase has built-in support for the most popular databases including MySQL, MariaDB, PostgreSQL, SQL Server and Oracle. If you’re using another database, be sure to check their full list of supported databases.
You can execute Liquibase from the command line, Maven, Ant or directly from Java source code. This allows us to easily integrate it in our CI/CD pipelines!
It’s also important to note that, being a Java-based tool, Liquibase requires Java to be installed on the machine running it. It also needs the appropriate JDBC drivers for the database that you expect to use it against. You can easily find and download the JDBC drivers for free online.
Why use Liquibase?
The obvious benefits of Liquibase come from automating the change management for your database environments. Comparing the current database state to its desired state is a thing of the past! Most deployment scenarios can be handled by Liquibase’s tracking of changes applied.
By combining the storage of database changes in source control and their deployment using Liquibase, you are adding transparency and consistency to manual processes while also reducing the risk of human-error.
You can even take this one step further! Why not integrate database deployments as part of your CI/CD pipelines?
That would add even more traceability to the process. Committed changes and pull requests could automatically trigger database deployments using Liquibase. It would be easy to audit and track accountability through the source control and pipeline logs. Who made which changes? What was deployed to which environments? Which tests passed or failed?
How does Liquibase work?
Developers define and organize their database changes in changelog
files using either XML, YAML, JSON or SQL formats. These files should be stored in source control to enable collaboration. They contain two types of item, changeset definitions or include statements for nested changelog files. This nested hierarchy lets you further organize your changes.
The most important thing to remember about the changelog files is that nested files or changesets are listed explicitly and they are included/executed in the order that they appear.
As I already mentioned, each changelog file contains group of changes that are referred to as changesets
. These changesets are the individual units of change that are tracked by Liquibase. They are uniquely identified by a combination of author
, id
and filename
. Note that you can (and probably should) also define a rollback action for each changeset.
When you first run Liquibase against a database, it automatically creates two tracking tables, DATABASECHANGELOG
and DATABASECHANGELOGLOCK
. The first table will be checked by Liquibase on every database updates to determine whether changesets have already been applied or not. The second one keep track of Liquibase instances being run against the database to prevent concurrency issues.
Liquibase also has advanced features such as contexts, labels, and preconditions to precisely control when and where a changeset is deployed.
You can read more on these particular concepts in Liquibase’s docs.
- Major Liquibase Concepts
- Change Log Files
- Change Sets
- Rollbacks
- DATABASECHANGELOG Table
- DATABASECHANGELOGLOCK Table
Setting up your environment
Using Liquibase installers
Starting with Liquibase version 3.8.6, you can simply download the installers for Windows and MacOS on their GitHub Releases page. These installers include everything you need to run Liquibase (including Java).
The installers are perfect as a quick and easy way to install Liquibase and start playing around with it locally. However, you’re probably not going to be using them to run Liquibase from CI/CD pipelines.
Manual steps
Don’t worry though! Even without the installers, the installation steps are pretty simple.
Here’s what you need to do to setup Liquibase:
- Download the appropriate compressed file on their GitHub Releases page.
- Extract the content to a local folder. (i.e.
C:\liquibase
) - Add this location to your
PATH
environment variable. - Ensure that Java is installed on the machine and available in the
PATH
environment variable. You can test this by running the following commandjava -version
. - Liquibase also requires the
JAVA_HOME
environment variable is set to the JDK installation’s root folder.
Once you’re done, you can try running the Liquibase help command. Type liquibase --help
from the command-line and make sure that you don’t get any errors.
Notes for Java and licensing
With the whole Java licensing confusion going around, I suggest using the Java Runtime Environment (JRE) from AdoptOpenJDK. All AdoptOpenJDK binaries and scripts are open source licensed and available for free.
It’s also the JRE that is bundled with the Liquibase installers as per their README file.
You can find all of the information that you need on AdoptOpenJDK’s Installation page. Pick the version, JVM and platform from the lists before following the steps in the next section or simply use their installers.
Don’t forget to manually set the JAVA_HOME environment variable after the installation or to pick the option to update it directly from the installer.
Wrapping up
In this post, we’ve covered the What, Why and How of Liquibase before installing it locally and verifying the installation.
Next, we’ll cover Getting Started with Liquibase with some best practices about directory/file structure, command line usage and Liquibase project files.