《MySQL——主备一致性六问六答》
目錄
- 備庫(kù)為什么要設(shè)置為只讀模式?
- 備庫(kù)設(shè)置為只讀,如何與主庫(kù)保持同步更新?
- A到B的內(nèi)部流程如何?
- binlog內(nèi)容是什么?
- `row`格式對(duì)于恢復(fù)數(shù)據(jù)有何好處
- M-M結(jié)構(gòu)的循環(huán)復(fù)制問(wèn)題以及解決方案
備庫(kù)為什么要設(shè)置為只讀模式?
有這樣幾點(diǎn)考慮:
1、有時(shí)候一些運(yùn)營(yíng)類的查詢語(yǔ)句會(huì)被放到備庫(kù)上去查,設(shè)置為只讀可以防止誤操作
2、防止切換邏輯有bug,比如切換過(guò)程中出現(xiàn)雙寫(xiě)( 同時(shí)寫(xiě)兩個(gè)庫(kù)(A、B )),造成主備不一致
3、可以用 readonly 狀態(tài),來(lái)判斷節(jié)點(diǎn)的角色
備庫(kù)設(shè)置為只讀,如何與主庫(kù)保持同步更新?
readonly的設(shè)置對(duì)于super權(quán)限用戶是無(wú)效的。用于同步的線程,就擁有super權(quán)限。
A到B的內(nèi)部流程如何?
主庫(kù)接收到客戶端的更新請(qǐng)求后,執(zhí)行內(nèi)部事務(wù)的更新邏輯,同時(shí)寫(xiě)binlog;
備庫(kù)B與主庫(kù)A之間維持一個(gè)長(zhǎng)連接。主庫(kù)內(nèi)部有一個(gè)線程,專門(mén)用于服務(wù)備庫(kù)B這個(gè)長(zhǎng)連接。
一個(gè)事務(wù)日志同步的完整過(guò)程:
1、備庫(kù)B通過(guò)change master命令,設(shè)置主庫(kù)A的IP、端口、用戶名、密碼,以及請(qǐng)求binlog的起始位置(文件名+日志偏移量)
2、備庫(kù)B執(zhí)行start slave命令,備庫(kù)啟動(dòng)兩個(gè)線程io_thread、sql_thread。io_thread負(fù)責(zé)與主庫(kù)建立連接
3、主庫(kù)A校驗(yàn)完用戶名、密碼后,按照備庫(kù)B傳過(guò)來(lái)的起始位置,讀取本地的binlog然后發(fā)給備庫(kù)B
4、備庫(kù)B拿到binlog后,寫(xiě)到本地文件,稱為中轉(zhuǎn)日志(relay log)
5、sql_thread讀取中轉(zhuǎn)日志relay log ,解析日志里的命令,并執(zhí)行
binlog內(nèi)容是什么?
在解釋內(nèi)容之前,需要知道binlog的格式。
binlog有三種格式:statement 、row、mixed
statement
binlog_format=statement 時(shí),binlog 里面記錄的就是 SQL 語(yǔ)句的原文
statement格式的binlog的缺陷有個(gè)缺陷:
主備使用的索引可能是不一致的,最終導(dǎo)致執(zhí)行刪除時(shí)刪除的數(shù)據(jù)不一致。
**row **
row 格式的 binlog 里沒(méi)有了 SQL 語(yǔ)句的原文,而是替換成了兩個(gè) event: Table_map和Delete_rows.
1、 Table_map , 用于說(shuō)明操作的表是test庫(kù)的表t
2、Delete_rows , 用于定義刪除的行為
當(dāng)binlog_format = row,binlog里面記錄了真實(shí)刪除行的主鍵id,這樣binlog傳到備庫(kù)去的時(shí)候,肯定不會(huì)出現(xiàn)主備刪除不同行的問(wèn)題
mixed
mixed格式用于哪些場(chǎng)景呢?
statement格式可能會(huì)導(dǎo)致主備不一致,所以要使用row格式
row格式比較占空間,同時(shí)也更要耗費(fèi)IO資源,影響執(zhí)行速度
所以采用這種方案,采用mixed格式,MySQL自己會(huì)判斷這條SQL語(yǔ)句是否可能引起主備不一致,如果可能,使用row格式,否則使用statement格式。
row格式對(duì)于恢復(fù)數(shù)據(jù)有何好處
現(xiàn)在,越來(lái)越多場(chǎng)景要求使用row格式的binlog,可以從delete、insert、update三種sql語(yǔ)句角度看待這個(gè)問(wèn)題。
使用delete語(yǔ)句,row格式會(huì)把被刪除的行的整行信息保存。所以刪錯(cuò)之后,只需要把binlog記錄的delete語(yǔ)句轉(zhuǎn)成insert就能恢復(fù)了。
使用insert語(yǔ)句,row格式會(huì)記錄所有的字段信息。所以插入錯(cuò)誤的時(shí)候,只需要把binlog記錄的insert語(yǔ)句轉(zhuǎn)成delete語(yǔ)句就能恢復(fù)了。
使用update語(yǔ)句,binlog會(huì)記錄修改前整行的數(shù)據(jù)和修改后的整行數(shù)據(jù)。所以如果update誤執(zhí)行,只需要把event前后的兩行信息對(duì)調(diào),再去數(shù)據(jù)庫(kù)執(zhí)行,就能恢復(fù)數(shù)據(jù)了。
M-M結(jié)構(gòu)的循環(huán)復(fù)制問(wèn)題以及解決方案
| M-S結(jié)構(gòu) | M-M結(jié)構(gòu) |
圖1是M-S結(jié)構(gòu),但是現(xiàn)在常用的是M-M結(jié)構(gòu),M-M結(jié)構(gòu)區(qū)別在于:節(jié)點(diǎn)A與節(jié)點(diǎn)B總是互為主備關(guān)系,所以在切換的時(shí)候就不用修改主備關(guān)系了。
M-M存在循環(huán)復(fù)制問(wèn)題:
在節(jié)點(diǎn)A更新一個(gè)語(yǔ)句,把生成的binlog發(fā)給節(jié)點(diǎn)B。
節(jié)點(diǎn)B執(zhí)行完更新語(yǔ)句后也會(huì)生成binlog。
如果A同時(shí)為B的備庫(kù),A會(huì)把節(jié)點(diǎn)B新生成的binlog拿過(guò)去執(zhí)行。節(jié)點(diǎn)A和B之間會(huì)不斷循環(huán)執(zhí)行這個(gè)更新語(yǔ)句。
解決方案:
已知MySQL在binlog中記錄了命令第一次執(zhí)行所在實(shí)例的server id。
1、規(guī)定兩個(gè)庫(kù)的server id 必須不同。若相同,則不能設(shè)定為主備關(guān)系
2、備庫(kù)接到binlog,生成與原binlog的server id相同的新的binlog
3、每個(gè)庫(kù)在收到從自己的主庫(kù)發(fā)過(guò)來(lái)的日志后,先判斷server id,如果和自己的相同,表示這個(gè)日志是自己生成的,丟棄這個(gè)日志。
所以使用M-M結(jié)構(gòu)的日志執(zhí)行流程如下:
1、從節(jié)點(diǎn)A更新的事務(wù),binlog里記錄的都是A的server id
2、傳到節(jié)點(diǎn)B執(zhí)行一次后,節(jié)點(diǎn)B生成的binlog的server id 也是A的server id
3、再傳給節(jié)點(diǎn)A,A判斷這個(gè)server id與自己的相同,不處理這個(gè)日志
總結(jié)
以上是生活随笔為你收集整理的《MySQL——主备一致性六问六答》的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 信阳治疗男人精子活力低最好的医院推荐
- 下一篇: 《MySQL——主备切换流程与主备延迟》