Thanks for answering the question.
We did update the version of liquibase version and it is 3.41.
Below is the databasechangelog record for the existing changeset which is failing.
id | author | filename | dateexecuted | orderexecuted | exectype | md5sum | description | comments | tag | liquibase | contexts | labels |
my_table_index_column1_alt | o | db/my_app_databasechange_log.sql | 12:15.8 | 168 | EXECUTED | 7:b7cfd7492431756ad5b4ee5ea769202f | sql | NULL | 3.4.1 | NULL | NULL |
I was trying to understand the root cause for the below checksum validation exception.
[JCD] 2019-11-07 16:29:55.366739: [0;39m[30m16:29:55.233[0;39m [34mINFO [0;39m [30m[product-service][0;39m - [34m2019-11-07T16:29:32.85+0000 [APP/PROC/WEB/1]OUT {"time":"2019-11-07T16:29:32.853+00:00","corr":"","tnt":"","cross-tnt":"","appn":"","subj":"","oper":"","rslt":"","dpmt":"","inst":"","span":"","prnt":"","expt":"","tid":"localhost-startStop-1","mod":"com.mycomp.product.service.utilities.DbUtil","lvl":"ERROR","msg":"Failed to execute ","exception":"liquibase.exception.ValidationFailedException: Validation Failed:\n 1 change sets check sum\n db/my_app_databasechange_log.sql::my_table_index_column1_alt::o is now: 7: b7cfd7492431756ad5b4ee5ea769202f\n\n\tat com.mycomp.product.service.config.SchemaUpgrader.configureSchema(SchemaUpgrader.java:178)\n\tat com.mycomp.product.service.config.SchemaUpgrader.upgradeSchema(SchemaUpgrader.java:72)\n\tat com.mycomp.product.service.config.SchemaUpgrader.call(SchemaUpgrader.java:51)\n\t... 4 common frames omitted\nWrapped by: java.util.concurrent.ExecutionException: com.mycomp.product.service.service.ServiceException: Validation Failed:\n 1 change sets check sum\n db/my_app_databasechange_log.sql::my_table_index_column1_alt::o is now: 7:b7cfd7492431756ad5b4ee5ea769202f\n\n\tat java.util.concurrent.FutureTask.report(FutureTask.java:122)\n\tat java.util.concurrent.FutureTask.get(FutureTask.java:192)\n\tat com.mycomp.product.service.utilities.DbUtil.lambda$waitForFutures$0(DbUtil.java:320)\n\tat java.util.ArrayList.forEach(ArrayList.java:1257)\n\tat com.mycomp.product.service.utilities.DbUtil.waitForFutures(DbUtil.java:318)\n\tat com.mycomp.product.service.config.DbUpgrader.upgrade(DbUpgrader.java:53)\n\tat com.mycomp.product.service.config.DbUpgrader.<init>(DbUpgrader.java:41)\n\tat com.mycomp.product.service.config.SmarterRoutingDataSource.<init>(SmarterRoutingDataSource.java:42)\n\tat com.mycomp.product.service.config.AlertsCloudConfig.dataSource(AlertsCloudConfig.java:43)\n\tat com.mycomp.product.service.config.AlertsCloudConfig$$EnhancerBySpringCGLIB$$f6d098fd.CGLIB$dataSource$1(<generated>)\n\tat com.mycomp.product.service.config.AlertsCloudConfig$$EnhancerBySpringCGLIB$$f6d098fd$$FastClassBySpringCGLIB$$391e0291.invoke(<generated>)\n\tat org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)\n\tat org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358)\n\tat com.mycomp.product.service.config.AlertsCloudConfig$$EnhancerBySpringCGLIB$$f6d098fd.dataSource(<generated>)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n\tat java.lang.reflect.Method.invoke(Method.java:498)\n\tat org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)\n\tat org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1177)\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1072)\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511)\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481)\n\tat org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)\n\tat org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)\n\tat org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)\n\tat org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1131)\n\tat org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1059)\n\tat org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)\n\tat org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)\n\tat org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:467)\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1177)\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1072)\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511)\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481)\n\tat org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)\n\tat org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)\n\tat org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1082)\n\tat org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:857)\n\tat org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)\n\tat org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:124)\n\tat org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)\n\tat org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)\n\tat org.springframework.boot.SpringApplication.run(SpringApplication.java:303)\n\tat org.springframework.boot.web.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:156)\n\tat org.springframework.boot.web.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:136)\n\tat org.springframework.boot.web.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:91)\n\tat org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169)\n\tat org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5245)\n\tat org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)\n\tat org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:754)\n\tat org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730)\n\tat org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)\n\tat org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1140)\n\tat org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1875)\n\tat java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)\n\tat java.util.concurrent.FutureTask.run(FutureTask.java:266)\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\n\tat java.lang.Thread.run(Thread.java:748)\n"}
Ideally both should be equal as i did not modify that changeset and should not throw any exception.
That is why I am printing the old(ranChangeSet.getLastChecksum) and new checksum(changeset.generateChecksum) values for comparison in the catch block highlighted.
Below is my method for migration
private void configureSchema(Connection connection) throws SQLException {
logger.info("Beginning schema configure");
if (System.getenv("SKIP_LIQUIDB") != null){
logger.info("skipping liquidb due to setup");
return;
}
connection.setAutoCommit(false);
Database database = null;
Liquibase liquibase = null;
try {
logger.error("creating liquidb");
System.setProperty("liquibase.changeLogLockWaitTimeInMinutes", "1");
logger.error("Value of system property liquibase.changeLogLockWaitTimeInMinutes {}", System.getProperty("liquibase.changeLogLockWaitTimeInMinutes"));
database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection));
liquibase = new liquibase.Liquibase("db/my_app_databasechange_log.sql", new ClassLoaderResourceAccessor(), database);
logger.error("upgrading liqui");
liquibase.update(new Contexts(), new LabelExpression());
} catch (LockException e) {
logger.error("LockException exception running Liquibase script " + e.getMessage(), e);
try {
liquibase.forceReleaseLocks();
} catch (LiquibaseException e1) {
e1.printStackTrace();
logger.error("",e1);
}
logger.error("DB changelog lock forcefully released");
} catch (Exception e) {
if(e instanceof ValidationFailedException) {
ValidationFailedException validationFailedException = (ValidationFailedException) e;
if(validationFailedException.getInvalidMD5Sums() !=null) {
Database finalDatabase = database;
validationFailedException.getInvalidMD5Sums().forEach(changeSet -> {
try {
finalDatabase.getRanChangeSetList().forEach((ranChangeSet -> {
if(ranChangeSet.getId().equals(changeSet.getId())){
logger.error("db changeset id:: " +ranChangeSet.getId()
+ " checksum:: "+ranChangeSet.getLastCheckSum() + "\n current changeset id:: " + changeSet.getId() +" current checksum:: "+ changeSet.generateCheckSum());
}
})
);
} catch (DatabaseException e1) {
e1.printStackTrace();
}
});
}
}
logger.error("", e);
throw new ServiceException(ErrorCode.SCHEMA_INIT_FAILURE, e.getMessage());
} finally {
if (database != null){
try {
database.close();
logger.info("closed liquib successfully");
} catch (DatabaseException e) {
logger.warn("",e);
}
}
}
}
But old checksum is printed a different value(not) which is not even there in the databasechangelog table.
I expected ranChangeSet.getLastChecksum should give the value what is there in the database i.e 7:b7cfd7492431756ad5b4ee5ea769202f but not sure why it printed a different value 7:31ca124527c4ca9f5a9c2aa06c03a1dc
and the printed new checksum value is same as database checksum value i.e 7:b7cfd7492431756ad5b4ee5ea769202f
Below is the log printed :
db ran changeset id:: my_table_index_column1_alt checksum:: 7:31ca124527c4ca9f5a9c2aa06c03a1dc
current changeset id:: my_table_index_column1_alt current checksum:: 7:b7cfd7492431756ad5b4ee5ea769202f