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