Issue Summary
- Bamboo logs are full of missing cluster_node_heartbeat table at logs when Server license is used.
- Calls to specific API methods are also failing such as rest/api/latest/server:
{"message":"error executing work; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: error executing work","status-code":500}%
Steps to Reproduce
- Bamboo with Server license applied
- Login to Bamboo
- Check application logs
Expected Results
Regular activity logs
Actual Results
The below exception is thrown in the atlassian-bamboo.log file:
2021-09-24 09:34:29,521 WARN [http-nio-8085-exec-4] [SqlExceptionHelper] SQL Error: 0, SQLState: 42P01 2021-09-24 09:34:29,521 ERROR [http-nio-8085-exec-4] [SqlExceptionHelper] ERROR: relation "cluster_node_heartbeat" does not exist Position: 54 2021-09-24 09:34:29,561 WARN [http-nio-8085-exec-4] [BambooRuntimeExceptionMapper] Unexpected error from REST call org.springframework.dao.InvalidDataAccessResourceUsageException: error executing work; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: error executing work at org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:193) at org.springframework.orm.hibernate5.HibernateTemplate.doExecute(HibernateTemplate.java:370) at org.springframework.orm.hibernate5.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:334) at com.atlassian.bamboo.persistence.BambooConnectionTemplate$1.doInTransactionWithoutResult(BambooConnectionTemplate.java:27) at org.springframework.transaction.support.TransactionCallbackWithoutResult.doInTransaction(TransactionCallbackWithoutResult.java:36) at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) at com.atlassian.bamboo.persistence.BambooConnectionTemplate.execute(BambooConnectionTemplate.java:24) at com.atlassian.bamboo.beehive.AbstractBambooRawJdbcDao.withDatabaseConnection(AbstractBambooRawJdbcDao.java:42) at com.atlassian.bamboo.beehive.BambooClusterNodeHeartBeatRawJdbcDao.findAll(BambooClusterNodeHeartBeatRawJdbcDao.java:115) at com.atlassian.bamboo.beehive.BambooClusterNodeHeartbeatServiceImpl.getNodeStatuses(BambooClusterNodeHeartbeatServiceImpl.java:107) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26) at com.sun.proxy.$Proxy660.getNodeStatuses(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.doInvoke(ServiceInvoker.java:56) at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.invoke(ServiceInvoker.java:60) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:137) at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.eclipse.gemini.blueprint.service.util.internal.aop.ServiceTCCLInterceptor.invokeUnprivileged(ServiceTCCLInterceptor.java:70) at org.eclipse.gemini.blueprint.service.util.internal.aop.ServiceTCCLInterceptor.invoke(ServiceTCCLInterceptor.java:53) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.eclipse.gemini.blueprint.service.importer.support.LocalBundleContextAdvice.invoke(LocalBundleContextAdvice.java:57) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:137) at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) at com.sun.proxy.$Proxy1043.getNodeStatuses(Unknown Source) at com.atlassian.bamboo.plugins.rest.resource.ServerResource.getServerStatusInfo(ServerResource.java:47) at com.atlassian.bamboo.plugins.rest.resource.ServerResource.getStatus(ServerResource.java:56) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Workaround
Create missing table manually. Make sure to create this table using the Bamboo database user.
MSSQL:
create table CLUSTER_NODE_HEARTBEAT (NODE_ID nvarchar(36), NODE_NAME nvarchar(255), HEARTBEAT_TIMESTAMP bigint, primary key (NODE_ID));
Oracle:
create table CLUSTER_NODE_HEARTBEAT (NODE_ID varchar2(36), NODE_NAME varchar2(255), HEARTBEAT_TIMESTAMP number(19,0), primary key (NODE_ID));
PostgreSQL, MySQL:
create table CLUSTER_NODE_HEARTBEAT (NODE_ID varchar(36), NODE_NAME varchar(255), HEARTBEAT_TIMESTAMP int8, primary key (NODE_ID));