程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQL 5.6 主從復制如何處理——觸發器,函數,存儲過程,調度事件

MySQL 5.6 主從復制如何處理——觸發器,函數,存儲過程,調度事件

編輯:MySQL綜合教程

MySQL 5.6 主從復制如何處理——觸發器,函數,存儲過程,調度事件



截圖來自MySQL5.6的pdf版文檔。   說明:   1)基於語句的復制時,trigger會在slave上執行,所以slave上也需要有trigger的定義,不然會導致主從數據不一致的;   2)基於行的復制時,trigger不會在slave上執行。因為復制的數據,不是sql語句。 截圖來自MySQL5.6的pdf版文檔。   說明:   基於行的復制時,存儲過程,函數,觸發器都只在master上執行,然後將執行之後的數據傳給 slave 。不會將它們的sql語句發給slave. slave上看到的只有修改的行數據,不會有 存儲過程、函數、觸發器的調用語句。 截圖來自MySQL5.6的pdf版文檔。   說明:   說的基本和第一幅截圖一樣。   基於語句的復制,trigger會在master和slave上都執行。   基於行的復制,trigger只會在master上執行,然後將數據行傳給slave. 因為如果基於行的復制,salve上也執行trigger的話,會導致執行兩次,導致主從數據不一致。 截圖來自MySQL5.6的pdf版文檔。   說明:   1)對於存儲過程,如果不是 確定性的,或者該存儲過程不對數據進行修改,那麼它就會導致在復制時,主從數據的不一致。這裡指基於statement的復制。對於基於row的復制,不會導致主從不一致。   2. trigger 的局限:   carete trigger 語法:
Syntax:
CREATE
[DEFINER = { user | CURRENT_USER }]
TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
trigger_body

trigger_time: { BEFORE | AFTER }

