1. 程式人生 > MYSQL進階教學 ><p>MySQL 物理組成-一條更新語句是如何執行的</p>

<p>MySQL 物理組成-一條更新語句是如何執行的</p>

上一小節,我們介紹了MySQL的日誌檔案和資料檔案,相信大家對MySQL的物理組成已經有了一個初步認識。本小節,我們繼續深入,來看看一條更新語句在MySQL內部是如何執行的?以及 binlog(歸檔日誌)和redo log(重做日誌)在其中所起的重要作用。

1.一條更新語句是如何執行的

相比查詢語句的執行流程,更新語句的執行流程多了兩個重要的日誌模組: binlog(歸檔日誌)和redo log(重做日誌) 。上一小節,我們介紹了這兩個日誌的基本概念,大家可能會有疑問,這兩份日誌,到底有啥區別?為什麼會有兩份日誌呢?

1.1 binlog和redo log的區別

  • binlog是邏輯日誌,記錄某個語句的基本邏輯,即SQL語句;redo log是物理日誌,記錄在某個資料頁所做的修改;
  • binlog是在MySQL的Server層實現,所有的儲存引擎都可以使用binlog這個日誌模組;redo log是InnoDB儲存引擎特有的日誌模組;
  • binlog是追加寫,在寫滿或重啟之後,會生成新的binlog檔案,之前的日誌不會進行覆蓋;redo log是迴圈寫,空間大小是固定的;
  • binlog 是在事務最終提交前寫入的;redo log是在事務執行過程不斷的寫入;
  • binlog可以應用於資料歸檔、主從搭建等場景;redo log作為異常宕機或者介質故障後的資料恢復使用;

1.2 為什麼會有兩份日誌

剛開始MySQL自帶的引擎是MyISAM,然而MyISAM並沒有crash-safe的能力,而binlog只能用於資料歸檔。InnoDB引擎是另外一家公司開發的MySQL外掛,同時開發了redo log來實現crash-safe能力。從5.5.5版本開始,InnoDB成為MySQL的預設儲存引擎,也是當前最常用的儲存引擎。

**Tips:**crash-safe指資料庫發生故障重啟,之前提交的資料不會丟失

1.3 一條更新語句的執行流程

update語句將id等於1這一行的value值加1

update a set value=value+1 where id=1;

表a擁有一個欄位id和一個欄位value

CREATE TABLE `a` (
  `id` int(11) DEFAULT NULL,
  `value` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8

我們來看看這條update語句在MySQL內部是如何執行的?

  1. 執行器通過引擎找到id=1這一行。如果id=1這一行的資料頁在記憶體中,直接返回給執行器;如果不在,則要從磁碟讀入記憶體,再返回給執行器;
  2. 執行器拿到id=1這一行資料,把value值加1,產生一行新的資料,呼叫引擎介面寫入這行新的資料;
  3. 引擎將新的這行資料更新到記憶體中,同時將這個操作記錄到redo log,此時redo log處於prepare狀態;
  4. 執行器生成更新操作的binlog,並寫入磁碟;
  5. 執行器呼叫引擎的事務提交介面,引擎將剛剛寫入的redo log改成commit提交狀態,更新完成。

2.小結

一條更新語句的執行過程,除了要經過連線池、查詢快取、解析器、優化器、執行器這幾個模組之外,還涉及到兩個非常重要的日誌模組: binlog(歸檔日誌)和redo log(重做日誌)。
通過本文的講解,希望您對MySQL的物理組成有更深入的認識。