使用update語句修改表中數據「updateset多條數據」

概述

今天主要簡單介紹一下select語句的流程、update語句執行流程以及涉及的兩階段提交協議,僅供參考。

redo log(innodb引擎獨有,循環寫,空間固定會用完,比如配置一組4個文件,每個文件大小為4GB,則總共可以記錄4GB的操作)是物理日誌,記錄的在「在某個數據頁上做了什麼修改」;

binlog(mysql的server層實現,日誌追加寫)是邏輯日誌,記錄的是這個語句的原始邏輯。

如果每一次數據更新的時候都需要寫進磁盤,然後磁盤找對應記錄,然後再更新,整個過程IO成本、查找成本都很高,而mysql數據庫採用WAL(write-ahead logging)來解決這個問題,關鍵在先寫日誌,再寫磁盤。也就是當數據庫進行更新的時候,innodb引擎先把記錄寫到redo log,並更新內存,這時候更新就算完成了,同時innodb引擎會在適當時候更新到磁盤。當redo log空間不夠時則先將redo log內容寫到磁盤再繼續工作。


先理解mysql數據庫如何實現崩潰恢復?

1、MySQL沒有開啟Binary log的情況下:

InnoDB存儲引擎通過redo和undo日誌可以safe crash recovery數據庫,當數據crash recovery時,通過redo日誌將所有已經在存儲引擎內部提交的事務應用redo log恢復,所有已經prepared但是沒有commit的transactions將會應用undo log做roll back。然後客戶端連接時就能看到已經提交的數據存在數據庫內,未提交被回滾的數據需要重新執行。

2、MySQL開啟Binary log 的情況下:

為了保證存儲引擎和MySQL數據庫上層的二進制日誌保持一致(因為備庫通過二進制日誌重放主庫提交的事務,假設主庫存儲引擎已經提交而二進制日誌沒有保持一致,則會使備庫數據丟失造成主備數據不一致),引入二階段提交(two phase commit or 2pc)


理解mysql數據庫select語句流程

從mysql數據庫update流程理解兩階段提交協議

update語句執行流程

從mysql數據庫update流程理解兩階段提交協議

換個角度考慮為什麼要設計兩階段提交

從mysql數據庫update流程理解兩階段提交協議

2PC協議也成為2段提交,1prepare階段,2commit階段。

所謂的兩個階段是指:第一階段:準備階段(投票階段)和第二階段:提交階段(執行階段)

為什麼要有兩階段提交?這是為了讓redo log和binlog日誌之間的邏輯一致。

由於redo log和binlog是兩個獨立的邏輯,如果不用兩階段提交,那就是先寫完redo log,再寫binlog,或者採用反過來的順序。

以update語句為例:update t set c = c+1 where id=2;

假設執行 update 語句過程中在寫完第一個日誌後,第二個日誌還沒有寫完期間發生了 crash,會出現什麼情況呢?

1、先寫 redo log 後寫 binlog

假設在 redo log 寫完,binlog 還沒有寫完的時候,MySQL 進程異常重啟。由於我們前面說過的,redo log 寫完之後,系統即使崩潰,仍然能夠把數據恢復回來,所以恢復後這一行 c 的值是 1。

但是由於 binlog 沒寫完就 crash 了,這時候 binlog 裏面就沒有記錄這個語句。因此,之後備份日誌的時候,存起來的 binlog 裏面就沒有這條語句。

然後你會發現,如果需要用這個 binlog 來恢復臨時庫的話,由於這個語句的 binlog 丟失,這個臨時庫就會少了這一次更新,恢復出來的這一行 c 的值就是 0,與原庫的值不同。

即:

在寫binlog之前崩潰時:

1)重啟恢復:發現沒有commit,回滾

2)備份恢復:沒有binlog

3)結果:事務一致

2、先寫 binlog 後寫 redo log

如果在 binlog 寫完之後 crash,由於 redo log 還沒寫,崩潰恢復以後這個事務無效,所以這一行 c 的值是 0。但是 binlog 裏面已經記錄了「把 c 從 0 改成 1」這個日誌。所以,在之後用 binlog 來恢復的時候就多了一個事務出來,恢復出來的這一行 c 的值就是 1,與原庫的值不同。

在redo log commit階段之前崩潰時:

1)重啟恢復:沒有commit,但滿足prepare和binlog完整,重啟後自動commit

2)備份恢復:記錄binlog

3)結果:事務一致

可以看到,如果不使用「兩階段提交」,那麼數據庫的狀態就有可能和用它的日誌恢復出來的庫的狀態不一致。


通過上面的內容大家可以理解mysql數據庫為什麼要去設計WAL,在理解select、update語句執行流程後再去理解為什麼要去設計二階段提交協議,如果沒有二階段提交協議會怎樣?最後大家有空可以再去考慮三段提交協議,以及為了提高效率在mysql 5.6所設計的組提交概念。

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/209399.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-08 15:36
下一篇 2024-12-08 15:36

相關推薦

發表回復

登錄後才能評論