mysql中一条SQLupdate语句是如何执行的?redo log 与binlog
mysql> create table T(id int primary key,c int);
mysql> update T set c=c+1 where id=2;
大體流程與查詢流程是一樣的:先是檢查連接權限,然后經過分析器,知道是更行語句,查詢緩沖遇到更行語句就清空該表的查詢緩存;優化器決定使用id這個索引并生成執行計劃;執行器負責執行,找到這一行,并進行更行。
與查詢流程不一樣的是:更新流程還涉及兩個重要的日志模塊:redo log與binlog(歸檔日志)
………………………………………………………………………………………………………………………………………………
Redo log
一個店家有兩個賬本,A一個記錄了所有的客戶消費信息與欠賬信息;
可日常繁忙時,無法快速定位將客人信息記錄到A中,這時就需要臨時有一個B,隨時記錄客人消費信息;等晚上客人走了,再將B中的信息整理到A中;
B賬本就是redo log
……………………………………………………………………………………………………………………………………………………
Mysql里也有這個問題,如果每一次的更行操作都需要寫入磁盤,然后磁盤也要找到對應的那條記錄,然后再更行,整個過程IO成本,查找成本會很高。
Mysql就找到一種解決方法:就是WAL技術:先寫日志,再寫磁盤。
具體來說:當有一條記錄需要更新的時候,INNODB引擎就會把記錄寫到redo log,并更行內存,這個時候更新就算完成了;同時,innodb引擎會在適當的時候,將這個操作記錄更新到磁盤里面。
……………………………………………………………………………………………………………………………………
店鋪掌柜,發現B賬本快寫滿了,那么他就會將已經寫進A賬本的記錄擦掉,就有了剩余空間,繼續往里面寫記錄
……………………………………………………………………………………………………………………………………
write pos 是當前記錄的位置,一邊寫一邊后移,寫到第 3 號文件末尾后就回到 0 號文件開頭。checkpoint 是當前要擦除的位置,也是往后推移并且循環的,擦除記錄前要把記錄更新到數據文件。
如果wiite pos 追上了checkpoint,表示redo已經滿了,不能繼續執行更行操作了,要停下來,等checkpoint向前推移,有了剩余空間,再繼續更新
…………………………………………………………………………………………………………………………………………
有了redo log,innodb就可以保證數據庫發生異常重啟后,之前提交的記錄都不會丟失,這個能力稱為crash-safe
Redolog 不是記錄數據頁“更改之后的狀態”,而是記住“頁做了什么改動”
Binlog有兩種模式,statement格式記錄sql語句;row格式記錄行內容:更行前后都有
一般選用row模式,因為遇到主從不一致時,row模式,更改前后都有,恢復之后,不會丟失某個事務的數據。
兩種日志的不同:
這兩種日志有以下三點不同。
1 redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 層實現的,所有引擎都可以使用。
2 redo log 是物理日志,記錄的是“在某個數據頁上做了什么修改”;binlog 是邏輯日志,記錄的是這個語句的原始邏輯,比如“給 ID=2 這一行的 c 字段加 1 ”。
3 redo log 是循環寫的,空間固定會用完;binlog 是可以追加寫入的。“追加寫”是指 binlog 文件寫到一定大小后會切換到下一個,并不會覆蓋以前的日志。
……………………………………………………………………………………………………………………………………………………
Binlog或redolog可以二選一嗎?
首先,redo log只有innodb引擎才有,所以不能丟;redo log不具備歸檔的功能,刷到磁盤后就被清除了;而binlog是追加,可以歸檔,用作數據庫恢復,數據庫擴容都很重要。
……………………………………………………………………………………………………………………………………………………
執行器先找引擎取ID=2,ID是主鍵,引擎通過索引快速找到ID=2這一行;如果這一行本就在內存中,就直接返回給執行器;否則需要從磁盤讀入內存,然后再返回。
執行器拿到引擎給的行數據,把這個值加1,得到新的行數據,再調用引擎接口寫入這行新數據。
引擎將這行數據更新到內存中,同時將這個更行操作記錄到redo log中,此時redo log處于prepare狀態。然后告知執行器執行完成了,隨時可以提交事務。
執行器生成這個操作的binlog,并把binlog寫入磁盤。
執行器調用引擎接口,引擎把redo log 改成commit狀態,更新完成。
最后三步看上去有點繞,將redo log寫入拆分為兩個步驟:prepart和commit------兩階段提交。
…………………………………………………………………………………………………………………………………………
內容主體來自林曉斌老師《mysql實戰45講》
總結
以上是生活随笔為你收集整理的mysql中一条SQLupdate语句是如何执行的?redo log 与binlog的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql中,一条select语句是如何
- 下一篇: 验证MYSQL安装成功