我有一个多节点生产服务器(CentOS 7.x上的Tomcat 8.x;每个节点都是一个单独的CentOS实例),它使用一个MySQL数据库服务器(MySQL 5.7.x)。服务器的每个节点都将手动更新:系统管理员停止每个节点并部署新版本的应用程序(.war
文件)。这意味着该服务不会有停机时间,因为每时每刻都至少有一个工作节点。
数据库迁移是使用Liquibase变更集实现的,它们放在.war
文件中。因此,每个节点都验证并更新(如果需要)数据库模式。实际上,只有第一个节点执行变更集,而其他节点只是验证它。
问题是每个节点的更新之间存在时间差:当第一个节点已经使用新的应用程序版本更新时,最后一个节点仍然可以使用以前的应用程序版本(可能使用数据库中的旧列)例)。这可能会导致数据库不一致。
示例
假设服务器有3个节点。此时他们正在处理N版本的应用程序。
下一版本需要更改数据库架构:将列title
重命名为title_new
。
为了能够在不停机的情况下更新数据库架构,我们需要使用"两步更改":
title_new
,title
(标记为已弃用); title
中的所有数据复制到title_new
; title_new
; title
。现在管理员将部署版本N + 1。他停止第一个节点进行更新,但其他两个节点仍在使用版本N.当第一个节点正在更新时,一些用户可能会使用节点2或3更改其数据(有一个负载均衡器,将请求路由到不同的节点)。因此,我们需要一种方法来禁止用户通过节点2和3进行任何更改,而不会使用版本N + 1进行更新。
我认为有两种不同的方法可以解决这个问题:
read_only
模式 - 然后应用程序逻辑禁止用户进行任何更改。但是,我们需要使用控制台或管理面板随时实现某些启用此模式的方法(必须允许管理员启用此模式)。read_only
模式。但我无法找到任何可供MySQL使用的方法。问题:解决上述问题的最佳方法是什么?
P.S。应用程序基于Spring 4.x框架+ Hibernate 4.x。
答案 0 :(得分:1)
解决此问题的另一种方法可能是:"使用数据库触发器":
版本N + 1:
版本N + 2:
这种方法的优点是:
缺点:
答案 1 :(得分:0)
我发现上面的文章对于没有停机的数据库迁移的各种选项非常有见地。