質問

ノードの1つをマスターとして指定する必要があるクラスター化されたアプリケーションがあります。クラスターノードは、 nodeID isMaster lastTimestamp の列を持つテーブルで追跡されます。

クラスター内の各ノードは、 X 秒ごとにマスターになろうとします。ノードは、次のいずれかの場合にのみマスターになることができます

  • 他のマスターノードはありません
  • 現在のマスターノードの lastTimestamp 2 * X
  • だけ古い

上記の条件のいずれかが満たされた場合

  • 現在のマスターノードの isMaster をクリアする必要があります
  • 新しいマスターノードの isMaster を設定する必要があります
  • 新しいマスターノードの lastTimestamp は、「今」のタイムスタンプに設定する必要があります。

2つ以上のノードがマスターになることなく上記を達成するための単一(ポータブル)SQLステートメントとは何ですか?

役に立ちましたか?

解決

この種の調整は、通常、DBMSで実行されるアプリケーションではなく、DBMS自体によって処理されますか?私もおなじみのDBMSでそれを行う方法を構想することができますが、システムについて詳しくは知りません(おそらく共有ディスクを使用しているため、すべてのノードが同じデータを参照します。おそらく、同時アクセスを防止するロックプロトコルがあります。データに対して;定期的にlastTimestampを更新するのはマスターノード上のユーザープロセスですか)、多くのことを支援するのは難しいでしょう。また、Jamie Loveが指摘したように、DBMSでは、複数のプロセスが関連レコードへのアクセスを調整できるようにする必要があります。メインの関連レコードは現在のマスターレコードです。

[編集済み:読みすぎていたのかもしれません。

単一のUPDATEステートメントは、テーブルの2つの行で差分更新を行う必要があり、2つの更新のうち1つのみが可能な場合は失敗する必要があります。つまり、現在のマスターを非マスターに変更すると同時に、マスターになるように独自のレコードを変更する必要があります。 1つの問題は、DBMSが「1行のみがマスターになる」制約をどのように強制するかです。それが機能し、問題がある場合はステートメント全体が失敗すると想定しましょう-あるべきです。列名を提供する場合でも、なぜ人々はテーブル名を頻繁に省略するのですか?まあ、テーブル名は以下 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」フラグを持つ行が1つだけであることを保証するための(おそらく神話上の)制約があるため、マスターが最新の場合、これは必要に応じて失敗します。

テストされていないSQL!

]

他のヒント

Oracleデータベースのソリューションは想像できますが、移植性があるかどうかはわかりません。なぜこれは単一の移植可能なSQLステートメントである必要があるのですか?ほとんどのデータベースでは、テーブルのロックとトランザクションが許可されています。これにより、このようなことを複数のステートメントで実行できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top