You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Liquibase Version:
3.10.x, 4.0.x, 4.1.x Liquibase Integration & Version: <Pick one: CLI, maven, gradle, spring boot, servlet, etc.>
All affected Database Vendor & Version:
Some parts is specific for Oracle, DB2 or Derby, others are vendor independent Operating System Type & Version:
OS independent
Description
When liquibase run on clean schema it creates and initializes DatabaseChangeLogLock table before it can use it's standard locking mechanism. In clustered environment, applications can be deployed for the first time to multiple nodes at same time. This initialization process is not protected against race conditions.
Table creation part of this issue is already mentioned here: https://liquibase.jira.com/browse/CORE-2596
It tried to fix the problem by parsing the database error message for table already exists condition.
catch (DatabaseException e) {
if ((e.getMessage() != null) && e.getMessage().contains("exists")) {
//hit a race condition where the table got created by another node.
}
This solution does not work with all database and/or non English environment. A bug already reported here: #1036
DatabaseChangeLogLock table content initialization (insert) can fail with primary key violated error if another node inserts this record between selecting and inserting operations.
On Derby and DB2 database a DatabaseChangeLogLock table recreation can happen if it has wrong column type. It can delete an already acquired lock so can bypass locking.
Possible solutions:
Forbid running 'update' on schemas without DatabaseChangeLogLock table
Make liquibase table initialization process protected from race conditions
For the latter, i would suggest:
Generalizing race condition handling in DatabaseChangeLogLock table initialization:
check table/record existence
create/insert if table/record does not exist
Retry (GOTO 1) once if table creation or record insertion fails
Change DatabaseChangeLogLock table modification to table alter instead of drop/recreate and move it to the synchronized section (do it while having the lock)
Steps To Reproduce
Run multiple instances of liquibase update on an empty database schema at same time
Actual Behavior
Sometimes create table DATABASECHANGELOGLOCK fails with 'table already exists' error (On oracle database)
Sometimes insert into DATABASECHANGELOGLOCK fails with 'primary key violated' error
Sometimes multiple nodes start updating the schema (On Derby and Db2)
Sometimes liquibase creates and initializes it's tables successfully
Expected/Desired Behavior
Liquibase always creates and initializes it's tables successfully
The text was updated successfully, but these errors were encountered:
The PR ist ready for review and in my local tests I was able to start five instances of a service at the same time on a fresh DB. None of these instances crashes anymore.
Environment
Liquibase Version:
3.10.x, 4.0.x, 4.1.x
Liquibase Integration & Version: <Pick one: CLI, maven, gradle, spring boot, servlet, etc.>
All affected
Database Vendor & Version:
Some parts is specific for Oracle, DB2 or Derby, others are vendor independent
Operating System Type & Version:
OS independent
Description
When liquibase run on clean schema it creates and initializes DatabaseChangeLogLock table before it can use it's standard locking mechanism. In clustered environment, applications can be deployed for the first time to multiple nodes at same time. This initialization process is not protected against race conditions.
Table creation part of this issue is already mentioned here: https://liquibase.jira.com/browse/CORE-2596
It tried to fix the problem by parsing the database error message for table already exists condition.
This solution does not work with all database and/or non English environment. A bug already reported here: #1036
DatabaseChangeLogLock table content initialization (insert) can fail with primary key violated error if another node inserts this record between selecting and inserting operations.
On Derby and DB2 database a DatabaseChangeLogLock table recreation can happen if it has wrong column type. It can delete an already acquired lock so can bypass locking.
Possible solutions:
For the latter, i would suggest:
Steps To Reproduce
Run multiple instances of liquibase update on an empty database schema at same time
Actual Behavior
Expected/Desired Behavior
The text was updated successfully, but these errors were encountered: