这种协调通常不是由 DBMS 本身处理,而不是由运行在 DBMS 上的应用程序处理吗?我也可以设想在我熟悉的 DBMS 中执行此操作的方法,但对您的系统没有更多了解(它可能使用共享磁盘,因此所有节点都看到相同的数据;可能存在阻止并发访问的锁定协议到数据;是否是主节点上的用户进程定期更新 lastTimestamp),这将很难有多大帮助。而且,正如 Jamie Love 所指出的,DBMS 应该允许多个进程协调对相关记录的访问——主要的相关记录是当前的主记录。
[编辑:也许我读得太多了。
单个 UPDATE 语句必须对表的两行进行差异更新,并且如果两个更新中只有一个是可能的,则必须失败。也就是说,它必须既将当前的主服务器更改为非主服务器,也必须更改自己的记录,使其成为主服务器。一个问题是 DBMS 如何强制执行“只有一行可能是主”约束。让我们假设如果出现问题,它的工作原理和整个语句将失败 - 正如它应该的那样。为什么人们经常忽略表名,即使他们提供了列名?哦,好吧,表名以下是ClusterControl。每个节点必须以某种方式知道自己的 NodeID;我使用 {MyNodeID} 来指示它出现在 SQL 中的位置。
您需要单独的心跳更新:
UPDATE ClusterControl
SET lastTimestamp = CURRENT_TIMESTAMP
WHERE NodeID = {MyNodeID};
“获取主状态”更新可能是:
UPDATE ClusterControl
SET lastTimestamp = (CASE
WHEN NodeID = {MyNodeID} THEN CURRENT_TIMESTAMP
ELSE lastTimestamp END),
isMaster = (CASE
WHEN NodeID = {MyNodeId} THEN 'Y'
ELSE 'N' END)
WHERE (NodeID = {MyNodeID} AND isMaster = 'N') OR
(NodeID != {MyNodeID} AND
lastTimestamp < CURRENT_TIMESTAMP - INTERVAL '120' SECOND AND
isMaster = 'Y'
);
“获取主状态”更新背后的理论是(SET 子句):
- 新 master 的 lastTimestamp 字段设置为当前时间戳,但旧 master 保持不变。
- isMaster 字段更改为新主服务器的“Y”和旧主服务器的“N”。
WHERE 子句背后的理论是:
- 仅当当前节点不是当前节点且时间戳超过 120 秒(问题中的“2 * X”)时更改当前节点的记录,如果它不是当前主节点或当前主节点的记录.
由于有一个(可能是神话般的)约束来确保只有一行具有“Y”标志,因此当主服务器是最新的时,这应该会按要求失败。
未经测试的 SQL!
]