Changelog Formats

The changeset tag is a unit of change that Liquibase executes on a database and which is used to group database Liquibase Change Types together. A list of changes created by multiple changesets are tracked in a changelog.

A changeset is uniquely tagged by both an author and an id attributes (author:id), as well as the changelog file path. The id tag is only used as an identifier, it does not direct the order that changes are run and does not have to be an integer. If you do not know or do not want to save the actual author, use a placeholder value such as UNKNOWN. To execute the changeset, you must include both author and id.

<?xml version="1.0" encoding="UTF-8"?> 
<databaseChangeLog
	xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
	xmlns:pro="http://www.liquibase.org/xml/ns/pro"
	xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
		http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
		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">
    <changeSet id="1" author="bob">  
        <comment>A sample change log</comment>  
        <createTable/> 
    </changeSet>  
    <changeSet id="2" author="bob" runAlways="true">  
        <alterTable/>  
    </changeSet>  
    <changeSet id="3" author="alice" failOnError="false" dbms="oracle">
        <alterTable/>  
    </changeSet>  
    <changeSet id="4" author="alice" failOnError="false" dbms="!oracle">
        <alterTable/>  
    </changeSet>  

</databaseChangeLog>

Running the changeset

As Liquibase uses the DATABASECHANGELOG table, it reads the changesets in order and, for each one, checks the DATABASECHANGELOG table to see if the combination of id/author/filepath has been run.

If it has been run, the changeset will be skipped unless there is a runAlways tag set to true in that changeset. After all the changes in the changesets are run, Liquibase will insert a new row with the id/author/filepath along with an MD5Sum of the changeset in the DATABASECHANGELOG.

Note: filepath is the path that defines the changelog-file attribute. Even if the same file is referenced with a different path, that is considered a different file unless the logicalFilePath is defined.

Liquibase attempts to execute each changeset in a transaction that is committed at the end, or rolled back if there is an error. Some databases will auto-commit statements which interferes with this transaction setup and could lead to an unexpected database state. Therefore, it is best practice to have just one change per changeset unless there is a group of non-auto-committing changes that you want to apply as a transaction such as inserting data.

Available attributes

id

Specifies an alpha-numeric identifier. Required

Note: If there are zeros in the id, it is best practice to put quotes around the id. ie: "1.10" This allows all characters to be retained.

 

author Specifies the creator of the changeset. Required
dbms Specifies the type of a database for which that changeset will be used. When the migration step is running, it checks the database type against this attribute.

Note: For more information about database type names, see Supported databases page.

Also, you can do the following:
  • List multiple databases separated by commas.
  • Specify that a changeset is not applicable to a particular database type by prefixing it with !.
  • Add the keywords all and none.
runAlways Executes the changeset on every run, even if it has been run before.
runOnChange Executes the changeset the first time and each time the changeset has been changed.
Contexts Controls whether a changeset is executed depending on runtime settings. Any string can be used for the context name and they are checked case-insensitively.
Labels Controls whether a changeset is executed depending on runtime settings. Any string can be used for the label name and they are checked case-insensitively.
runInTransaction

Specifies whether the changeset can be ran as a single transaction (if possible). Default value is true.

Warning: If this attribute is set to false and an error occurs part way through running a changeset that contains multiple statements, the Liquibase DATABASECHANGELOG table will be left in an invalid state. Since 1.9

failOnError Defines whether the migration will fail if an error occurs while executing the changeset. Default value is true.
objectQuotingStrategy Controls how object names are quoted in the SQL files generated by Liquibase and used in calls to the database. Default value is LEGACY.
  • LEGACY – The default value. Does not quote objects unless the database specifies that they must be quoted, usually including reserved words and names with hyphens. In PostgreSQL databases, mixed-case names will also be quoted.
  • QUOTE_ALL_OBJECTS – Every object gets quoted. For example, person becomes "person".
  • QUOTE_ONLY_RESERVED_WORDS – The same logic as LEGACY, but without mixed-case objects in PostgreSQL databases.
runOrder Overrides the order in the changelog from where the changeset with the runOrder="first|last" will be run. It is typically used when you want a changeset to be always executed after everything else but don’t want to keep moving it to the end of the changelog. Setting the runOrder to last will automatically move it in the final changeset order.Since 3.5

Note: The runOrder changeset attribute is not supported in formatted SQL changesets.

created Stores dates, versions, or any other string of value without using remarks (comments) attributes. Since 3.5
ignore Ignores the changeset from the execution. Since 3.6
logicalFilePath Overrides the file name and path when creating the unique identifier of changesets. Required when moving or renaming changelog.

Available sub-tags

comment Specifies the description of the changeset. XML comments will provide the same benefit.
preConditions Must be passed before the changeset will be executed. It is typically used for doing a data sanity check before doing something unrecoverable such as a dropTable.Since 1.7

Note: For more information, see Preconditions.

<Any Refactoring Tag(s)> Specifies the database change(s) to run as part of the changeset (Liquibase Change Types).
validCheckSum Adds a checksum that is considered valid for this changeset, regardless of what is stored in the database. It is primarily used when you need to change a changeset and don't want errors thrown on databases on which it has already been run (not a recommended procedure). Special value "1:any" will match to any checksum and will not execute the changeset on ANY change. Since 1.7
rollback Specifies SQL statements or Change Type tags that describe how to rollback the changeset.

Note: For more information, see Liquibase Rollback Workflow.

The rollback tag

The rollback tag describes how to roll back a change using SQL statements, Change Types, or a reference to a previous changeset.

Note: For more information about the rollback tag and examples, see Liquibase Auto Rollback.

changeset checksums

When Liquibase reaches a changeset, it computes a checksum and stores it in the DATABASECHANGELOG table. The value of storing the checksum for Liquibase is to know if something has been changed in the changeset since it was run.

If the changeset has been changed since it was run, Liquibase will exit the migration with an error message like Validation failed: change set check sums <changeset identifer> was: <old checksum> but is now: <newchecksum>. This is because Liquibase cannot identify what was changed and the database may be in a state different than what the changelog is expecting. If there was a valid reason for the changeset to be changed and you want to ignore this error, there are two options.

Note: You can also use the clear-checksums command to resolve the checksum error, however, it will clear the entire column of checksums in your DATABASECHANGELOG table.

The manual update of the DATABASECHANGELOG table

The first option is to manually update the DATABASECHANGELOG table so that the row with the corresponding id/author/filepath has a null value for the checksum. You would need to do this for all environments where the changeset has been deployed. The next time you run the Liquibase update command, it will update the checksum value to the new correct value.

The <validCheckSum> attribute

The second option is to add a <validCheckSum> element to the changeset. The text contents of the element should contain the old checksum from the error message.

The runOnChange attribute

Checksums are also used in conjunction with the runOnChange changeset attribute. There are times you may not want to add a new changeset because you only need to know about the current version, but you want this change to be applied whenever it is updated. For example, you can do this with stored procedures.

If you copy the entire text of the stored procedure to a new changeset each time you make a change, you will not only end up with a very long changelog, but you will lose the merging and diffing power of your source control. Instead, put the text of the stored procedure in a changeset with a runOnChange="true" attribute. The stored procedure will be re-created when there is a change to the text of it.

Note: For more information, see runOnChange.

Related links