sql更新是如何執行的?

李宗俍發表於2019-04-26


update from set a = 1 where id = 1複製程式碼


首先看一下一張圖(圖片來自 sql查詢是如何執行的?

sql更新是如何執行的?

和查詢類似,也會走同樣的邏輯。
1. 建立連線。

2. 清除快取。

3. 分析器 分析語法,檢查表和欄位是否存在。

4. 優化器,決定是否使用索引,使用哪一個索引。

5. 執行器。主要區別在這一層,下面說說我理解的具體區別。

與查詢流程不同的是,更新涉及到redo_log (重做日誌) 和 binlog(歸檔日誌)


redo log

如果更新資料直接修改磁碟資料,會首先找到磁碟中的資料,然後在修改磁碟中的資料,io成本會很高。所以mysql更新不會直接修改邏輯資料,而是先寫到記憶體中,然後等mysql空閒之後,會同步到硬碟。

1. 作用在儲存引擎上,innodb 特有的。

2. redo log 大小是固定的。類似一個環,每次寫滿之後會強制重新整理,從頭開始寫。

3. redo log 會保證即使資料庫發生異常,資料也不會丟失。

4. 物理日誌,記錄了在哪個資料頁上的修改


binlog

作用在service層,是mysql的日誌,所有儲存引擎都可以使用。記錄了所有增刪改的邏輯日誌。

記錄方式 statement   記錄sql語句  row  記錄每一行資料的改動,mixed(混合模式) mysql會根據具體的sql來決定按照什麼方式進行記錄

執行器的執行流程

update t set a=a+1 where id=1;複製程式碼

  1.  呼叫儲存引擎介面,找到id=1這一條記錄。如果資料在記憶體中直接返回,否則先從磁碟中讀到記憶體,然後返回
  2.  執行器拿到結果,進行+1操作,再呼叫儲存引擎介面寫入新資料。
  3. 儲存引擎將這行資料更新到記憶體,同時記錄redo log(perpare) 然後返回成功
  4. 執行器生成binlog,把binlog寫入磁碟。
  5. 呼叫引擎提交事務,把redo log 改成提交狀態(commit)。更新完成


sql更新是如何執行的?

兩階段提交

上面redo log 2次寫入被稱為兩階段提交。

redo log 保證了及時異常重啟,也會把資料重新整理到磁碟中。binlog主要適用於資料備份的。

目的:因為redo log 和binlog 是2個完全不同的東西,一個是儲存引擎實現的一個是資料庫本身實現的。所以為了保證redo log 和binglog 的一致性,引入了兩階段提交。


uodo log 只是為了回滾使用,比如把name=‘a’ 修改為name = ‘b’ ,那麼undo日誌就會用來存放name=’a’的記錄,如果這個修改出現異常,可以使用undo日誌來實現回滾操作,保證事務的一致性。






相關文章