掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流
大家好,我是樓仔!

為永仁等地區(qū)用戶(hù)提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及永仁網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為網(wǎng)站建設(shè)、做網(wǎng)站、永仁網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專(zhuān)業(yè)、用心的態(tài)度為用戶(hù)提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶(hù)的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!
MySQL 主從一直是面試常客,里面的知識(shí)點(diǎn)雖然基礎(chǔ),但是能回答全的同學(xué)不多。
比如我之前面試小米,就被問(wèn)到過(guò)主從復(fù)制的原理,以及主從延遲的解決方案,你之前面試,有遇到過(guò)哪些 MySQL 主從的問(wèn)題呢?
所謂 MySQL 主從,就是建立兩個(gè)完全一樣的數(shù)據(jù)庫(kù),一個(gè)是主庫(kù),一個(gè)是從庫(kù),主庫(kù)對(duì)外提供讀寫(xiě)的操作,從庫(kù)對(duì)外提供讀的操作。
對(duì)于數(shù)據(jù)庫(kù)單機(jī)部署,在 4 核 8G 的機(jī)器上運(yùn)行 MySQL 5.7 時(shí),大概可以支撐 500 的 TPS 和
10000 的 QPS,當(dāng)遇到一些活動(dòng)時(shí),查詢(xún)流量驟然,就需要進(jìn)行主從分離。
大部分系統(tǒng)的訪(fǎng)問(wèn)模型是讀多寫(xiě)少,讀寫(xiě)請(qǐng)求量的差距可能達(dá)到幾個(gè)數(shù)量級(jí),所以我們可以通過(guò)一主多從的方式,主庫(kù)只負(fù)責(zé)寫(xiě)入和部分核心邏輯的查詢(xún),多個(gè)從庫(kù)只負(fù)責(zé)查詢(xún),提升查詢(xún)性能,降低主庫(kù)壓力。
當(dāng)主庫(kù)宕機(jī)時(shí),從庫(kù)可以切成主庫(kù),保證服務(wù)的高可用,然后主庫(kù)也可以做數(shù)據(jù)的容災(zāi)備份,整體場(chǎng)景總結(jié)如下:
MySQL 的主從復(fù)制是依賴(lài)于 binlog,也就是記錄 MySQL 上的所有變化并以二進(jìn)制形式保存在磁盤(pán)上二進(jìn)制日志文件。
主從復(fù)制就是將 binlog 中的數(shù)據(jù)從主庫(kù)傳輸?shù)綇膸?kù)上,一般這個(gè)過(guò)程是異步的,即主庫(kù)上的操作不會(huì)等待 binlog 同步地完成。
詳細(xì)流程如下:
當(dāng)主庫(kù)和從庫(kù)數(shù)據(jù)同步時(shí),突然中斷怎么辦?因?yàn)橹鲙?kù)與從庫(kù)之間維持了一個(gè)長(zhǎng)鏈接,主庫(kù)內(nèi)部有一個(gè)線(xiàn)程,專(zhuān)門(mén)服務(wù)于從庫(kù)的這個(gè)長(zhǎng)鏈接。
對(duì)于下面的情況,假如主庫(kù)執(zhí)行如下 SQL,其中 a 和 create_time 都是索引:
delete from t where a > '666' and create_time<'2022-03-01' limit 1;
我們知道,數(shù)據(jù)選擇了 a 索引和選擇 create_time 索引,最后 limit 1 出來(lái)的數(shù)據(jù)一般是不一樣的。
所以就會(huì)存在這種情況:在 binlog = statement 格式時(shí),主庫(kù)在執(zhí)行這條 SQL 時(shí),使用的是索引 a,而從庫(kù)在執(zhí)行這條 SQL
時(shí),使用了索引 create_time,最后主從數(shù)據(jù)不一致了。
那么我們?cè)撊绾谓鉀Q呢?
可以把 binlog 格式修改為 row,row 格式的 binlog 日志記錄的不是 SQL 原文,而是兩個(gè) event:Table_map 和
Delete_rows。
Table_map event 說(shuō)明要操作的表,Delete_rows event用于定義要?jiǎng)h除的行為,記錄刪除的具體行數(shù)。row 格式的 binlog
記錄的就是要?jiǎng)h除的主鍵 ID 信息,因此不會(huì)出現(xiàn)主從不一致的問(wèn)題。
但是如果 SQL 刪除 10 萬(wàn)行數(shù)據(jù),使用 row 格式就會(huì)很占空間,10 萬(wàn)條數(shù)據(jù)都在 binlog 里面,寫(xiě) binlog 的時(shí)候也很耗 IO。但是
statement 格式的 binlog 可能會(huì)導(dǎo)致數(shù)據(jù)不一致。
設(shè)計(jì) MySQL 的大叔想了一個(gè)折中的方案,mixed 格式的 binlog,其實(shí)就是 row 和 statement 格式混合使用,當(dāng) MySQL
判斷可能數(shù)據(jù)不一致時(shí),就用 row 格式,否則使用就用 statement 格式。
有時(shí)候我們遇到從數(shù)據(jù)庫(kù)中獲取不到信息的詭異問(wèn)題時(shí),會(huì)糾結(jié)于代碼中是否有一些邏輯會(huì)把之前寫(xiě)入的內(nèi)容刪除,但是你又會(huì)發(fā)現(xiàn),過(guò)了一段時(shí)間再去查詢(xún)時(shí)又可以讀到數(shù)據(jù)了,這基本上就是主從延遲在作怪。
主從延遲,其實(shí)就是“從庫(kù)回放” 完成的時(shí)間,與 “主庫(kù)寫(xiě) binlog” 完成時(shí)間的差值,會(huì)導(dǎo)致從庫(kù)查詢(xún)的數(shù)據(jù),和主庫(kù)的不一致。
談到 MySQL 數(shù)據(jù)庫(kù)主從同步延遲原理,得從 MySQL 的主從復(fù)制原理說(shuō)起:
總結(jié)一下主從延遲的主要原因:主從延遲主要是出現(xiàn)在 “relay log 回放” 這一步,當(dāng)主庫(kù)的 TPS 并發(fā)較高,產(chǎn)生的 DDL 數(shù)量超過(guò)從庫(kù)一個(gè)
SQL 線(xiàn)程所能承受的范圍,那么延時(shí)就產(chǎn)生了,當(dāng)然還有就是可能與從庫(kù)的大型 query 語(yǔ)句產(chǎn)生了鎖等待。
我們一般會(huì)把從庫(kù)落后的時(shí)間作為一個(gè)重點(diǎn)的數(shù)據(jù)庫(kù)指標(biāo)做監(jiān)控和報(bào)警,正常的時(shí)間是在毫秒級(jí)別,一旦落后的時(shí)間達(dá)到了秒級(jí)別就需要告警了。
解決該問(wèn)題的方法,除了縮短主從延遲的時(shí)間,還有一些其它的方法,基本原理都是盡量不查詢(xún)從庫(kù),具體解決方案如下:
在實(shí)際應(yīng)用場(chǎng)景中,對(duì)于一些非常核心的場(chǎng)景,比如庫(kù)存,支付訂單等,需要直接查詢(xún)從庫(kù),其它非核心場(chǎng)景,就不要去查主庫(kù)了。
兩臺(tái)機(jī)器 A 和 B,A 為主庫(kù),負(fù)責(zé)讀寫(xiě),B 為從庫(kù),負(fù)責(zé)讀數(shù)據(jù)。
如果 A 庫(kù)發(fā)生故障,B 庫(kù)成為主庫(kù)負(fù)責(zé)讀寫(xiě),修復(fù)故障后,A 成為從庫(kù),主庫(kù) B 同步數(shù)據(jù)到從庫(kù) A。
優(yōu)點(diǎn):從庫(kù)支持讀,分擔(dān)了主庫(kù)的壓力,提升了并發(fā)度,且一個(gè)機(jī)器故障了可以自動(dòng)切換,操作比較簡(jiǎn)單,公司從庫(kù)還可以充當(dāng)數(shù)據(jù)備份的角色;
缺點(diǎn):一臺(tái)從庫(kù),并發(fā)支持還是不夠,并且一共兩臺(tái)機(jī)器,還是存在同時(shí)故障的機(jī)率,不夠高可用。
對(duì)于一主一從的模式,一般小公司會(huì)這么用,不過(guò)該模式下,主從分離的意義其實(shí)并不大,因?yàn)樾」镜牧髁坎桓?,更多是為了?shù)據(jù)庫(kù)的可用性,以及數(shù)據(jù)備份。
4.2 一主多從一臺(tái)主庫(kù)多臺(tái)從庫(kù),A 為主庫(kù),負(fù)責(zé)讀寫(xiě),B、C、D為從庫(kù),負(fù)責(zé)讀數(shù)據(jù)。
如果 A 庫(kù)發(fā)生故障,B 庫(kù)成為主庫(kù)負(fù)責(zé)讀寫(xiě),C、D 負(fù)責(zé)讀,修復(fù)故障后,A 也成為從庫(kù),主庫(kù) B 同步數(shù)據(jù)到從庫(kù) A。
基本上大公司,比如百度、滴滴,都是這種一主多從的模式,因?yàn)椴樵?xún)流量太高,一定需要進(jìn)行讀寫(xiě)分離,同時(shí)也需要支持服務(wù)的高可用、數(shù)據(jù)容災(zāi)。

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流