我在所有项目中都使用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
经过一番挖掘,我意识到与此同时,该团队正在使用DB Connection Pool。
application.properties
文件包含以下内容:spring.datasource.tomcat.initial-size=5
spring.datasource.tomcat.max-wait=20000
spring.datasource.tomcat.max-active=5
spring.datasource.tomcat.max-idle=5
spring.datasource.tomcat.min-idle=5
spring.datasource.tomcat.default-auto-commit=true
遗憾的是,我对DB Pool的了解不多。但是引起我注意的是关于
auto-commit
的最后一行。上一次出现此错误。我禁用所有这些行,该应用程序开始正常运行。我不知道这是否只是巧合。非常感谢你!
更新4
我回到正题...我不知道如何解决这个问题
更新5
我将mysql-connector-java更新为v8.0.15。我的服务器有MySQL v5.6.33。我仍然遇到此问题,现在无法重新启动我的应用程序。
完成上述更改后,现在异常以以下结尾:
The last packet successfully received from the server was 10,036 milliseconds ago. The last packet sent successfully to the server was 10,036 milliseconds ago.
.
.
.
Caused by: java.io.IOException: Socket is closed
at com.mysql.cj.protocol.AbstractSocketConnection.getMysqlInput(AbstractSocketConnection.java:72) ~[mysql-connector-java-8.0.15.jar!/:8.0.15]
at com.mysql.cj.protocol.a.NativeProtocol.clearInputStream(NativeProtocol.java:833) ~[mysql-connector-java-8.0.15.jar!/:8.0.15]
... 92 common frames omitted
更新6-替代解决方案
为了清楚起见,我决定通过在
liquibase.enabled=false
中设置application.properties
来禁用项目中的liquibase。现在,我可以随时启动/停止/重新启动应用程序了。由于我仅使用liquibase来维护数据库,并且执行了所做的更改(问题在于释放锁时),因此我将启用Liquibase只是为了更新架构,然后禁用它来运行应用程序更新7-我想我已经解决了
我不断重复地停止和启动应用程序,每次执行该操作时,我都会得到
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的情况下启动。我很高兴! :-)
最佳答案
你解决了吗?
我遇到了类似的问题,并通过强制Liquibase以同步模式执行来解决了该问题。
您的spring boot应用是否是由jhipster生成的?如果是这样,请查看DatabaseConfiguration并将其从AsyncSpringLiquibase更改为SpringLiquibase
关于mysql - Spring Boot + Liquibase:通信链接失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57154254/