stop slave;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
start slave;
flush privileges;
然后觀察一段時間,一直到244應用日志跟上243的master信息。。。。
補充內容:
mysqlbinlog主從寫的機制:
一:在主庫243操作數(shù)據(jù)庫,然后分別在243和244上格式化當前的binlog,并且查看相關內容,結果如下:
create table liuliuliu ( id int)
insert into liuliuliu values(111)
insert into liuwenhe.liuliuliu values(11)
[root@S243 mybinlog]# mysqlbinlog --base64-output=decode-rows -v -v mysql-bin.001473 > binlog
[root@S243 mybinlog]# cat binlog | grep liuliuliu
create table liuliuliu ( id int)
insert into liuliuliu values(111)
insert into liuwenhe.liuliuliu values(11)
[root@S244 mybinlog]# mysqlbinlog --base64-output=decode-rows -v -v mysql-bin.001513 > binlog
[root@S244 mybinlog]# cat binlog | grep liuliuliu
create table liuliuliu ( id int)
insert into liuliuliu values(111)
insert into liuwenhe.liuliuliu values(11)
結論:在主庫操作的數(shù)據(jù)庫,相關記錄必然記錄到主庫binlog,值得注意的是從庫也把相關的信息記錄進它自己的binlog中. 然后我猜應該是做了特別的標記,使得244并不會把從243接收到的相關操作信息再次傳回給243,
二:binlog的三種格式以及binlog的組提交(摘自網(wǎng)絡):
2.1:Mysql binlog日志有三種格式,分別為Statement,MiXED,以及ROW!
2.1.1.Statement:每一條會修改數(shù)據(jù)的sql都會記錄在binlog中。
優(yōu)點:不需要記錄每一行的變化,減少了binlog日志量,節(jié)約了IO,提高性能。(相比row能節(jié)約多少性能與日志量,這個取決于應用的SQL情況,正常同一條記錄修改或者插入row格式所產生的日志量還小于Statement產生的日志量,但是考慮到如果帶條件的update操作,以及整表刪除,alter表等操作,ROW格式會產生大量日志,因此在考慮是否使用ROW格式日志時應該跟據(jù)應用的實際情況,其所產生的日志量會增加多少,以及帶來的IO性能問題。)
缺點:由于記錄的只是執(zhí)行語句,為了這些語句能在slave上正確運行,因此還必須記錄每條語句在執(zhí)行的時候的一些相關信息,以保證所有語句能在slave得到和在master端執(zhí)行時候相同 的結果。另外mysql 的復制,像一些特定函數(shù)功能,slave可與master上要保持一致會有很多相關問題(如sleep()函數(shù), last_insert_id(),以及user-defined functions(udf)會出現(xiàn)問題).
使用以下函數(shù)的語句也無法被復制:
* LOAD_FILE()
* UUID()
* USER()
* FOUND_ROWS()
* SYSDATE() (除非啟動時啟用了 --sysdate-is-now 選項)
同時在INSERT ...SELECT 會產生比 RBR 更多的行級鎖
2.1.2:Row:不記錄sql語句上下文相關信息,僅保存哪條記錄被修改。
優(yōu)點: binlog中可以不記錄執(zhí)行的sql語句的上下文相關的信息,僅需要記錄那一條記錄被修改成什么了。所以rowlevel的日志內容會非常清楚的記錄下每一行數(shù)據(jù)修改的細節(jié)。而且不會出現(xiàn)某些特定情況下的存儲過程,或function,以及trigger的調用和觸發(fā)無法被正確復制的問題
缺點:所有的執(zhí)行的語句當記錄到日志中的時候,都將以每行記錄的修改來記錄,這樣可能會產生大量的日志內容,比如一條update語句,修改多條記錄,則binlog中每一條修改都會有記錄,這樣造成binlog日志量會很大,特別是當執(zhí)行alter table之類的語句的時候,由于表結構修改,每條記錄都發(fā)生改變,那么該表每一條記錄都會記錄到日志中。
2.1.3:Mixedlevel: 是以上兩種level的混合使用,一般的語句修改使用statment格式保存binlog,如一些函數(shù),statement無法完成主從復制的操作,則采用row格式保存binlog,MySQL會根據(jù)執(zhí)行的每一條具體的sql語句來區(qū)分對待記錄的日志形式,也就是在Statement和Row之間選擇一種.新版本的MySQL中隊row level模式也被做了優(yōu)化,并不是所有的修改都會以row level來記錄,像遇到表結構變更的時候就會以statement模式來記錄。至于update或者delete等修改數(shù)據(jù)的語句,還是會記錄所有行的變更。
2.1.4:Binlog基本配制與格式設定
1.基本配制
Mysql BInlog日志格式可以通過mysql的my.cnf文件的屬性binlog_format指定。如以下:
binlog_format = MIXED //binlog日志格式
log_bin =目錄/mysql-bin.log //binlog日志名
expire_logs_days = 7 //binlog過期清理時間
max_binlog_size 100m //binlog每個日志文件大小
2.1.5:Binlog日志格式選擇
Mysql默認是使用Statement日志格式,推薦使用MIXED.
由于一些特殊使用,可以考慮使用ROWED,如自己通過binlog日志來同步數(shù)據(jù)的修改,這樣會節(jié)省很多相關操作。對于binlog數(shù)據(jù)處理會變得非常輕松,相對mixed,解析也會很輕松(當然前提是增加的日志量所帶來的IO開銷在容忍的范圍內即可)。
2.1.6:針對binlog的三種格式而產生相應的主從復制的三種方式:
(1):基于語句(Statement)的復制: 在主服務器上執(zhí)行的SQL語句,在從服務器上執(zhí)行同樣的語句。MySQL默認采用基于語句的復制,效率比較高。
(2):基于行(row)的復制:把改變的內容復制過去,而不是把命令在從服務器上執(zhí)行一遍. 從mysql5.0開始支持
(3):混合類型(mixed)的復制: 默認采用基于語句的復制,一旦發(fā)現(xiàn)基于語句的無法精確的復制時,就會采用基于行的復制。
2.2: binlog組提交(5.6),5.6默認就是組提交,不需要開啟,這是它的內部機制
它的基本思想是:引入隊列機制保證innodb commit順序與binlog落盤順序一致,并將事務分組,組內的binlog刷盤動作交給一個事務進行,實現(xiàn)組提交目的。binlog提交將提交分為了3個階段,F(xiàn)LUSH階段,SYNC階段和COMMIT階段。每個階段都有一個隊列,每個隊列有一個mutex保護,約定進入隊列第一個線程為leader,其他線程為follower,所有事情交由leader去做,leader做完所有動作后,通知follower刷盤結束。在 mysql 5.5 中,只有當 sync_binlog = 0 時,才能使用 group commit,在 mysql 5.6中都可以進行 group commit log組提交基本流程如下:
FLUSH 階段
1) 持有Lock_log mutex [leader持有,follower等待]
2) 獲取隊列中的一組binlog(隊列中的所有事務)
3) 將binlog buffer到I/O cache
4) 通知dump線程dump binlog
SYNC階段
這個階段和參數(shù)sync_binlog有關系,
1) 釋放Lock_log mutex,持有Lock_sync mutex[leader持有,follower等待]
2) 將一組binlog 落盤(sync動作,最耗時,假設sync_binlog為1)。
COMMIT階段
1) 釋放Lock_sync mutex,持有Lock_commit mutex[leader持有,follower等待]
2) 遍歷隊列中的事務,逐一進行innodb commit
3) 釋放Lock_commit mutex
4) 喚醒隊列中等待的線程
說明:由于有多個隊列,每個隊列各自有mutex保護,隊列之間是順序的,約定進入隊列的一個線程為leader,因此FLUSH階段的leader可能是SYNC階段的follower,但是follower永遠是follower。
通過上文分析,我們知道MYSQL目前的組提交方式解決了一致性和性能的問題。通過二階段提交解決一致性,通過redo log和binlog的組提交解決磁盤IO的性能。
2.3:關于參數(shù)sync_binlog的理解:
sync_binlog=0,當事務提交之后,MySQL不做fsync之類的磁盤同步指令刷新binlog_cache中的信息到磁盤,而讓Filesystem自行決定什么時候來做同步,或者cache滿了之后才同步到磁盤。
sync_binlog=n,當每進行n次事務提交之后,MySQL將進行一次fsync之類的磁盤同步指令來將binlog_cache中的數(shù)據(jù)強制寫入磁盤,當數(shù)據(jù)庫crash的時候至少會丟失N-1個transactions
sync_binlog=1,每一個transaction commit都會調用一次fsync(),此時能保證數(shù)據(jù)最安全但是性能影響較大。
總結:mysql主從復制,正常情況下slave讀取master的binlog_buffer中的binlog,并不是等寫到binlog底層文件后才讀取的,只有當slave出現(xiàn)故障后,但是此時maser庫依舊在跑業(yè)務,當從新開始start slave;這時候讀取的binlog就會從磁層磁盤binlog文件讀取。
延伸內容:
異 步復制:咱們現(xiàn)在大多數(shù)都是異步復制的,MySQL本身支持單向的、異步的復制。異步復制意味著在把數(shù)據(jù)從一臺機器拷貝到另一臺機器時有一個延時 – 最重要的是這意味著當應用系統(tǒng)的事務提交已經(jīng)確認時數(shù)據(jù)并不能在同一時刻拷貝/應用到從機。通常這個延時是由網(wǎng)絡帶寬、資源可用性和系統(tǒng)負載決定的。然 而,使用正確的組件并且調優(yōu),復制能做到接近瞬時完成。
同步復制:使用MyISAM或者InnoDB存儲引擎的MySQL本身并不支持同步復制,同步復制可以定義為數(shù)據(jù)在同一時刻被提交到一臺或多臺機器,通常這是通過眾所周知的“兩階段提交”做到的,也就是說保證數(shù)據(jù)至少在一臺slave上正常commit。雖然這確實給你在多系統(tǒng)中保持一致性,但也由于增加了額外的消息交換而造成性能下降。
半同步復制:是基于Google為MySQL開發(fā)的半同步復制的插件。半同步復制的原理是,一個事務在主服務器上執(zhí)行完成后,必須至少確保至少在一臺從服務器上執(zhí)行完成后,事務才算提交成功。如果在一定時間內從服務器沒有響應,則會自動降級為異步復制。
這個半同步復制是建立在異步復制的基礎之上進行的。
網(wǎng)頁題目:mysql主從不同步問題解決
新聞來源:http://weahome.cn/article/jodhio.html