Mysql

MySQL master 到 master 競爭條件,我需要為這段程式碼使用事務/鎖嗎?

  • May 13, 2020

我正在使用 master 到 master MySQL 複製,希望我可以在兩個不同伺服器上的 C# 應用程序上執行兩個副本,以幫助提高性能。而不是我目前擁有的一台伺服器上的一份副本。

但是,我很難理解 MySQL 如何防止或處理競爭條件並維護數據庫的完整性。例如,我的應用程序具有類似於以下的程式碼。

SELECT 100 TASKS TO PROCESS

UPDATE THE 100 TASKS TO SAY WE'RE WORKING ON THEM

INSERT THE RESULTS OF THE 100 TASKS INTO THE DATABASE

因為上面的程式碼執行如此頻繁,最終我的應用程序將嘗試處理已被我的應用程序的另一個實例“選擇”但尚未“更新”的任務,當它這樣做時,它將嘗試“插入”數據已經插入,這會產生唯一的關鍵錯誤,從而破壞 MySQL 主控複製。

我可以從這個答案中看到 mysql 實例看起來非常獨立,並且似乎不知道彼此的鎖/事務。

https://stackoverflow.com/questions/36026769/transactions-between-two-replicating-master-mysql-servers

我可以看到我可以使用下面的配置禁用唯一鍵錯誤,但我不確定這是否會導致比修復更多的問題。

slave-skip-errors=1169

這是我可以通過鎖和事務避免的嗎?

或者這只是主到主複製的一部分,我必須圍繞這個設計我的應用程序?

簡而言之 - 是的,您必須以一種能夠抵抗競爭條件的方式來設計您的應用程序。交易不會幫助你解決這個問題。

幾條評論…

  • Master-Master 不會有太大幫助——對一個 master 的所有寫入都被“複製”到另一個 master。因此,您不會獲得太多的寫入縮放。
  • 兩個客戶端(甚至 N 個客戶端)可以在一個主伺服器上競爭。但是這種爭用很容易通過事務處理。
  • 一個人UPDATE可以原子地抓取 100 個任務。

一條建議:

Loop:
   UPDATE Tasks SET who_has = $me
       WHERE ... -- if filtering needed
       ORDER BY ... -- if needed
       LIMIT 100;
   SELECT * FROM Tasks WHERE who_has = $me;
   process the tasks
   UPDATE Tasks SET who_has = NULL ...
       WHERE ... -- either all 100 or one at a time;
end_loop.

如果“任務”可能相互干擾,則使用BEGIN...COMMIT. 但是讓我們討論一下它的細節。簡單INSERTs的可以毫不費力地完成。

引用自:https://dba.stackexchange.com/questions/267106