上一篇mysql面試的文章以後收到很多朋友的意見,但願深刻講講複製、日誌的格式這些,今天,咱們就來深挖一下mysql的複製機制到底有哪一些,以及binlog和relay-log的結構究竟是什麼樣子的。mysql
binlog的主要做用是記錄數據庫中表的更改,它只記錄改變數據的sql,不改變數據的sql不會寫入,好比select語句通常不會被記錄,由於他們不會對數據產生任何改動。面試
用一個實際的場景看下binlog產生的過程,準備sql: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';
顯示的結果以下:
另外,也可使用mysqlbinlog工具來查看binlog的內容:服務器
show variables like 'log_%'; #查看日誌目錄 mysqlbinlog --short-form --force-if-open --base64-output=never /usr/local/var/mysql/binlog.000029
從日誌咱們能夠看到執行了建立表的語句以及一個Format_desc頭和Ratate輪換事件,這個咱們會在後面講到,先看幾個字段表明的含義。併發
Log_name表明日誌文件的名稱,好比我這裏的查詢是直接查詢binlog.000029,默認的寫法是show binlog events,可是這樣只會查詢到第一個binlog,並非當前激活狀態的binlog,若是你不知道binlog有哪些,能夠用命令:編輯器
show binary logs; #查看binlog列表 show master status; #查看最新的binlog
Pos表明文件開始的位置。工具
Event_type表明事件的類型。ui
Server_id是建立事件的服務器ID。spa
End_log_pos表明事件在文件中的結束位置,以上面爲例,第一次查詢的結束位置是723,第二次insert以後文件的開始位置就是從723開始。
Info表明事件信息,是一段可讀的文本內容。
binlog日誌的結構大概是長這樣的,它由索引文件和binlog文件組成,其中binlog事件又包含通用頭、提交頭和事件體3個部分組成。
首先說說索引文件,索引文件的每一行都包含了一個binlog文件的完整文件名(相似host-bin.001),一些命令好比flush logs將全部日誌寫入磁盤會影響到索引文件。
每一個binlog文件以若干個binlog事件組成,以格式描述事件(Format_description)做爲文件頭(上面的binlog圖片Format_desc事件),以日誌輪換事件(rotate)做爲文件尾。
Format_description包含binlog文件的服務器信息、文件狀態的關鍵信息等。若是服務器關閉或者重啓,則會建立一個新的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的文件名以及開始讀取的位置,它由服務器寫完binlog後添加到文件尾,輪換事件並不會每次都存在,格式以下。
if binlog-version > 1 { 8 position } string[p] name of the next binlog
binlog事件包含若干個事務組成的組(group),每一個組對應一個事務,若是是create alter語句不屬於事務語句的話,則他們自己就是一個組,每一個組要麼所有執行,要麼都不執行。
每一個binlog事件由3個部分組成:
從上面的例子咱們也能夠看出來,binlog並不是只有一個,而基於真實的場景來講,始終寫一個binlog文件確定也是不可取的,而binlog輪換主要有3個場景:
隨着時間的推移,咱們的binlog文件會愈來愈多,這時候有兩種方式能夠清除binlog:
relay-log中繼日誌是鏈接master和slave的核心,咱們來深刻了解一下它的結構和使用。
relay-log的結構和binlog很是類似,只不過他多了一個master.info和relay-log.info的文件。
master.info記錄了上一次讀取到master同步過來的binlog的位置,以及鏈接master和啓動複製必須的全部信息。
relay-log.info記錄了文件複製的進度,下一個事件從什麼位置開始,由sql線程負責更新。
上一篇文章咱們提到了整個複製流程的過程大概是這個樣子:
知道binlog和relay-log的結構以後,咱們從新梳理一下整個鏈路的流程,這裏咱們假定master.info和relay-log.info都是存在的狀況:
可是在這裏IO和SQL線程有會產生重複事件的問題,舉一個場景:
既然會有這個問題還爲何要這樣作呢?假設反過來,先更新master.info再記錄中繼日誌,這樣帶來的問題就是丟失數據了。而mysql認爲丟失比重複更嚴重,因此要先刷新日誌,保大仍是保小mysql幫你作了決定。
- END -