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...