MySQL是一種關(guān)系數(shù)據(jù)庫管理系統(tǒng),關(guān)系數(shù)據(jù)庫將數(shù)據(jù)保存在不同的表中,而不是將所有數(shù)據(jù)放在一個(gè)大倉庫內(nèi),這樣就增加了速度并提高了靈活性。
MySQL所使用的 SQL 語言是用于訪問數(shù)據(jù)庫的最常用標(biāo)準(zhǔn)化語言。MySQL 軟件采用了雙授權(quán)政策,分為社區(qū)版和商業(yè)版,由于其體積小、速度快、總體擁有成本低,尤其是開放源碼這一特點(diǎn),一般中小型網(wǎng)站的開發(fā)都選擇MySQL 作為網(wǎng)站數(shù)據(jù)庫。
在這篇文章,小編要跟大家介紹的是在MySQL面試中的一些題目和答案:
1.mysql的復(fù)制原理以及流程。
(1) 先問基本原理流程,3 個(gè)線程以及之間的關(guān)聯(lián)。
MySQL 的復(fù)制原理:Master 上面事務(wù)提交時(shí)會將該事務(wù)的 binlog event 寫入binlog file,然后 master 將 binlog event 傳到 slave 上面,slave 應(yīng)用該 binlog event 實(shí)現(xiàn)邏輯復(fù)制。MySQL 的復(fù)制是基于如下 3 個(gè)線程的交互(多線程復(fù)制里面應(yīng)該是 4 類線程):
a. Master 上面的 binlog dump 線程,該線程負(fù)責(zé)將 master 的 binlog event 傳到slave;
b. Slave 上面的 IO 線程,該線程負(fù)責(zé)接收 Master 傳過來的 binlog,并寫入 relay log;
c. Slave 上面的 SQL 線程,該線程負(fù)責(zé)讀取 relay log 并執(zhí)行;
d. 如果是多線程復(fù)制,無論是 5.6 庫級別的假多線程還是 MariaDB 或者 5.7 的真正的多線程復(fù)制,SQL 線程只做 coordinator,只負(fù)責(zé)把 relay log 中的 binlog讀出來然后交給worker 線程,woker 線程負(fù)責(zé)具體 binlog event 的執(zhí)行;
(2) 再問一致性延時(shí)性,數(shù)據(jù)恢復(fù)。
一致性可以從以下幾個(gè)方面來講:
a.在 MySQL5.5 以及之前,slave 的 SQL 線程執(zhí)行的 relay log 的位置只能保存在文件(relay-log.info)里面,并且該文件默認(rèn)每執(zhí)行 10000 次事務(wù)做一次同步到磁盤,這意味著 slave 意外 crash 重啟時(shí),SQL 線程執(zhí)行到的位置和數(shù)據(jù)庫的數(shù)據(jù)是不一致的,將導(dǎo)致復(fù)制報(bào)錯(cuò),如果不重搭復(fù)制,則有可能會導(dǎo)致數(shù)據(jù)不一致。MySQL 5.6 引入?yún)?shù) relay_log_info_repository,將該參
數(shù)設(shè)置為TABLE 時(shí),MySQL 將 SQL 線程執(zhí)行到的位置存到mysql.slave_relay_log_info 表,這樣更新該表的位置和 SQL 線程執(zhí)行的用戶事務(wù)綁定成一個(gè)事務(wù),這樣slave 意外宕機(jī)后,slave 通過 innodb 的崩潰恢復(fù)可以把SQL 線程執(zhí)行到的位置和用戶事務(wù)恢復(fù)到一致性的狀態(tài)。
b. MySQL 5.6 引入 GTID 復(fù)制,每個(gè) GTID 對應(yīng)的事務(wù)在每個(gè)實(shí)例上面最多執(zhí)行一次,這極大地提高了復(fù)制的數(shù)據(jù)一致性;
c. MySQL 5.5 引入半同步復(fù)制,用戶安裝半同步復(fù)制插件并且開啟參數(shù)后,設(shè)置超時(shí)時(shí)間,可保證在超時(shí)時(shí)間內(nèi)如果binlog 不傳到 slave 上面,那么用戶提交事務(wù)時(shí)不會返回,直到超時(shí)后切成異步復(fù)制,但是如果切成異步之前用戶線程提交時(shí)在master 上面等待的時(shí)候,事務(wù)已經(jīng)提交,該事務(wù)對 master資源由www.eimhe.com 美河學(xué)習(xí)在線收集提供上面的其他 session 是可見的,如果這時(shí) master 宕機(jī),那么到 slave 上面該事務(wù)又不可見了,該問題直到 5.7 才解決;
d. MySQL 5.7 引入無損半同步復(fù)制,引入?yún)?rpl_semi_sync_master_wait_point,該參數(shù)默認(rèn)為 after_sync,指的是在切成半同步之前,事務(wù)不提交,而是接收到 slave 的 ACK 確認(rèn)之后才提交該事務(wù),從此,復(fù)制真正可以做到無損的了。
e.可以再說一下 5.7 的無損復(fù)制情況下,master 意外宕機(jī),重啟后發(fā)現(xiàn)有 binlog沒傳到 slave 上面,這部分 binlog 怎么辦???分 2 種情況討論,1 宕機(jī)時(shí)已經(jīng)切成異步了,2 是宕機(jī)時(shí)還沒切成異步???這個(gè)怎么判斷宕機(jī)時(shí)有沒有切成異步呢???分別怎么處理???
延時(shí)性:
可以講下5.5 是單線程復(fù)制,5.6 是多庫復(fù)制(對于單庫或者單表的并發(fā)操作是沒用的),5.7 是真正意義的多線程復(fù)制,它的原理是基于 group commit,只要master 上面的事務(wù)是 group commit 的,那 slave 上面也可以通過多個(gè) worker線程去并發(fā)執(zhí)行。和 MairaDB10.0.0.5 引入多線程復(fù)制的原理基本一樣。數(shù)據(jù)恢復(fù)???他想問什么???
(3)再問各種工作遇到的復(fù)制 bug 的解決方法
復(fù)制的bug???上面說的算嗎?我還真沒遇到過,5.6 的多庫復(fù)制有時(shí)候自己會停止,我們寫了一個(gè)腳本重新 start slave;待補(bǔ)充…
這篇文章中小編只列舉的一個(gè)個(gè)例子,大家要是覺得有用的話可以關(guān)注公眾號“鯨魚湖南”,回復(fù)“MySQL面試題”或者“干貨”,小編會發(fā)送給大家一全套的MySQL面試題解。