Best practice for shortening changelog for new deployments?

My changelog has grown to some 200 changesets between releases 1.0 and 2.0 . When deploying a new instance of my 2.0 application on an empty database, I’d like to run just one changeset creating the 2.0 schema instead of replaying the 200 changesets from the 1.x releases.

On the other hand, when updating an existing 1.x instance, I would like to run just the missing 1.x changesets and any new ones for the 2.x release.

How to handle both cases with one changelog?

Best regards,

Hi, Harald; fancy seeing you around these parts.  :-)

I would ask: does it really matter how many changesets you have?  Why not just continually replay them?

(I ask this knowing you might have a good answer, but in these days of cheap disk–and where the changelog is treated as kind of a black box anyway–what does it really matter how big it is?)

(Idea just hit me for an extension that would allow Liquibase to read directly from gzipped changelogs.)




Great question! I would like to know good answer too :slight_smile:

I can share with you my idea in this subject, already applied and working quite fine. The idea is to have “merged changeLogs” which result in exactly same final database, but build in different way. For example: in “core” changeLogs we have changeSet C1 that changes column type from A to B, and some time later next changeSet C2 that chaneges it to C. We can run different changeSet (let’s call it mergeC1C2) which will change column type from A to C directly and mark changeSets C1 and C2 as ran.

Implementation details:

  • new refactoring markRan, which marks some changeSet as ran without running it.

  • XMLChangeLogSAXParser which reads “X-merged.xml” file instead “X.xml” file when “useMergedChangeLogs” is enabled

So basic flow is like this: when we want to do update “fast way” then we enable “useMergesChangeLogs” flag and during update shorter changeSets from “X-merge” changeLogs will be executed. Of course they have to be created manually and (because we don’t use logicalFilePath or whatever functionality) they are responsible for marking “original” changeSets as ran. This way when validating against “not merged” changeLog everything will be applied.

This “manual part” is a little tricky, but we can (partially) test that databases from merged and not merged scripts are the same - using diff tool.

Maybe you can use similar approach, maybe you see some improvements. Any news would be interesting :slight_smile:

Hi Laird,

it’s not disk space I’m worried about, but runtime.

We’re running Liquibase in our integration tests to (re)create a database with mostly empty tables. This takes several minutes, whereas a plain old createTables.sql script runs in a few seconds.

Best regards,


This is especially painful for (old, stupid, fat,…) mssql, where you have to drop and recreate indexes to modify columns. Recreating index on big table can be very time consuming, and for example in tests, where you can (and probably want) recreate db from scratch - completely unnecessary.

Thanks for all your replies!

Picking up some of these ideas and trying out different options, I’ve now come up with the following approach.

1) We put our changesets into monthly changelogs, so the master changelog.xml contains nothing but includes:



2) Using the CLI command generateChangeLog on a current database, I generated a changelog fastforward-9.6.xml which creates identical database contents but with a much smaller number of changesets. This changelog brings an empty database up to date. To ensure that it only runs on an empty database, I added a precondition:

select count(*) from DATABASECHANGELOG


3) I copied our current master changelog.xml to baseline-2012.6.xml. New monthly changelogs changelog-2012.7.xml and so forth will be appended to changelog.xml, but not to this baseline-2012.6.xml.

4) I use a combination of

update fastforward-2012.6.xml
changelogSync baseline-2012.6.xml
update changelog.xml

as a fast lane for creating and updating an SQL database.

changelogSync marks all changesets from the base line as run without actually running them. So when running changelog.xml in the last step, only the changesets newer than the baseline will be executed.

All this is integrated into our Maven build as three successive executions of the liquibase-maven-plugin, preceded by an sql-maven-plugin execution to (drop and re-)create an empty database.

Best regards,