MYSQL學習筆記 SQL更新語句的執行

2021-10-08 15:42:36 字數 1726 閱讀 9167

mysql更新語句是這樣子的:

mysql> update t set c=c+1 where id=2;
更新語句跟查詢語句走的流程是一樣的:

跟查詢一樣,聯結器----》查詢快取—》分析器----》優化器—》執行器。

與查詢不同的地方,多了兩個日誌模組redolog和binlog.

redo log

由於每次操作如果每次對資料庫的操作都寫入磁碟進行持久化的,整個操作的io成本,查詢成本都很高。所以mysql設計者就用了wal技術(write-ahead logging).原理就是先寫日誌,在不忙的時候在寫磁碟,提高效率。

innoddb先把記錄寫入日誌,更新記憶體,然後直接返回。redo log的大小是固定的,比如可以配置一組4個,每個1gb,總共用4g的快取空間。同時redo log採用了迴圈緩衝區的資料結構,如下圖:

當write_pos 等於check point的時候,表示緩衝區已經滿了,需要先清理一下緩衝區。

有了這個設計,就可以保證crach-safe,當資料庫異常重啟的時候,之前提交的事物記錄都不會丟失。

binlog

binlog(歸檔日誌),是mysql server層,不具備crach-safe能力。redo log是innodb擁有的。

不同的地方:

1 redo log 是 innodb 引擎特有的;binlog 是 mysql 的 server 層實現的,所有引擎都可以使用。

2 redo log 是物理日誌,記錄的是「在某個資料頁上做了什麼修改」;binlog 是邏輯日誌,記錄的是這個語句的原始邏輯,比如「給 id=2 這一行的 c 欄位加 1 」。

3 redo log 是迴圈寫的,空間固定會用完;binlog 是可以追加寫入的。「追加寫」是指 binlog 檔案寫到一定大小後會切換到下乙個,並不會覆蓋以前的日誌。

更新語句執行流程:

1 執行器找引擎拿到id=2這一行,如果在記憶體,直接從記憶體裡面取。如果不在記憶體,則從磁碟裡面拿。

2 拿到資料後進行+1操作,呼叫引擎介面寫入。

3 引擎寫入記憶體,同時寫入redo log,並把狀態改為prepare,告知執行器執行完成,可以隨時進行提交事物

4 執行器生成binlog,並持久化到磁碟

5 執行器開始提交事務,引擎把redo log的狀態從perpare改為commited

兩階段提交

其實就算讓兩個不同的檔案儲存邏輯上的一致

順序不能變,假設:

1 先寫 redo log 後寫 binlog。

redo log 寫完,但是沒有寫binlog,發生了崩潰。redo log已經寫完,binlog沒有寫。使用binlog備份的時候就會少記錄,那麼用這個binlog去恢復的時候就會造成丟失資料。

2 先寫 binlog 後寫 redo log

binlog寫完,redolog沒有寫入就崩潰了。那麼這個事物是無效的,因為redolog沒有這一條記錄,但是binlog卻有這條記錄,從binlog恢復的時候就會多出一條事物,造成了資料的不一致。

MySQL學習筆記(二)一條SQL更新語句

從乙個表的一條更新語句說起,下面是這個表的建立語句,這個表有乙個主鍵id和乙個整型欄位c mysql create table t id int primary key,c int 假如將id 2這一行的值加1 執行語句要先通過聯結器連線資料庫。在乙個表上更新的時候,跟這個表有關的查詢快取會失效。接...

mysql學習 日誌系統 sql更新語句的執行過程

前言 對於更新語句來說,流程是和查詢語句是一樣的,同樣要經過聯結器,分析器,優化器,執行器。mysql update t set c c 1where id 2 不一樣的是,更新流程還涉及到兩個日誌模組 walwal 的全稱是 write ahead logging,它的關鍵點就是先寫日誌,再寫磁碟...

SQL更新語句執行

分析器 解析知道這是一條更新語句 優化器 決定使用id索引 執行器 具體執行 包括執行 1之類的 redolog crash safe能力,write pos和checkpoint的概念。引擎層innodb,在資料庫讀取的時候不會用redolog合併,會用change buffer中的資料 binl...