我應該在 mysql 的從屬設備中禁用觸發器和時間戳嗎?
我們正在使用 MySQL。我們有一個主人,最終會有兩個奴隸。當某些表中的數據發生變化時,數據庫中有觸發器會執行。我想知道是否禁用從屬中的觸發器。在我看來,我應該這樣做。似乎時間戳之類的東西應該在從站中禁用,否則從站上的數據將不同於主站上的數據。
我不是 DBA,我是開發人員。我們公司沒有 DBA,所以我和運維管理員正在解決這個問題。我們已經設置了主伺服器和一個從伺服器並進行了複製,並且我們在從伺服器上收到了重複條目錯誤。
我們正在考慮不要因為重複複製錯誤而停止複制,如這篇文章:http ://www.ducea.com/2008/02/13/mysql-skip-duplicate-replication-errors/ 。我們不知道這是否是個好主意。我確實覺得這掩蓋了問題,但我們都不知道如何解決問題。
如果我們應該禁用觸發器和/或設置從屬設備不插入時間戳,我們該怎麼做呢?還是建立一個數據庫作為奴隸自動做這些事情呢?
不要禁用從屬伺服器上的觸發器,也不要將從屬伺服器配置為跳過錯誤。
當使用一致的數據集和相同的配置(包括表及其數據、視圖、觸發器、儲存函式和儲存過程)正確設置複製時,它就可以正常工作。如果它不是“正常工作”,那麼它已經在其中一種方式上不一致。重複鍵錯誤是一個危險信號,表明您的數據不相同,您不想抑制這一點。
如果你還沒有,你應該使用
binlog_format
=MIXED
除非你有特定的理由不這樣做。MySQL 5.6 之前的預設值是STATEMENT
,但這主要是出於遺留原因。使用混合日誌記錄允許主節點上的優化器選擇記錄對主節點數據的每次更改的最佳方式——通過:
- 記錄您的客戶端發送給主伺服器的文字和準確查詢,以便從伺服器可以執行相同的查詢,從而修改它們的數據(基於語句的日誌記錄),或者
- 記錄在主伺服器上更改的特定行,以便從伺服器可以更改受影響表中的相同行,而不考慮導致更改的實際查詢(基於行的日誌記錄)。
MIXED
如果一個語句被確定為基於語句的日誌記錄是“不安全的”(這意味著它可能會導致數據偏離其初始相同狀態),如果您使用的是模式,它將自動記錄為基於行。這方面的例子是涉及對非確定性函式的呼叫的語句,例如UUID()
它將在主伺服器和從伺服器上返回不同的值。基於行的日誌可以毫無問題地處理這個問題,因為它傳遞了文字值。你可能認為
NOW()
也可能是這樣的功能,如果伺服器時鐘不同步,類似的限制可能適用於自動時間戳列,但事實並非如此——因為對於每個二進制(複製)日誌條目,主節點都會記錄其內容目前時間戳是執行查詢的時間——允許從屬設備擁有一個“偽系統時鐘”,以便在需要時執行該語句時實際捏造主控時鐘的值。順便說一句,這個日誌條目是從伺服器如何通過將其係統時鐘與記錄的時間戳進行比較來計算“落後於主伺服器的秒數”的。(例外情況是,當從伺服器執行了中繼日誌中的所有內容時,它總是顯示“0”秒後,因為它沒有如果使用基於行的日誌記錄查詢,則觸發器更改的任何數據也將記錄為基於行的日誌條目,並且從屬設備上的觸發器將自動不觸發。
另一方面,如果使用基於語句的日誌記錄相同的查詢,則複製取決於從屬伺服器上存在的相同觸發器,因為主伺服器不會記錄觸發器所做的事情——它只記錄發出的查詢,並且假設您希望所有伺服器上的數據保持一致,則取決於從屬觸發器的觸發方式與它們在主伺服器上的觸發方式完全相同。
使用基於語句的複制,在主伺服器上執行的觸發器也會在從伺服器上執行。使用基於行的複制,在主伺服器上執行的觸發器不會在從伺服器上執行。相反,由觸發器執行導致的主伺服器上的行更改被複製並應用於從伺服器。
此行為是設計使然。
$$ … $$
http://dev.mysql.com/doc/refman/5.5/en/replication-features-triggers.html
該文件通常以聽起來像是非此即彼(語句或行)的術語來談論複製,但是對於每個查詢執行
MIXED
的日誌記錄將在每個查詢的基礎上選擇日誌記錄方法。您可能還會發現在某些情況下“需要”基於行的日誌記錄的語句,但這僅意味著它必須可用(即 viaMIXED
);這並不意味著伺服器必須配置為ROW
. 當然,無論二進制日誌格式如何,DDL 總是被記錄為語句。