Mysql三類log解析
MySQL裡邊還有幾種常見的
log
,分別為:
-
undo log
-
binlog
-
redo log
一、什麼是binlog
binlog
其實在日常的開發中是聽得很多的,因為很多時候資料的更新就依賴著
binlog
。
舉個很簡單的例子:我們的資料是儲存在資料庫裡邊的嘛,現在我們對某個商品的某個欄位的內容改了(資料庫變更),而 使用者檢索的出來資料是走搜尋引擎的。為了讓使用者能搜到最新的資料,我們需要把引擎的資料也改掉。
一句話: 資料庫的變更,搜尋引擎的資料也需要變更。
於是,我們就會監聽
binlog
的變更,如果
binlog
有變更了,那我們就需要將變更寫到對應的資料來源。
什麼是binlog
?
binlog
記錄了資料庫表結構和表資料變更,比如
update/delete/insert/truncate/create
。它不會記錄
select
(因為這沒有對錶沒有進行變更)
binlog
長什麼樣?
binlog
我們可以簡單理解為:儲存著每條變更的
SQL
語句(當然從下面的圖看來看,不止SQL,還有XID「事務Id」等等)
binlog
一般用來做什麼
主要有兩個作用: 複製和恢復資料
- MySQL在公司使用的時候往往都是
一主多從結構的,從伺服器需要與主伺服器的資料保持一致,這就是透過
binlog
來實現的 - 資料庫的資料被幹掉了,我們可以透過
binlog
來對資料進行恢復。
因為
binlog
記錄了資料庫表的變更,所以我們可以用
binlog
進行復制(主從複製)和恢復資料。
二、什麼是redo log
假設我們有一條sql語句:
update user_table set name='java3y' where id = '3'
MySQL執行這條SQL語句,肯定是先把
id=3
的這條記錄查出來,然後將
name
欄位給改掉。這沒問題吧?
實際上Mysql的基本儲存結構是 頁(記錄都存在頁裡邊),所以MySQL是先把這條記錄所在的 頁找到,然後把該頁載入到記憶體中,將對應記錄進行修改。
現在就可能存在一個問題: 如果在記憶體中把資料改了,還沒來得及落磁碟,而此時的資料庫掛了怎麼辦?顯然這次更改就丟了。
如果每個請求都需要將資料 立馬落磁碟之後,那速度會很慢,MySQL可能也頂不住。所以MySQL是怎麼做的呢?
MySQL引入了
redo log
,記憶體寫完了,然後會寫一份
redo log
,這份
redo log
記載著這次
在某個頁上做了什麼修改。
其實寫
redo log
的時候,也會有
buffer
,是先寫
buffer
,再真正落到磁碟中的。至於從
buffer
什麼時候落磁碟,會有配置供我們配置。
所以,
redo log
的存在為了:當我們修改的時候,寫完記憶體了,但資料還沒真正寫到磁碟的時候。此時我們的資料庫掛了,我們可以根據
redo log
來對資料進行恢復。因為
redo log
是順序IO,所以
寫入的速度很快,並且
redo log
記載的是物理變化(xxxx頁做了xxx修改),檔案的體積很小,
恢復速度很快。
三、binlog和redo log
看到這裡,你可能會想:
binlog
和
redo log
這倆也太像了吧,都是用作”恢復“的。
其實他倆除了"恢復"這塊是相似的,很多都不一樣,下面看我列一下。
儲存的內容
binlog
記載的是
update/delete/insert
這樣的SQL語句,而
redo log
記載的是物理修改的內容(xxxx頁修改了xxx)。
所以在搜尋資料的時候會有這樣的說法:
redo log
記錄的是資料的
物理變化,
binlog
記錄的是資料的
邏輯變化
功能
redo log
的作用是為
持久化而生的。寫完記憶體,如果資料庫掛了,那我們可以透過
redo log
來恢復記憶體還沒來得及刷到磁碟的資料,將
redo log
載入到記憶體裡邊,那記憶體就能恢復到掛掉之前的資料了。
binlog
的作用是複製和恢復而生的。
- 主從伺服器需要保持資料的一致性,透過
binlog
來同步資料。 - 如果整個資料庫的資料都被刪除了,
binlog
儲存著所有的資料變更情況,那麼可以透過binlog
來對資料進行恢復。
又看到這裡,你會想:”如果整個資料庫的資料都被刪除了,那我可以用
redo log
的記錄來恢復嗎?“
不能
因為功能的不同,
redo log
儲存的是物理資料的變更,如果我們記憶體的資料已經刷到了磁碟了,那
redo log
的資料就無效了。所以
redo log
不會儲存著
歷史所有資料的變更,
檔案的內容會被覆蓋的。
binlog和redo log 寫入的細節
redo log
是MySQL的InnoDB引擎所產生的。
binlog
無論MySQL用什麼引擎,都會有的。
InnoDB是有事務的,事務的四大特性之一:永續性就是靠
redo log
來實現的(如果寫入記憶體成功,但資料還沒真正刷到磁碟,如果此時的資料庫掛了,我們可以靠
redo log
來恢復記憶體的資料,這就實現了永續性)。
上面也提到,在修改的資料的時候,
binlog
會記載著變更的類容,
redo log
也會記載著變更的內容。(只不過一個儲存的是物理變化,一個儲存的是邏輯變化)。那他們的寫入順序是什麼樣的呢?
redo log
事務開始的時候,就開始記錄每次的變更資訊,而
binlog
是在
事務提交的時候才記錄。
於是新有的問題又出現了:我寫其中的某一個
log
,失敗了,那會怎麼辦?現在我們的前提是先寫
redo log
,再寫
binlog
,我們來看看:
- 如果寫
redo log
失敗了,那我們就認為這次事務有問題,回滾,不再寫binlog
。 - 如果寫
redo log
成功了,寫binlog
,寫binlog
寫一半了,但失敗了怎麼辦?我們還是會對這次的 事務回滾,將無效的binlog
給刪除(因為binlog
會影響從庫的資料,所以需要做刪除操作) - 如果寫
redo log
和binlog
都成功了,那這次算是事務才會真正成功。
簡單來說:MySQL需要保證
redo log
和
binlog
的
資料是一致的,如果不一致,那就亂套了。
- 如果
redo log
寫失敗了,而binlog
寫成功了。那假設記憶體的資料還沒來得及落磁碟,機器就掛掉了。那主從伺服器的資料就不一致了。(從伺服器透過binlog
得到最新的資料,而主伺服器由於redo log
沒有記載,沒法恢復資料) - 如果
redo log
寫成功了,而binlog
寫失敗了。那從伺服器就拿不到最新的資料了。
MySQL透過
兩階段提交來保證
redo log
和
binlog
的資料是一致的。
四、什麼是undo log
undo log
有什麼用?
undo log
主要有兩個作用:回滾和多版本控制(MVCC)
在資料修改的時候,不僅記錄了
redo log
,還記錄
undo log
,如果因為某些原因導致事務失敗或回滾了,可以用
undo log
進行回滾
undo log
主要儲存的也是邏輯日誌,比如我們要
insert
一條資料了,那
undo log
會記錄的一條對應的
delete
日誌。我們要
update
一條記錄時,它會記錄一條對應
相反的update記錄。
這也應該容易理解,畢竟回滾嘛,跟需要修改的操作相反就好,這樣就能達到回滾的目的。因為支援回滾操作,所以我們就能保證:“ 一個事務包含多個操作,這些操作要麼全部執行,要麼全都不執行”。【原子性】
因為
undo log
儲存著修改之前的資料,相當於一個
前版本,MVCC實現的是讀寫不阻塞,讀的時候只要返回前一個版本的資料就行了。
注:內容整理自公眾號Java3y
【沒想到MySQL還會問這些...】
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69994536/viewspace-2763270/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【Mysql】三大日誌 redo log、bin log、undo logMySql
- MySQL error log和bin logMySqlError
- log工具類
- 必須瞭解的mysql三大日誌-binlog、redo log和undo logMySql
- 解析 crash log(一)
- MySQL Binary LogMySql
- MySQL的Redo log 以及Bin logMySql
- MySQL Undo Log和Redo Log介紹MySql
- MySQL中的redo log和undo logMySql
- mysql之 redo logMySql
- MySQL的general_log和slow_logMySql
- ELK收集mysql_slow.logMySql
- MySQL:慢SQL(slow_log)MySql
- MySQL8.0:The General Query LogMySql
- MySQL redo log最佳化MySql
- MySQL重做日誌(redo log)MySql
- mysql日誌:redo log、binlog、undo log 區別與作用MySql
- MySQL中redo log、undo log、binlog關係以及區別MySql
- 深入理解MySQL系列之redo log、undo log和binlogMySql
- mysql8 log_status 查詢pos與gtid不一致 bug解析MySql
- kafka-log日誌程式碼解析Kafka
- 開啟 mysql 的 general_logMySql
- MySQL中的redo log和checkpointMySql
- 基於Redo Log和Undo Log的MySQL崩潰恢復流程MySql
- InnoDB文件筆記(三)—— Undo Log筆記
- 高通進dump和抓取解析dump log
- MySQL中undo log介紹及清理MySql
- MySQL 日誌系統 redo log、binlogMySql
- MySQL [ERROR] Slave I/O: Found a Gtid_log_event or Previous_gtids_log_eventMySqlError
- estk/log4rs: 類似log4j的Rust日誌框架Rust框架
- Mysql系統變數中 log_error_services | log_filter_internal; log_sink_internal 和 log_error_verbosity | 2 解釋MySql變數ErrorFilter
- ClickHouse(16)ClickHouse日誌引擎Log詳細解析
- 容器類原始碼解析系列(三)—— HashMap 原始碼分析(最新版)原始碼HashMap
- mysql relay log相關引數說明MySql
- mysql5.7.22-log 修改遠端訪問MySql
- mysql之 slow log 慢查詢日誌MySql
- MySQL relay log 詳細引數解釋MySql
- MySQL Slow Query log(慢查詢日誌)MySql