Liquibase
tries to keep the database in a consistent state, Liquibase
migrator executes each ChangeSet
and keeps a record of ChangeSet id
in DATABASECHANGELOG
table along with the MD5 checksum of the ChangeSet
. in subsequent deployments, Liquibase
compare the ChangeSet
id if exist in DATABASECHANGELOG
table, it means the ChangeSet
has been executed before, then it compares the ChangeSet
MD5 checksum of ChangeSet
with DATABASECHANGELOG
table, if checksum is different , Liquibase
throws checksum error. let's see this with an example
changelog.mysql.xml
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet author="wesome (generated)" id="1692523877432-1" >
<createTable catalogName="appledb" tableName="apple">
<column name="apple_id" type="BIGINT">
<constraints nullable="false" primaryKey="true"/>
</column>
<column name="apple_name" type="VARCHAR(255)"/>
</createTable>
</changeSet>
<changeSet author="wesome (generated)" id="1692523877432-2">
<insert catalogName="appledb" tableName="apple">
<column name="apple_id" valueNumeric="1"/>
<column name="apple_name" value="Macintosh"/>
</insert>
</changeSet>
</databaseChangeLog>
liquibase.properties (update changeLogFile file format with SQL, XML, YAML, JSON as per changelog.mysql.<format>)
changeLogFile=changelog.mysql.xml
liquibase.command.url:jdbc:mysql://localhost:3306/AppleDb?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
liquibase.command.username: root
liquibase.command.password: rootroot
run the update command
liquibase update
Liquibase
will print the number of ChangeSet
executed in the logs
now update the changelog.mysq.xml file without changing the id attribute as below
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet author="wesome (generated)" id="1692523877432-1" >
<createTable catalogName="appledb" tableName="apple">
<column name="apple_id" type="BIGINT">
<constraints nullable="false" primaryKey="true"/>
</column>
<column name="apple_name" type="VARCHAR(255)"/>
</createTable>
</changeSet>
<changeSet author="wesome (generated)" id="1692523877432-2">
<insert catalogName="appledb" tableName="apple">
<column name="apple_id" valueNumeric="1"/>
<!-- <column name="apple_name" value="Macintosh"/> -->
<column name="apple_name" value="Fuji"/>
</insert>
</changeSet>
</databaseChangeLog>
run the update command
liquibase update
Liquibase
will throw a checksum validation failed error to notify that the ChangeSet
has been modified.
Unexpected error running Liquibase: Validation Failed:
1 changesets check sum
changelog.mysql.xml::1692523877432-2::wesome (generated) was: 8:d2236600353b2860139fca78b183edd6 but is now: 8:088f0cfa70cebaf7e03ecd5e99e12dc6
Run Liquibase update with changeset modification
Some times requirement is to run the ChangeSet
with modification, a very common example is CREATE OR REPLACE in views and stored procedures. Liquibase
provides an runOnChange
attribute to run the change set irrespective of modification.
Append runOnChange="true"
to each ChangeSet
that needs to run on modification.
changelog.mysql.xml
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet author="wesome (generated)" id="1692523877432-1" >
<createTable catalogName="appledb" tableName="apple">
<column name="apple_id" type="BIGINT">
<constraints nullable="false" primaryKey="true"/>
</column>
<column name="apple_name" type="VARCHAR(255)"/>
</createTable>
</changeSet>
<changeSet author="wesome (generated)" id="1692523877432-2">
<insert catalogName="appledb" tableName="apple">
<column name="apple_id" valueNumeric="1"/>
<column name="apple_name" value="Macintosh"/>
</insert>
</changeSet>
</databaseChangeLog>
liquibase.properties (update changeLogFile file format with SQL, XML, YAML, JSON as per changelog.mysql.<format>)
changeLogFile=changelog.mysql.xml
liquibase.command.url:jdbc:mysql://localhost:3306/AppleDb?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
liquibase.command.username: root
liquibase.command.password: rootroot
run the update command
liquibase update
Liquibase
will print the number of ChangeSet
executed in the logs
now update the changelog.mysq.xml file without changing the id attribute as below
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet author="wesome (generated)" id="1692523877432-1" >
<createTable catalogName="appledb" tableName="apple">
<column name="apple_id" type="BIGINT">
<constraints nullable="false" primaryKey="true"/>
</column>
<column name="apple_name" type="VARCHAR(255)"/>
</createTable>
</changeSet>
<changeSet author="wesome (generated)" id="1692523877432-2" runOnChange="true">
<insert catalogName="appledb" tableName="apple">
<column name="apple_id" valueNumeric="1"/>
<!-- <column name="apple_name" value="Macintosh"/> -->
<column name="apple_name" value="Fuji"/>
</insert>
</changeSet>
</databaseChangeLog>
liquibase.properties (update changeLogFile file format with SQL, XML, YAML, JSON as per changelog.mysql.<format>)
changeLogFile=changelog.mysql.xml
liquibase.command.url:jdbc:mysql://localhost:3306/AppleDb?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
liquibase.command.username: root
liquibase.command.password: rootroot
run the update command
liquibase update
Liquibase
will throw a checksum validation failed error to notify that the ChangeSet
has been modified.
UPDATE SUMMARY
Run: 0
Previously run: 2
Filtered out: 0
-------------------------------
Total change sets: 2
Liquibase command 'update' was executed successfully.