再深入一點|binlog和relay-log到底長啥樣?

上一篇mysql面試的文章之后收到不少朋友的意見健盒,希望深入講講復(fù)制绒瘦、日志的格式這些,今天扣癣,我們就來深挖一下mysql的復(fù)制機制到底有哪一些惰帽,以及binlog和relay-log的結(jié)構(gòu)到底是什么樣子的。

binlog作用

binlog的主要作用是記錄數(shù)據(jù)庫中表的更改父虑,它只記錄改變數(shù)據(jù)的sql该酗,不改變數(shù)據(jù)的sql不會寫入,比如select語句一般不會被記錄士嚎,因為他們不會對數(shù)據(jù)產(chǎn)生任何改動呜魄。

用一個實際的場景看下binlog產(chǎn)生的過程莱衩,準(zhǔn)備sql:

create table    test(text varchar(20));
insert into test values ('test_text');
select * from test;
flush logs;

查看binlog

show binlog events in 'binlog.000029';

顯示的結(jié)果如下:

binlog

另外爵嗅,也可以使用mysqlbinlog工具來查看binlog的內(nèi)容:

show variables like 'log_%'; #查看日志目錄
mysqlbinlog --short-form --force-if-open --base64-output=never /usr/local/var/mysql/binlog.000029
image
image

從日志我們可以看到執(zhí)行了創(chuàng)建表的語句以及一個Format_desc頭和Ratate輪換事件,這個我們會在后面講到笨蚁,先看幾個字段代表的含義睹晒。

Log_name代表日志文件的名稱,比如我這里的查詢是直接查詢binlog.000029括细,默認(rèn)的寫法是show binlog events伪很,但是這樣只會查詢到第一個binlog,并不是當(dāng)前激活狀態(tài)的binlog奋单,如果你不知道binlog有哪些锉试,可以用命令:

show binary logs; #查看binlog列表
show master status; #查看最新的binlog
image

Pos代表文件開始的位置。

Event_type代表事件的類型览濒。

Server_id是創(chuàng)建事件的服務(wù)器ID呆盖。

End_log_pos代表事件在文件中的結(jié)束位置,以上面為例匾七,第一次查詢的結(jié)束位置是723絮短,第二次insert之后文件的開始位置就是從723開始。

Info代表事件信息昨忆,是一段可讀的文本內(nèi)容丁频。

binlog日志結(jié)構(gòu)

binlog日志的結(jié)構(gòu)大概是長這樣的,它由索引文件和binlog文件組成邑贴,其中binlog事件又包含通用頭席里、提交頭和事件體3個部分組成。

image

首先說說索引文件拢驾,索引文件的每一行都包含了一個binlog文件的完整文件名(類似host-bin.001)奖磁,一些命令比如flush logs將所有日志寫入磁盤會影響到索引文件。

每個binlog文件以若干個binlog事件組成繁疤,以格式描述事件(Format_description)作為文件頭(上面的binlog圖片F(xiàn)ormat_desc事件)咖为,以日志輪換事件(rotate)作為文件尾秕狰。

Format_description包含binlog文件的服務(wù)器信息、文件狀態(tài)的關(guān)鍵信息等躁染。如果服務(wù)器關(guān)閉或者重啟鸣哀,則會創(chuàng)建一個新的binlog文件,同時寫入一個新的format_description吞彤。他的格式大致如下我衬。

2                binlog-version
string[50]       mysql-server version
4                create timestamp
1                event header length
string[p]        event type header lengths

日志輪換事件則包含下一個binlog的文件名以及開始讀取的位置,它由服務(wù)器寫完binlog后添加到文件尾饰恕,輪換事件并不會每次都存在挠羔,格式如下。

if binlog-version > 1 {
8              position
}
string[p]      name of the next binlog

binlog事件包含若干個事務(wù)組成的組(group)埋嵌,每個組對應(yīng)一個事務(wù)破加,如果是create alter語句不屬于事務(wù)語句的話,則他們本身就是一個組莉恼,每個組要么全部執(zhí)行拌喉,要么都不執(zhí)行。

image

binlog事件結(jié)構(gòu)

每個binlog事件由3個部分組成:

  1. 通用頭俐银,包含binlog中所有事件具備的基本信息尿背。
  2. 提交頭,對于不同類型的事件來說捶惜,提交頭的內(nèi)容也不盡相同
  3. 事件體田藐,存儲事件的主要數(shù)據(jù),同樣對于不同類型事件也不同吱七。

binlog輪換和清理

