
開局一張圖 內(nèi)容全靠編
本文主要說一下,應(yīng)用程序在與數(shù)據(jù)庫交互時(shí),數(shù)據(jù)庫的大概執(zhí)行流程。整體上了解一下一條SQL的流轉(zhuǎn)。
- 建立連接
應(yīng)用程序與MySQL各自使用線程池,來維護(hù)之間的連接。每個(gè)連接都是一個(gè)線程,從而實(shí)現(xiàn)并發(fā)訪問MySQL。
- 客戶端發(fā)送 SQL
- 查詢緩存,查詢語句與緩存中的完全一致(包括參數(shù)且不能存在不確定參數(shù)比如 now()),則將查詢到的結(jié)果返回。
- SQL 解析器,解析 SQL 判斷 SQL 是否合法。
- 查詢優(yōu)化器,根據(jù)解析器結(jié)果生成最佳的執(zhí)行計(jì)劃。
- 選擇合適的存儲(chǔ)引擎進(jìn)行操作數(shù)據(jù)(圖中是 InnoDB 存儲(chǔ)引擎)
InnoDB執(zhí)行流程將需要操作的數(shù)據(jù)從磁盤文件中查詢出來,放入緩沖池(Buffer Pool)。如果緩沖池中已經(jīng)存在則不需要查詢磁盤。(查詢SQL此時(shí)會(huì)返回結(jié)果)
將 舊數(shù)據(jù) 寫入 undo log。(undo log 用于事務(wù)回滾)
更新緩沖池中的數(shù)據(jù)。
寫入 Redo Log Buffer。(redo log 主要用于 MySQL 突然宕機(jī)的數(shù)據(jù)恢復(fù))(此時(shí)寫入的日志存儲(chǔ)于內(nèi)存中)
-
redo log 寫入磁盤的時(shí)機(jī)。
innodb_flush_log_at_trx_commitmysql 的這個(gè)配置來控制寫入 redo log 的時(shí)機(jī) 默認(rèn) 為 1
0時(shí) 事務(wù)提交時(shí),不寫入redo 磁盤文件,而是由 InnoDB存儲(chǔ)引擎線程來定時(shí)寫入磁盤. 性能最好,但是宕機(jī)會(huì)丟失數(shù)據(jù)
1時(shí) 事務(wù)提交時(shí),寫入 redo 磁盤文件。安全性最高,不會(huì)丟失數(shù)據(jù),相對性能差。
2 事務(wù)提交時(shí),不寫入redo 磁盤文件,而是寫入 os cache。然后再從os cache 寫入 磁盤文件。性能比1好,但是比0差,如果機(jī)器宕機(jī)則會(huì)丟失數(shù)據(jù)。 -
寫入 binlog 日志. (用于數(shù)據(jù)庫恢復(fù)和主從復(fù)制)
sync_binlog控制binlog寫入磁盤策略 默認(rèn)=0
=0時(shí)先寫入 OS cache 然后寫入磁盤
=1直接寫入磁盤 redo log 與 bin log 全部寫入成功后提交事務(wù)完成
以上就是大概 SQL 的運(yùn)行流程。主要描述的是 InnoDB 存儲(chǔ)引擎。