使用基於語句的複製時,在來源上執行的觸發器也會在副本上執行。使用基於列的複製時,在來源上執行的觸發器不會在副本上執行。相反地,來源上因觸發器執行而產生的資料列變更會被複製並套用至副本。
此行為是設計使然。如果在基於列的複製下,副本同時套用觸發器以及它們所導致的資料列變更,則變更實際上會在副本上套用兩次,導致來源和副本上的資料不同。
如果您希望在來源和副本上都執行觸發器,可能是因為您在來源和副本上有不同的觸發器,則必須使用基於語句的複製。但是,若要啟用副本端觸發器,並非必須完全使用基於語句的複製。只需針對您希望產生此效果的那些陳述式切換到基於語句的複製,並在其他時間使用基於列的複製就足夠了。
使用基於語句的複製時,叫用會導致更新 AUTO_INCREMENT
資料行的觸發器(或函數)的陳述式無法正確複製。MySQL 9.0 會將此類陳述式標記為不安全。(錯誤 #45677)
觸發程序可以針對不同的觸發事件組合(INSERT
、UPDATE
、DELETE
)和動作時間(BEFORE
、AFTER
)設定觸發程序,並且允許存在多個觸發程序。
為了簡潔起見,此處的「多個觸發程序」是「具有相同觸發事件和動作時間的多個觸發程序」的簡寫。
升級。 在 MySQL 5.7 之前的版本中,不支援多個觸發程序。如果您在使用早於 MySQL 5.7 版本的複製拓樸中升級伺服器,請先升級副本,然後再升級來源。如果升級後的複製來源伺服器仍有使用不支援多個觸發程序的舊版 MySQL 的副本,則當來源在已經有具有相同觸發事件和動作時間的觸發程序的表上建立觸發程序時,這些副本會發生錯誤。
降級。 如果您將支援多個觸發程序的伺服器降級到不支援的較舊版本,則降級會產生以下影響:
對於每個具有觸發程序的表,所有觸發程序定義都位於該表的
.TRG
檔案中。但是,如果有具有相同觸發事件和動作時間的多個觸發程序,則伺服器在觸發事件發生時只會執行其中一個。有關.TRG
檔案的資訊,請參閱 MySQL 伺服器 Doxygen 文件中的「表觸發程序儲存」部分,該文件位於 https://mysqldev.dev.org.tw/doc/index-other.html。如果在降級後添加或刪除表的觸發程序,伺服器會重寫該表的
.TRG
檔案。重寫後的檔案只會保留每個觸發事件和動作時間組合的一個觸發程序;其他觸發程序會遺失。
為了避免這些問題,請在降級之前修改您的觸發程序。對於每個具有每個觸發事件和動作時間組合有多個觸發程序的表,請將每個此類觸發程序集轉換為單個觸發程序,如下所示:
針對每個觸發程序,建立一個儲存常式,其中包含觸發程序中的所有程式碼。可以使用參數將使用
NEW
和OLD
存取的值傳遞給常式。如果觸發程序需要程式碼的單個結果值,您可以將程式碼放入儲存函數中,並讓函數傳回值。如果觸發程序需要程式碼的多個結果值,您可以將程式碼放入儲存程序中,並使用OUT
參數傳回這些值。刪除該表的所有觸發程序。
為該表建立一個新的觸發程序,以調用剛建立的儲存常式。因此,此觸發程序的效果與其取代的多個觸發程序相同。