
1、執(zhí)行的流程
??從上圖大家可以看出,mysql主要涉及兩層:server層和存儲(chǔ)引擎層,server層主要包括:連接器、緩存、分析器、優(yōu)化器、執(zhí)行器,存儲(chǔ)引擎是主要涉及數(shù)據(jù)的存儲(chǔ)以及提供接口給server層進(jìn)行操作,相信上面的圖可以給出比較直觀的展示
2、每個(gè)環(huán)節(jié)的作用
客戶端:主要適配不同開發(fā)語(yǔ)言,通過(guò)客戶端連接上數(shù)據(jù)庫(kù)server;
連接器:客戶端和連接器對(duì)接,連接器會(huì)對(duì)客戶端發(fā)起的連接進(jìn)行鑒權(quán),如果網(wǎng)絡(luò)是連通的,對(duì)于有效的用戶連接則會(huì)建議連接;同時(shí)對(duì)于連接存在長(zhǎng)連接、短連接的情況,具體使用看場(chǎng)景而定;
短連接:連接-> 通信-> 關(guān)閉連接,適用于操作不頻繁的通信場(chǎng)景下,但是對(duì)于高并發(fā)的情況下,例如每秒上萬(wàn)的請(qǐng)求,那么使用短連接是合適,因?yàn)椴捎瞄L(zhǎng)連接的話,占用的系統(tǒng)資源會(huì)更多;同時(shí)這里提到一個(gè)擴(kuò)展點(diǎn),對(duì)于高并發(fā)的情況下,可以通過(guò)調(diào)整服務(wù)器的端口范圍和減少端口回收延期時(shí)間,另外還有一種方式就是一個(gè)主機(jī)多個(gè)ip來(lái)擴(kuò)展;
長(zhǎng)連接:是一些驅(qū)動(dòng)、驅(qū)動(dòng)框架、ORM工具的特性,適用于頻繁與服務(wù)器通信發(fā)送數(shù)據(jù),減少了數(shù)據(jù)庫(kù)scoket連接開銷,但是長(zhǎng)連接過(guò)多、并且不釋放,會(huì)導(dǎo)致內(nèi)存占用提升,它可以節(jié)省創(chuàng)建連接的開銷,但維持連接也是需要內(nèi)存的;
連接池:是應(yīng)用服務(wù)器的組件,它可以通過(guò)參數(shù)來(lái)配置連接數(shù)、連接檢測(cè)、連接的生命周期,連接池或長(zhǎng)連接使用的連接數(shù)很多,有可能會(huì)超過(guò)數(shù)據(jù)庫(kù)實(shí)例的限制,那么就需要留意連接相關(guān)的設(shè)置了,比如連接池的最小、最大連接數(shù)設(shè)置
緩存:對(duì)于緩存,開啟緩存后mysql server會(huì)先查詢緩存,緩存的存儲(chǔ)在內(nèi)存,使用key-value模式進(jìn)行存儲(chǔ),key是sql語(yǔ)句,value是對(duì)應(yīng)的值,但是在mysql 8.0之后,緩存已經(jīng)被刪除了;緩存全面講解可參考:https://zhuanlan.zhihu.com/p/55947158
分析器:簡(jiǎn)單理解為sql語(yǔ)句進(jìn)來(lái)之后,會(huì)進(jìn)行sql語(yǔ)句的詞法分析、語(yǔ)法分析、以及涉及哪些表哪些列,同時(shí)檢查這些表和列是否存在,不存在則拋出異常;
優(yōu)化器:對(duì)于一條sql在執(zhí)行之前,進(jìn)行判定是否可以優(yōu)化執(zhí)行方式,例如是否走索引,化器是在表里面有多個(gè)索引的時(shí)候,決定使用哪個(gè)索引,以及在存在多種執(zhí)行路徑的情況下,選擇哪種執(zhí)行方式,如join操作;
執(zhí)行器:對(duì)真實(shí)的sql進(jìn)行執(zhí)行,開始執(zhí)行的時(shí)候,要先判斷一下你對(duì)這個(gè)表 T 有沒(méi)有執(zhí)行查詢的權(quán)限,操作后數(shù)據(jù)存在內(nèi)存,然后寫入redo_log,此時(shí)redo_log進(jìn)入prepare狀態(tài),然后寫入bin_log,然后調(diào)用存儲(chǔ)引擎接口提交redo_log commit,進(jìn)行數(shù)據(jù)處理和記錄,這里在server層會(huì)記錄bin_log日志,在存儲(chǔ)引擎會(huì)執(zhí)行redo_log日志,這里可以想下為啥需要記錄這兩個(gè)日志,目的是為了啥?
3、兩種日志的說(shuō)明
??首先說(shuō)下redo_log,他是屬于物理日志,記錄數(shù)據(jù)庫(kù)操作的真實(shí)數(shù)據(jù)存儲(chǔ)頁(yè)的變化,首先在執(zhí)行完數(shù)據(jù)操作后,存儲(chǔ)引擎會(huì)將更新數(shù)據(jù)更新在內(nèi)存,然后進(jìn)入prepare狀態(tài),之后server層會(huì)記錄邏輯日志bin_log,記錄好bin_log后,redo_log提交commit,事務(wù)完成,可以看出來(lái)redo_log進(jìn)行了兩步操作,也就是所謂的兩階段提交,這個(gè)時(shí)候回到我們前面的提問(wèn),為啥需要這么做?這個(gè)時(shí)候你的腦海里是不是,冒出一下幾個(gè)問(wèn)題:
這兩種日志的作用是啥?
bin_log作用:
1,用于復(fù)制,在主從復(fù)制中,從庫(kù)利用主庫(kù)上的binlog進(jìn)行重播,實(shí)現(xiàn)主從同步。
2,用于數(shù)據(jù)庫(kù)的基于時(shí)間點(diǎn)的還原。
binlog 有三種模式:Statement(基于 SQL 語(yǔ)句的復(fù)制)、Row(基于行的復(fù)制) 以及 Mixed(混合模式)
redo_log作用
確保事務(wù)的持久性。防止在發(fā)生故障的時(shí)間點(diǎn),尚有臟頁(yè)未寫入磁盤,在重啟 mysql 服務(wù)的時(shí)候,根據(jù) redo log 進(jìn)行重做,從而達(dá)到事務(wù)的持久性這一特性。InnoDB 就可以保證即使數(shù)據(jù)庫(kù)發(fā)生異常重啟,之前提交的記錄都不會(huì)丟失,這個(gè)能力稱為 crash-safe。
兩種日志的區(qū)別:
- redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 層實(shí)現(xiàn)的,所有引擎都可以使用。
- redo log 是物理日志,記錄的是“在某個(gè)數(shù)據(jù)頁(yè)上做了什么修改”;binlog 是邏輯日志,記錄的是這個(gè)語(yǔ)句的原始邏輯,比如“給 ID=2 這一行的 c 字段加 1 ”。
- redo log 是循環(huán)寫的,空間固定會(huì)用完;binlog 是可以追加寫入的?!白芳訉憽笔侵?binlog 文件寫到一定大小后會(huì)切換到下一個(gè),并不會(huì)覆蓋以前的日志
只記錄一種日志行不行?
- 為什么要分兩步?目的是為了啥,不這么做有什么后果?
首先我們看下第一個(gè)問(wèn)題:
這兩種日志的作用是啥?
我們一起看下第2個(gè)問(wèn)題: - 只記錄一種日志行不行?只記錄一種日志,首先innodb是存儲(chǔ)引擎層記錄的,bin_log是server層記錄的,如果僅記錄其中一種,當(dāng)寫入bin_log后crash,這樣bin_log沒(méi)法和存儲(chǔ)層保持一致;因?yàn)樽铋_始 MySQL 里并沒(méi)有 InnoDB 引擎。MySQL 自帶的引擎是 MyISAM,但是 MyISAM 沒(méi)有 crash-safe 的能力,binlog 日志只能用于歸檔。而 InnoDB 是另一個(gè)公司以插件形式引入 MySQL 的,既然只依靠 binlog 是沒(méi)有 crash-safe 能力的,所以 InnoDB 使用另外一套日志系統(tǒng)——也就是 redo log 來(lái)實(shí)現(xiàn) crash-safe 能力
為什么要分兩步?目的是為了啥,不這么做有什么后果?
目的:為了讓兩份日志之間的邏輯一致
事務(wù)的提交要先寫redo log(prepare),再寫binlog,最后再提交(commit)。這里為什么要有個(gè)prepare的動(dòng)作?redo log直接commit狀態(tài)不行嗎?假設(shè)redo log直接提交,在寫binlog的時(shí)候,發(fā)生了crash,這時(shí)binlog就沒(méi)有對(duì)應(yīng)的數(shù)據(jù),那么所有依靠binlog來(lái)恢復(fù)數(shù)據(jù)的slave,就沒(méi)有對(duì)應(yīng)的數(shù)據(jù),導(dǎo)致主從不一致。所以需要通過(guò)兩段式(2pc)提交來(lái)保證redo log和binlog的一致性是非常有必要的。具體的步驟是:處于prepare狀態(tài)的redo log,會(huì)記錄2PC的XID,binlog寫入后也會(huì)記錄2PC的XID,同時(shí)會(huì)在redo log上打上commit標(biāo)識(shí)
總結(jié)
??redolog和binlog具有關(guān)聯(lián)行,在恢復(fù)數(shù)據(jù)時(shí),redolog用于恢復(fù)主機(jī)故障時(shí)的未更新的物理數(shù)據(jù),binlog用于備份操作。每個(gè)階段的log操作都是記錄在磁盤的,在恢復(fù)數(shù)據(jù)時(shí),redolog 狀態(tài)為commit則說(shuō)明binlog也成功,直接恢復(fù)數(shù)據(jù);如果redolog是prepare,則需要查詢對(duì)應(yīng)的binlog事務(wù)是否成功,決定是回滾還是執(zhí)行。
4、參考文獻(xiàn)
https://time.geekbang.org/column/article/68633
https://zhuanlan.zhihu.com/p/55947158
https://blog.csdn.net/tototuzuoquan/article/details/78573955
https://juejin.cn/post/7007945074080235534