從上面的例子我們也可以看出來汽久,binlog并非只有一個,而基于真實的場景來說踊餐,始終寫一個binlog文件肯定也是不可取的景醇,而binlog輪換主要有3個場景:

  1. 服務(wù)器啟動,每次服務(wù)器啟動都會生成一個新的binlog文件吝岭。
  2. 達(dá)到最大大小三痰,可以通過binlog-cache-size控制大小,達(dá)到最大大小后將更換窜管。
  3. 顯示刷新散劫,flush logs將所有日志寫入磁盤,這時候會創(chuàng)建一個新的文件寫入幕帆,從第一個例子也能看出來執(zhí)行完之后生成了一個新的日志binlog.000030的文件并且開始的位置是4获搏。
image

隨著時間的推移,我們的binlog文件會越來越多失乾,這時候有兩種方式可以清除binlog:

  1. 通過設(shè)置expire-logs-days控制想保留的binlog日志文件天數(shù)常熙,系統(tǒng)將會自動清理纬乍。
  2. 通過PURGE BINARY LOGS手動清理

relay-log結(jié)構(gòu)

relay-log中繼日志是連接master和slave的核心,我們來深入了解一下它的結(jié)構(gòu)和使用症概。

image-20200909161115718

relay-log的結(jié)構(gòu)和binlog非常相似蕾额,只不過他多了一個master.info和relay-log.info的文件。

master.info記錄了上一次讀取到master同步過來的binlog的位置彼城,以及連接master和啟動復(fù)制必須的所有信息。

relay-log.info記錄了文件復(fù)制的進度退个,下一個事件從什么位置開始募壕,由sql線程負(fù)責(zé)更新。

上一篇文章我們提到了整個復(fù)制流程的過程大概是這個樣子:

image

知道binlog和relay-log的結(jié)構(gòu)之后语盈,我們重新梳理一下整個鏈路的流程舱馅,這里我們假定master.info和relay-log.info都是存在的情況:

  1. Master收到客戶端請求語句,在語句結(jié)束之前向二進制日志寫入一條記錄刀荒,可能包含多個事件代嗤。
  2. 此時,一個Slave連接到Master缠借,Master的dump線程從binlog讀取日志并發(fā)送到Slave的IO線程干毅。
  3. IO線程從master.info讀取到上一次寫入的最后的位置。
  4. IO線程寫入日志到relay-log中繼日志泼返,如果超過指定的relay-log大小硝逢,寫入輪換事件,創(chuàng)建一個新的relay-log绅喉。
  5. 更新master.info的最后位置
  6. SQL線程從relay-log.info讀取進上一次讀取的位置
  7. SQL線程讀取日志事件
  8. 在數(shù)據(jù)庫中執(zhí)行sql
  9. 更新relay-log.info的最后位置
  10. Slave記錄自己的binlog日志
image

但是在這里IO和SQL線程有會產(chǎn)生重復(fù)事件的問題渠鸽,舉一個場景:

  1. 先記錄中繼日志,然后更新master.info位置
  2. 此時服務(wù)器崩潰柴罐,寫入master.info失敗
  3. 服務(wù)器恢復(fù)徽缚,再次同步從master.info獲取到的是上一次的位置,會導(dǎo)致事件重復(fù)執(zhí)行

既然會有這個問題還為什么要這樣做呢革屠?假設(shè)反過來凿试,先更新master.info再記錄中繼日志,這樣帶來的問題就是丟失數(shù)據(jù)了屠阻。而mysql認(rèn)為丟失比重復(fù)更嚴(yán)重红省,所以要先刷新日志,保大還是保小mysql幫你做了決定国觉。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吧恃,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子麻诀,更是在濱河造成了極大的恐慌痕寓,老刑警劉巖傲醉,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異呻率,居然都是意外死亡硬毕,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門礼仗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吐咳,“玉大人,你說我怎么就攤上這事元践【录梗” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵单旁,是天一觀的道長沪羔。 經(jīng)常有香客問我,道長象浑,這世上最難降的妖魔是什么蔫饰? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮愉豺,結(jié)果婚禮上篓吁,老公的妹妹穿的比我還像新娘。我一直安慰自己粒氧,他們只是感情好越除,可當(dāng)我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著外盯,像睡著了一般摘盆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上饱苟,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天孩擂,我揣著相機與錄音,去河邊找鬼箱熬。 笑死类垦,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的城须。 我是一名探鬼主播蚤认,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼糕伐!你這毒婦竟也來了砰琢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎陪汽,沒想到半個月后训唱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挚冤,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡训挡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年舍哄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蟆沫,死狀恐怖温治,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情舟山,我是刑警寧澤卤恳,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布突琳,位于F島的核電站拆融,受9級特大地震影響蠢琳,放射性物質(zhì)發(fā)生泄漏镜豹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一泰讽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧菇绵,春花似錦、人聲如沸翎嫡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽圈驼。三九已至望几,卻和暖如春橄抹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背玉锌。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工主守, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留榄融,地道東北人。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓黄刚,卻偏偏與公主長得像民效,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子业扒,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,927評論 2 355