trigger_event: { INSERT | UPDATE | DELETE }
1)trigger 只能在表中的數據進行: insert, update, delete 時進行某種處理,也就是說他不能對表上的 DDL 語句進行某種處理!!!!   2)MySQL triggers activate only for changes made to tables by SQL statements. They do not activate for changes in views, nor by changes to tables made by APIs that do not transmit SQL statements to the MySQL Server.  通過視圖修改和通過API修改的表的數據時,不會觸發trigger   ----------------------------------------  分割線   ------------------------------------------------ 下面的內容轉自:http://www.linuxidc.com/Linux/2012-06/63141.htm MySQL5.5 主從復制 (觸發器,函數,存儲引擎,事件處理)說明 mysql5.5 對觸發器,函數,存儲引擎,事件進行主從復制情況.   一、MySQL主從復制有三種模式.   1.binlog_format = row  : 日志中會記錄成每一行數據被修改的形式(記錄頁面),然後在 slave 端再對相同的數據進行修改。   2.binlog_format = statement  : 每一條會修改數據的 SQL 都會記錄到 master 的 bin-log 中。slave 在復制的時候 SQL 進程會解析成和原來 master 端執行過的相同的 SQL 再次執行。   3.binlog_format = mixed : 這個模式是在5.1.8版本之後, 才有的. mixed是row和statement的混合模式.   二、觸發器的主從復制.   A .當binlog_format = statement 或 binlog_format = mixed (使用混合模式用的是statement 方式)  這種模式下復制情況   1. 主從復制的時候,主從觸發器都受到definer從句的約束.只有主從上都有這個用戶才能正常運行這個觸發器.   2. 主服務器上SQL語句傳到從服務器上,從服務器再執行SQL語句去觸發從服務器的觸發器(這裡要說明是:主服務器不會把觸發後的SQL傳遞給從服務器). 這裡可以看到,傳遞是原始的SQL語句.   B .當binlog_format = row 或 binlog_format = mixed(使用混合模式用的是row方式)  這種模式下復制情況   1. 主服務器把被修改的頁面復制給從服務器,並且這個修改的頁面的值是觸發後的改變值.   2. 因為這個頁面的值是觸發後改變的值, 所以在從服務器上可以不需要這個觸發器.   3. 刪除從服務器上的觸發器.一樣的可以得到跟主服務器一樣的值. 三、存儲過程的主從復制   1. 主服務器上的存儲過程同樣收到definer從句的約束.但是,在復制的時候,從服務上不需要有存儲過程   A. 當binlog_format = statement 或binlog_format = mixed (使用混合模式用的是statement 方式)  這種模式下復制情況 可以看到通過系統函數轉換後的值復制給從服務器,不需要在從服務器上建立。(注:其實這裡是錯誤的!和文檔中的明顯不一致,參見最後的總結。) B .當binlog_format = row 或 binlog_format = mixed(使用混合模式用的是row方式)  這種模式下復制情況(傳的都是數據)   四、函數主從復制   A . 當binlog_format = statement 或binlog_format = mixed (使用混合模式用的是statement 方式)  這種模式下復制情況   1. 主從復制的時候,主從觸發器都受到definer從句的約束.只有主從上都有這個用戶才能正常運行這個函數   2.  主服務器上SQL語句復制從服務器上,從服務器再執行SQL語句再去調用從服務器的函數(主服務器不會把函數的返回值傳給從服務器的) B. 當binlog_format = row 或 binlog_format = mixed(使用混合模式用的是row方式)  這種模式下復制情況(傳的都是數據)   1.主服務器會直接把修改過的頁面復制給從服務器,從服務器不需要有對應的函數 五、事件主從復制   當事件有用函數,觸發器,存儲過程時.跟上面的操作情況是一樣的.   但有一點不同的是.   在主服務器上建立一個event,當然,在從服務器上也會創建一個event..(默認情況下主event復制到從服務器的event是關閉著的)   1.主服務器上的event 2.從服務器上的event 如果在從服務器,開啟事件.不僅主服務器復制過來的SQL語句執行一遍,從服務器上的EVENT也會執行.   ===============分割線=============   總結:   MySQL5.6文檔的說明和上面轉帖的博文,說的是不太相符的。不相符的地方在 存儲過程的說明上。我們還是應該以文檔為准。博文畢竟良莠不齊。   在基於row的復制時:   不管是 存儲過程,函數,還是觸發器,都是將 執行之後的數據行,傳給slave。slave上看到的都是數據,不會有它們的調用語句。slave上可以沒有它們的定義。   在基於statement 的復制時:   1)存儲過程、函數、觸發器 都會在slave上執行。所以基於statement復制時,slave也必須有它們的定義。而且存儲過程、函數必須是確定性的或者它們不修改表的數據。不然就會導致基於statement的復制,主從數據不一致。   2)存儲過程和函數在定義時,有 確定性函數和非確定性函數的分別;比如 uuid(),md5()這些函數肯定都是非確定性函數,因為它們每次執行的值是不確定的。所以在master和slave上分別執行會導致數據不一致。所以在基於語句復制的環境中,函數都必須是 確定性的(DETERMINISTIC)。不然就只能采用row復制格式了。   3)在基於statement復制時,trigger中定義的sql語句在執行時,不會傳給slave,而僅僅傳調用trigger的語句本身。所以不會導致定義在trigger中的sql執行兩次。也就是說不會既將調用trigger的語句傳給slave,又將在trigger執行時,在trigger中運行的那些sql語句傳給slave. 因為這樣會導致那些 sql 執行兩次。   4)上面存儲過程、函數、觸發器在復制時的區別,也說明了,基於row格式的復制要優於基於statement格式的復制,基於row的復制明顯要健壯很多。   同時也說明:觸發器、存儲過程能不用最好就不要用了。   5)最後,雖然有文檔的說明,實際使用時最好先通過自己的測試,來確認一下,到底 存儲過程、函數、觸發器是在基於statement的復制中是如何處理的。   基於row的復制,很定是沒有問題的。最好是采用基於row的復制,最好不用觸發器,存儲過程,非確定性函數。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved