MySQL小误区:关于set global sql_slave_skip_counter=N 命令的一些点
背景知識(shí)1:
????在主從庫(kù)維護(hù)中,有時(shí)候需要跳過(guò)某個(gè)無(wú)法執(zhí)行的命令,需要在slave處于stop狀態(tài)下,執(zhí)行?set global sql_slave_skip_counter=N以跳過(guò)命令。常用的且不易用錯(cuò)的是N=1的情況,但N>1時(shí),則不那么顧名思義,本文詳細(xì)介紹N的意義,及使用注意事項(xiàng)。
?
????背景知識(shí)2:
????MySQL從庫(kù)從主庫(kù)上復(fù)制binlog文件內(nèi)容到本地執(zhí)行。在binlog上命令以event的形式存在,并非一個(gè)命令對(duì)應(yīng)一個(gè)event。以一個(gè)insert語(yǔ)句為例(引擎InnoDB、binglog_format=statement),?在binlog中實(shí)際上有三個(gè)event,分別為begin\insert\commit?。?命令類型都是Query_log_event.
?
????而set global sql_slave_skip_counter=N的意思,即為在start slave時(shí),從當(dāng)前位置起,跳過(guò)N個(gè)event。每跳過(guò)一個(gè)event,則N--.
?
????與實(shí)際情況不符?
????看到這里有同學(xué)就會(huì)問(wèn),這是有問(wèn)題的。如果當(dāng)前的執(zhí)行位置是某個(gè)insert語(yǔ)句開(kāi)頭,那使用?N=1實(shí)際上是從begin\insert\commit的第二個(gè)開(kāi)始執(zhí)行,這個(gè)insert語(yǔ)句還是不能被跳過(guò)?
????實(shí)際上這里還有兩個(gè)策略:
????1、若N=1且當(dāng)前event為BEGIN,?則N不變,跳過(guò)當(dāng)前event繼續(xù)。
????2、若N=1且當(dāng)前event處于一個(gè)事務(wù)之內(nèi)(BEGIN之后,COMMIT之前),則N不變,跳過(guò)當(dāng)前event繼續(xù)。
?
?????說(shuō)明:其實(shí)上面兩個(gè)策略合起來(lái)就是一句話,當(dāng)N=1時(shí),會(huì)連續(xù)跳過(guò)若干個(gè)event,直到當(dāng)前所在的事務(wù)結(jié)束。
????當(dāng)然如果N>1,則每跳過(guò)一個(gè)event都要N--.
?
????命令舉例:
????所以我們平時(shí)最常用的N=1的情況,都是下一個(gè)事務(wù)。
????假設(shè)某個(gè)Pos之后執(zhí)行如下命令(?引擎InnoDB、binglog_format=statement),
????insert into t values(x1);
????begin;
????insert into t values(x2);
????insert into t values(x3);
????commit;
???insert into t values(x4);
你的從庫(kù)stop在Pos上,假設(shè)你要跳過(guò)前面幾個(gè)命令直接執(zhí)行插入x4的操作,則你的N設(shè)置為?4或5或6或7均可。(X1語(yǔ)句為3個(gè)event)
?
???其他說(shuō)明:
???上面舉例中都特別說(shuō)明了在innodb引擎和statement模式下。其他情況區(qū)別如下:
???1、若引擎為myisam(等不支持事務(wù)的引擎),且在statement下,則binlog中不會(huì)有begin和commit,每個(gè)命令都是一個(gè)event;
???2、row模式的binlog里,一個(gè)insert語(yǔ)句實(shí)際上是兩個(gè)event(Table_map_event和?Row_log_event),?計(jì)算時(shí)應(yīng)與statement不同。
??3、在row模式下,不論引擎是否支持事務(wù),一個(gè)insert語(yǔ)句都會(huì)加上BEGIN和commit,也即變成4個(gè)event。
??4、基于InnoDB引擎表的insert/delete/update操作都有顯式樣的BEGIN /COMMIT.
?
??上面舉的這個(gè)例子中,若為row模式,則要直接執(zhí)行X4語(yǔ)句需要設(shè)置的N為?5~10均可。
?
???小結(jié):
???1、set global sql_slave_skip_counter=N中的N是指跳過(guò)N個(gè)event
???2、最好記的是N被設(shè)置為1時(shí),效果跳過(guò)下一個(gè)事務(wù)。
???3、跳過(guò)第N個(gè)event后,位置若剛好落在一個(gè)事務(wù)內(nèi)部,則會(huì)跳過(guò)這整個(gè)事務(wù)
???4、一個(gè)insert/update/delete不一定只對(duì)應(yīng)一個(gè)event,由引擎和日志格式?jīng)Q定
總結(jié)
以上是生活随笔為你收集整理的MySQL小误区:关于set global sql_slave_skip_counter=N 命令的一些点的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [Mysql]——通过例子理解事务的4种
- 下一篇: 学习MongoDB 十一: MongoD