【mysql】主從同步,事務等概念


問題:

mysql用binary log來保證主從同步的可靠性和安全性,在mysql中,主從同步是異步線程和異步任務來保證的。

(在這點上,其它存儲引擎有另外的選項,比如mongoDB和ElasticSearch的核心存儲可以執行同步選項。mongoDB甚至支持同步到所有的從庫后返回值,這樣能夠保證主從同步是沒有延遲的。)

回到mysql,binary log是如何生成的?哪些操作會記錄,哪些操作不會記錄?

比如我有個疑問就是,對於事務操作,mysql是如何記錄binary log的呢?

這個需要參考文檔1:mysql在事務中的同步原理。

我來做個翻譯:

先了解下,一個事務中可能包含transactional和nontransactional statement,這兩個的區別是什么呢?

transactional statement是指,在事務處理失敗,並執行rollback該事務時,該語句會自動回滾,這個是由mysql來保證的;

nontranscational statement是指,在事務處理失敗,並執行rollback該事務時,該語句不會自動回滾,需要上層應用,即程序猿來保證。

 

mysql處理事務語句時遵循兩條規則:

規則1:如果該事務的初始化語句是nontransactional語句,會立即寫入到binlog中。其它事務語句會被cached。如果事務的結果是commit,那么在事務commit之后,這些cached語句會寫入到binlog(之前是不寫入的);但是如果事務回滾,有些cached語句仍然會被寫入到binlog中,如果這些語句是nontransactional語句(因為這些語句是無法rollback的),其它會被拋棄;

規則2:基於statement的日志,nontransactional語句受系統參數影響(具體是:binlog_direct_non_transactional_updates)。如果該參數為OFF(默認值),日志是不會記錄的。如果該參數為ON,nontransactional語句執行后會立即記入日志(而不僅僅是initial nontransactional語句)。其它語句會被保持在transaction緩存中,事務提交后記錄日志。binlog_direct_non_transactional_updates對日志記錄沒有影響,在row-format(基於行)或者mixed-format(混合型日志)的binlog處理中。

 

我們來對mysql的語句做下區分:

Transactional語句:僅僅操作transactional tables的語句;

Nontransactional語句:僅僅操作nontransactional tables的語句;

Mixed語句:同時會操作nontransactional和transactional tables的語句;

 

在執行以下任一動作是,Mixed語句(更新一個transactional table)被認為是不安全的:

1,更新或讀取臨時表(temporary table);

2,讀取untransactional table,並且事務的隔離級別是小於 DEPEATABLE_READ(the transaction isolation level is less than DEPEATABLE_READ);

一個事務中,如果一個mixed語句緊跟着要更新transactional table,並且它要執行以下任一操作時,被認為是不安全的:

1,更新任一tabe,and 從臨時表中讀取;

2,更新任一nontransactional table,並且binlog_direct_non_transactional_updates為OFF;

 

如果事務之間混合更新transactional 和 nontransactional表,binlog中的語句順訊是正確的,並且所有已執行的語句被記錄在binlog中,即使最后事務被rollback。

然而,如果第一個連接處理的transaction沒有執行完畢,此時第二個連接更新的是nontransactional table,語句記錄在binlog的順序是非有序的。原因是,第二個連接執行的更新語句會在執行更新后立即寫入到binlog中,而不管第一個連接的執行情況如何。

這里有我個人理解是,第一個連接在處理一個事務,現在進來一個新的連接(connection 2),connection2執行的語句是nontransactional 語句,此時有些觀點會認為connection1的語句先記錄在binlog中,connection2的語句后被記錄在binlog中,但實際情況不是。

 

如果從庫的引擎是nontransactional,主庫的事務執行transactional和nontransactional表更新時應當要避免的,因為這會造成數據的不一樣(具體指主庫的transactional表和從庫的nontransactional表)。

 

每一個事務都會被記錄在binlog中,只要是以start開始,commit或者rollback結束。這個對於使用nontransactional存儲引擎(比如MyISAM)的表操作語句也同樣適用。

 

要了解什么樣的table是transactional table,設么樣的table是nontransactional table?參考文檔2

 

參考文檔1:https://dev.mysql.com/doc/refman/5.7/en/replication-features-transactions.html

文檔2:https://dev.mysql.com/doc/refman/5.7/en/nontransactional-tables.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM