Spring Boot + Liquibase:通信链接失败

时间:2019-07-22 21:55:42

标签: mysql spring-boot jdbc liquibase spring-jdbc

我在所有项目中都使用Liquibase,我真的很喜欢它处理数据库更新的方式,但是最近我遇到了这个问题:

liquibase                                : Successfully acquired change log lock
liquibase                                : Successfully released change log lock
liquibase                                : Could not release lock

liquibase.exception.LockException: liquibase.exception.DatabaseException: liquibase.exception.DatabaseException: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Communications link failure during rollback(). Transaction resolution unknown.
    at liquibase.lockservice.StandardLockService.releaseLock(StandardLockService.java:283) ~[liquibase-core-3.5.5.jar!/:na]
    at liquibase.Liquibase.update(Liquibase.java:218) [liquibase-core-3.5.5.jar!/:na]
    at liquibase.Liquibase.update(Liquibase.java:192) [liquibase-core-3.5.5.jar!/:na]
.
.
.
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Communications link failure during rollback(). Transaction resolution unknown.
.
.
liquibase                                : Failed to restore the auto commit to true
.
.
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 16,913 milliseconds ago.  The last packet sent successfully to the server was 89 milliseconds ago.
.
.
Caused by: java.lang.NullPointerException: null
    at com.mysql.jdbc.MysqlIO.clearInputStream(MysqlIO.java:899) ~[mysql-connector-java-5.1.46.jar!/:5.1.46]
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2477) ~[mysql-connector-java-5.1.46.jar!/:5.1.46]

我的服务器上正在运行3个应用程序。其中一个运行了大约2年。第二次运行了2个月,第三个运行了。

它们都是Spring Boot应用程序。

当我想更新第二个应用程序的jar时,这开始发生,我停止了旧的jar,运行新的jar,但我无法使它从上面的错误开始。 然后,我运行同一应用程序的旧jar,它开始正常。我尝试停止并重新启动这个旧的jar,有几次我得到了上面的错误,但大多数情况下它就很好了。

我尝试重新启动服务器(所有三个应用程序均作为系统启动的服务启动),但由于相同的错误,它们均未成功启动。连两年都没有。我停止了所有其他应用程序,然后尝试使用这个持久的应用程序,直到启动它一直失败。

这可能是内存问题吗?我正在使用具有1核心和2gb RAM的DigitalOcean小滴。

另外,我注意到的是,当它成功启动日志时,它看起来像:

liquibase                                : Successfully acquired change log lock
liquibase                                : Reading from myDataBase.DATABASECHANGELOG
liquibase                                : Successfully released change log lock

请注意在获取和释放锁之间的语句。我还怀疑在获取锁和读取变更日志之间存在时间问题。但是不知道我是否可以增加时间或如何增加时间。

更新

我不知道问题的根源,但是在将liquibase-core更新为 v3.7.0 之后,所有应用都正确启动了

更新2

关于以前的更新,我正在测试,因为不是解决问题,而是减少了频率。但这确实发生了

3 个答案:

答案 0 :(得分:0)

您解决了吗?

我遇到了类似的问题,并通过强制Liquibase以同步模式执行来解决了该问题。 您的spring boot应用是否是由jhipster生成的?如果是这样,请查看DatabaseConfiguration并从AsyncSpringLiquibase更改为SpringLiquibase

答案 1 :(得分:0)

我不断重复地停止和启动应用程序,每次执行时我都得到Socket is closed,所以我开始着眼于时间问题...从引发的异常中我注意到,每次它说:

  

从服务器成功接收到的最后一个数据包是在xxxx毫秒之前。

在几毫秒前,我得到的最小值是 10.085 ,并且偶然地,我从同一时间获得了同一应用的一些日志,而该问题从未出现过。从这些日志语句中,我可以测量获取更改日志锁和释放它之间的时间。令我惊讶的是,它只有 9秒,而且从未超过。

所以我登录到mysql控制台并发出:

show variables LIKE '%timeout%';

哪个给了我一个定义的超时列表。而且, connect_timeout 最小,设置为 10秒。一定是这样。

我搜索了如何设置该值。我尝试创建文件/etc/my.cnf并将其添加到其中:

[mysqld]
connect_timeout=20

然后使用以下命令重新启动mysql:

sudo /etc/init.d/mysql restart

但是当我重新登录到mysql控制台时,该值仍为 10 。因此,在mysql控制台中,我发出了另一个命令:

SET GLOBAL connect_timeout=20;

值已更新(我不知道在服务器完全重启后该值是否还会持续)

我再次重新启动mysql,然后...!现在,这些应用程序通常在启用liquibase的情况下启动。我很高兴! :-)

答案 2 :(得分:0)

我们正在使用MySQL 8.0.19 。对我来说,这只是一个曾经失败的查询,但发生了Caused by: java.io.IOException: Socket is closed异常。

发现对于MySQL 8.0.19 ,存在一个与我的堆栈跟踪类似的错误-https://bugs.mysql.com/bug.php?id=99234

将MySQL服务器升级到 8.0.21 后,它开始工作!没有其他更改。

希望它对那些花了很多时间选择查询而不起作用并且具有相同错误并尝试了各种其他选择的人们有所帮助。