用于指定集群主机的SQL语句

时间:2008-11-27 21:27:02

标签: sql cluster-computing

我有群集应用程序,需要将其中一个节点指定为主节点。群集节点在 nodeID isMaster lastTimestamp 列的表格中进行跟踪。

群集中的每个节点都会尝试每 X 秒成为主节点。如果

,节点只能成为主节点
  • 没有其他主节点
  • 当前主节点上的 lastTimestamp 较旧 2 * X

当满足上述条件之一时

  • 应清除当前主节点的 isMaster
  • 应设置新主节点的 isMaster
  • 新主节点的 lastTimestamp 应设置为“now”时间戳。

什么是单个(可移植)SQL语句来实现上述目标而不会有两个或更多节点成为主节点?

2 个答案:

答案 0 :(得分:1)

我可以想象一个Oracle数据库的解决方案,但我不确定它是否可移植。为什么这需要是一个可移植的SQL语句?大多数数据库允许表锁定和事务,它允许您在多个语句中执行此类操作。

答案 1 :(得分:1)

这种协调通常不是由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子句):

  • 新主服务器的lastTimestamp字段设置为当前时间戳,但旧主服务器未更改。
  • 新主设备的isMaster字段更改为“Y”,旧主设备更改为“N”。

WHERE子句背后的理论是:

  • 当此节点不是当前节点且当前节点不是当前节点并且时间戳超过120秒(当前节点中的“2 * X”)时,仅更改当前节点的记录(如果它不是当前节点或当前主节点的记录)问题)老。

由于存在一个(可能是神话般的)约束来确保只有一行具有'Y'标志,因此当主服务器是最新的时,这应该根据需要失败。

未经测试的SQL!