Archive for the ‘Useage’ Category.

What Effects ChangeSet Checksums?

We store an md5 checksum with each changeset entry in the database changelog table to detect differences between what is currently in the changelog and what was actually ran against the database.

We try to keep as many false-positives and false-negitives out of the process by taking only the database change related tags, normalizing the XML, and then creating the checksum.

That means that you can reformat your XML (for the most part) as well as add or change preconditions, contexts, and validCheckSum tags without effecting the checksum.  The only time that the xml reformat can cause problems is if a text block such as an <sql> tag is reformatted.

So don’t fear the checksum.  It is there to help you out and you can add information around already ran changesets without problems.  And if you do need to change your original changes, there are ways to deal with the checksum problems.

Dealing with Changing ChangeSets

The goal of a LiquiBase change log file is to track the linear sequence of changes required to take a database from a starting point to the current state, and it is built up one change at a time throughtout development. By following the “always append changes” rule you will ensure that all databases are consistent since all will have gone through the exact same set of changes.

If you go back and modify an old changeSet to incorporate a new change you will run into troubles because that change may have been ran against other databases and will not be ran again.  To alert you to this problem, LiquiBase stored checksums (md5 hashes) of each change that was ran.  If the checksum of a changeSet in the current changelog file is different than what was executed before, LiquiBase does not attempt to update anything.

That being said, things never go according to plan, and so LiquiBase has several options for dealing with changes to existing changeSets depending on your needs.  Generally I see 3 main reasons for a change:

Original Change Set was Wrong or Buggy

There are times when a change that was created wrong, especially if you are using the <sql> tag and have a complicated statement.  When you catch the problem, you are often not able to recover original data or structures, but want the change to be correct for new databases going forward.  In this case, it is best to use add a <validCheckSum> tag to the changeSet specifying that the new check sum is correct.  To know the check sum to specify, simply make your change and try to update a database.  The resulting verification error will include the new check sum.

Multiple change sets should be consolidated into a single change set

There are times when several change sets should be consolidated into a single change for performance reasons.  There has been talk on the mailing list about creating syntax support for this, but for now the best option is to simply remove the old change sets from the change log and create a new one.  To keep the new change set from being run on databases that have already made the change the old way, use the <changeSetExecuted> precondition.

Example:

<changeSet id=”163-new” author=”nvoxland”>
<preConditions onFail=”MARK_RAN”>
<not>
<changeSetExecuted id=”163″ author=”nvoxland” changeLogFile=”com/example/db.changelog.xml”/>
</not>
</preConditions>

……

</changeSet>

Change should never have been applied

Perhaps you should never have moved data, or dropped a table.  Whatevever the reason, there are times you want to reverse a done change set if it was executed and otherwise just skip it.  The best way to handle this is similar to the combining change sets above.  You simply delete the old changeSet from your changelog file and create a new changeset that will only run if the old changeset was ran.

Example:

<changeSet id=”163-undo” author=”nvoxland”>
<preConditions onFail=”MARK_RAN”>
<changeSetExecuted id=”163″ author=”nvoxland” changeLogFile=”com/example/db.changelog.xml”/>
</preConditions>

…..
</changeSet>

More Options

Beyond these options, there are several other tools available to use including the changeLogSync command, markNextChangeSetRan, preconditions based on the database state (<tableExists>, <sqlCheck> etc.), or even manually editing the databasechangelog table to add or remove tables