Есть ли конфигурация для автоматического удаления LiquiBase DATABASE CHANGELOGLOCK через определенное время или при перезапуске приложения? - PullRequest
0 голосов
/ 04 августа 2020

У нас есть приложение HA java, управляемое SpringBoot 2, в котором мы используем PostgreSQL внизу.

По определенным причинам, таким как неожиданные сбои или исключения, Liquibase получает устаревший DATABASECHANGELOGLOCK, который так и не был выпущен.

Это приводит к сбою последующих развертываний приложения, когда приложение ожидает блокировки изменений, а затем завершается следующим образом:

   2020-03-04T11:10:31.78+0200 SELECT LOCKED FROM public.databasechangeloglock WHERE ID=1
   2020-03-04T11:10:31.78+0200 Waiting for changelog lock....
   2020-03-04T11:10:32.87+0200 SELECT LOCKED FROM public.databasechangeloglock WHERE ID=1
   2020-03-04T11:10:32.87+0200 Waiting for changelog lock....
   2020-03-04T11:10:41.78+0200 SELECT LOCKED FROM public.databasechangeloglock WHERE ID=1
   2020-03-04T11:10:41.78+0200 Waiting for changelog lock....
   2020-03-04T11:10:42.87+0200 SELECT LOCKED FROM public.databasechangeloglock WHERE ID=1
   2020-03-04T11:10:42.87+0200 Waiting for changelog lock....
   2020-03-04T11:10:51.79+0200 SELECT LOCKED FROM public.databasechangeloglock WHERE ID=1
   2020-03-04T11:10:51.79+0200 Waiting for changelog lock....
   2020-03-04T11:10:52.88+0200 SELECT LOCKED FROM public.databasechangeloglock WHERE ID=1
   2020-03-04T11:10:52.88+0200 Waiting for changelog lock....
   2020-03-04T11:10:54.00+0200 ERR 2020-03-04 09:10:54.010 UTC
   2020-03-04T11:10:55.88+0200 [HEALTH/0] ERR Failed to make TCP connection to port 8080: connection refused
   2020-03-04T11:10:55.88+0200 [CELL/0] ERR Failed after 1m0.626s: readiness health check never passed.
   2020-03-04T11:10:55.89+0200 [CELL/SSHD/0] OUT Exit status 0
   2020-03-04T11:10:55.89+0200 info    [native] Initiating shutdown sequence for Java agent
   2020-03-04T11:10:55.89+0200 info    [] Connection Status (120 times 300s)      : 0909

Существует ли конфигурация для автоматического удаления Liquibase DATABASECHANGELOGLOCK через определенное время или удаление его при запуске приложения, если оно старше, скажем, 5 минут или предопределенного периода времени. Или это можно сделать программно при запуске приложения до того, как Postgres начнет искать блокировку изменений.

1 Ответ

0 голосов
/ 11 августа 2020

Итак, я смог достичь этого с помощью следующего подхода:

Мы инициализируем LiquiBase с помощью bean-компонента SpringLiquibase.

В этом bean-компоненте, перед созданием экземпляра Liquibase, я вызвал метод который использует операторы для запроса к базе данных о блокировке, и если есть какие-либо lcoks старше 5 минут, мы их удаляем.

 @Bean
 public SpringLiquibase liquibase(DataSource dataSource) {
        // Added a hook to check for locks before LiquiBase initialises.
        removeDBLock(dataSource);
        //
        SpringLiquibase liquibase = new SpringLiquibase();
        liquibase.setChangeLog(Constants.DDL_XML);
        liquibase.setDataSource(dataSource);
        return liquibase;
    }



 private void removeDBLock(DataSource dataSource) {
   
    //Timestamp, currently set to 5 mins or older.

    final Timestamp lastDBLockTime = new Timestamp(System.currentTimeMillis() - (5 * 60 * 1000));
    
    final String query = format("DELETE FROM DATABASECHANGELOGLOCK WHERE LOCKED=true AND LOCKGRANTED<'%s'", lastDBLockTime.toString());
    

    try (Statement stmt = dataSource.getConnection().createStatement()) {

        int updateCount = stmt.executeUpdate(query);
        if(updateCount>0){
            log.error("Locks Removed Count: {} .",updateCount);
        }
    } catch (SQLException e) {
        log.error("Error! Remove Change Lock threw and Exception. ",e);
    }
}
...