mysql日誌系統 SQL 邏輯日誌 物理日誌

2022-05-23 02:09:09 字數 3236 閱讀 4546

更新語句執行的流程和查詢語句執行的流程一樣

注意:在乙個表上有更新的操作的時候,和這個表相關的查詢快取就會被清空

在經歷分析器,優化器,和執行器儲存引擎的歷程中,還多了重要的日誌模組

redo log 重做日誌

bin log 歸檔日誌

是innodb 引擎獨有的日誌模組

它的關鍵點就是更新的時候先寫日誌,再寫磁碟,在任務不忙的時候將大量的積累更新操作一塊兒進行

io寫入磁碟

innodb

的redo log

是固定大小的,比如可以配置為一組

4個檔案,每個檔案的大小是

1gb,那麼這塊"粉板

"總共就可以記錄

4gb的操作。從頭開始寫,寫到末尾就又回到開頭迴圈寫,如下面這個圖所示

是當前記錄的位置,一邊寫一邊後移,寫到第

3號檔案末尾後就回到

0號檔案開頭。

checkpoint

是當前要擦除的位置,也是往後推移並且迴圈的,擦除記錄前要把記錄更新到資料檔案。

write pos

和checkpoint

之間的是"粉板

"上還空著的部分,可以用來記錄新的操作。如果

write pos

追上checkpoint

,表示"粉板"

滿了,這時候不能再執行新的更新,得停下來先擦掉一些記錄,把

checkpoint

推進一下。

有了redo log

,innodb

就可以保證即使資料庫發生異常重啟,之前提交的記錄都不會丟失,這個能力稱為

crash-safe

是service層日誌模組

所有引擎都可以用

binlog以追加的方式記錄邏輯操作 是由執行器生成的

為什麼會有兩份日誌模組?

因為最開始

mysql

裡並沒有

innodb

引擎。mysql

自帶的引擎是

myisam

,但是myisam

沒有crash-safe

的能力,

binlog

日誌只能用於歸檔。而

innodb

是另乙個公司以外掛程式形式引入

mysql

的,既然只依靠

binlog

是沒有crash-safe

能力的,所以

innodb

使用另外一套日誌系統

——也就是

redo log

來實現crash-safe

能力兩種日誌特點對比:

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

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

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

執行器先找引擎取id=2這一行。id是主鍵,引擎直接用樹搜尋找到這一行。如果id=2這一行所在的資料頁本來就在記憶體中,就直接返回給執行器;否則,需要先從磁碟讀入記憶體,然後再返回。

執行器拿到引擎給的行資料,把這個值加上1,比如原來是n,現在就是n+1,得到新的一行資料,再呼叫引擎介面寫入這行新資料。

引擎將這行新資料更新到記憶體中,同時將這個更新操作記錄到redo log裡面,此時redo log處於prepare狀態。然後告知執行器執行完成了,隨時可以提交事務。

執行器生成這個操作的binlog,並把binlog寫入磁碟。

執行器呼叫引擎的提交事務介面,引擎把剛剛寫入的redo log改成提交(commit)狀態,更新完成。

執行流程圖,

圖中淺色框表示是在

innodb

內部執行的,

深色框表示是在執行器中執行的

重點:binlog 的完成在redolog 的prepare和commit之間

在binlog之前 redolog已經準備好在記憶體中,但是未寫入磁碟

在binlog之後 redolog 才處於提交狀態準備寫入磁碟。

redolog 和binlog是兩個獨立的階段,並不依賴

即,資料已經在記憶體中修改完畢,修改資料的操作也記錄完了,

但是資料庫的磁碟檔案還沒有真正寫入。

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

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

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

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

注意

redo log用於保證crash-safe能力。innodb_flush_log_at_trx_commit這個引數設定成1的時候,表示每次事務的redo log都直接持久化到磁碟。這個引數建議你設定成1,這樣可以保證mysql異常重啟之後資料不丟失。

sync_binlog這個引數設定成1的時候,表示每次事務的binlog都持久化到磁碟。這個引數建議你設定成1,這樣可以保證mysql異常重啟之後binlog不丟失。

mysql獲取邏輯日誌 MySQL 三種日誌

日誌是 資料庫的重要組成部分,記錄著資料庫執行期間各種狀態資訊。日誌主要包括錯誤日誌 查詢日誌 慢查詢日誌 事務日誌 二進位制日誌幾大類。作為開發,我們重點需要關注的是二進位制日誌 和事務日誌 包括 和 本文接下來會詳細介紹這三種日誌。binlog 用於記錄資料庫執行的寫入性操作 不包括查詢 資訊,...

11 日誌系統

作為黑客,日誌檔案可以跟蹤目標的活動和身份。但它也可以是你自己在別人系統上的活動痕跡。攻擊方使用日誌系統,抹掉自己的痕跡,防守方備份日誌系統,尋找攻擊方。保護系統,知道如何管理日誌記錄功能,以確定系統是否受到攻擊,破譯實際發生的事情以及是誰在攻擊你。查到第乙個攻擊目標,進一步確認目標的日誌系統看是否...

MySQL日誌系統

從乙個更新操作開始 mysql create table t id int primary key,c int mysql update t set c c 1 where id 2 與查詢流程不一樣的是,更新流程還涉及兩個重要的日誌模組,它們正是我們今天要討論的主角 redo log 重做日誌 和...