Оператор SQL для назначения мастера кластера

StackOverflow https://stackoverflow.com/questions/324677

  •  11-07-2019
  •  | 
  •  

Вопрос

У меня есть кластерные приложения, для которых требуется, чтобы один из узлов был назначен главным.Узлы кластера отслеживаются в таблице с идентификатор узла, isMaster, последняя временная метка столбцы.

Каждый узел кластера будет пытаться стать мастером каждый раз. Икс секунды.Узел может стать мастером только в том случае, если

  • других мастер-нод нет
  • тот последняя временная метка текущий главный узел старше на 2*Х

Когда одно из вышеперечисленных условий выполнено

  • текущий главный узел isMaster должен быть очищен
  • новый главный узел isMaster должен быть установлен
  • новый главный узел последняя временная метка должна быть установлена ​​временная метка «сейчас».

Что одинокий (переносимый) оператор SQL для достижения вышеуказанного без возможности того, чтобы два или более узлов стали главными?

Это было полезно?

Решение

Разве такая координация обычно не осуществляется самой СУБД, а не приложениями, работающими в СУБД?Я тоже могу представить способы сделать это в знакомой мне СУБД, но не знаю больше о вашей системе (предположительно, она использует общие диски, поэтому все узлы видят одни и те же данные;предположительно существуют протоколы блокировки, которые предотвращают одновременный доступ к данным;это пользовательский процесс на главном узле, который периодически обновляет LastTimestamp), будет сложно помочь.И, как отметил Джейми Лав, СУБД должна позволять нескольким процессам координировать доступ к соответствующим записям, причем основной соответствующей записью является текущая основная запись.

[Отредактировано:Возможно, я слишком много придавал этому значения.

Один оператор UPDATE должен выполнять дифференциальные обновления двух строк таблицы и должен завершиться неудачно, если возможно только одно из двух обновлений.То есть он должен одновременно изменить текущий мастер на неглавный, а также изменить свою собственную запись, чтобы он стал главным.Одна из проблем заключается в том, как СУБД обеспечивает соблюдение ограничения «только одна строка может быть главной».Давайте предположим, что это работает, и оператор в целом потерпит неудачу, если возникнет проблема - как и должно быть.Почему люди так часто опускают имя таблицы, даже если указывают имена столбцов?Да ладно, название таблицы здесь и далее КластерКонтроль.Каждый узел должен каким-то образом знать свой собственный NodeID;Я использовал {MyNodeID}, чтобы указать, где он появляется в SQL.

Вам нужно отдельное обновление Heartbeat:

 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!

]

Другие советы

Я могу представить решение для базы данных Oracle, но не уверен, что оно будет переносимым.Почему это должен быть один переносимый оператор SQL?Большинство баз данных допускают блокировку таблиц и транзакции, что позволяет вам делать подобные вещи в нескольких операторах.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top