mysql寫日誌的流程 MySQL中日誌機制

2021-10-25 14:55:38 字數 4803 閱讀 6479

1、wal機制

在mysql中,為了提高資料庫的效能,mysql採用了wal(write-ahead logging)機制,即客戶端在修改資料的過程後,並不會立馬對硬碟中的資料進行更新。

這樣做的原因在於,如果每次客戶端進行資料更改後,立馬對磁碟中的資料進行更改的話,那麼磁碟的壓力是非常大的。

想想看,mysql改資料之前要先定位資料,那麼定位資料的過程可能會是磁碟的隨機讀,隨機讀的過程是非常慢的。

資料庫在併發的情況下,大量的隨機讀盤會造成資料庫在某一時刻的效能將變得很低很低。所以,mysql要引入wal機制來減少這種情況的發生。

wal機制,主要的操作是先寫日誌,先在乙個日誌中記錄了mysql要對硬碟中的儲存mysql資料的資料頁中的資料進行什麼樣的更改,等到mysql空閒的時候再進行同步操作到硬碟中。

舉個例子,就是我們作為開發人員,同一時間不可能處理10個需求,而是需要通過協同工具,處理完乙個再到另外乙個,這樣我們的就不會感到那麼累。

當然,在資料庫並沒有累這一說,wal機制意義就在於「削峰」,這也是我們在處理高併發場景下的乙個解決思路。

可能有人會很疑惑,同樣是操作磁碟,為什麼寫日誌比直接改資料會更加高效?

答案在於寫日誌是順序寫,直接改磁碟是隨機寫。所以同樣是寫,它們寫的速度有著天壤之別。這也是wal的另外乙個好處。

接下來我們就具體介紹一下wal中涉及到的2個主要的日誌redolog、binlog。從而了解修改語句在mysql的處理過程中的處理方式和一些技巧。

2、redolog

redo log我們也稱為重做日誌,我們上面所說到資料庫先寫日誌再寫磁碟的這個特點中的「日誌」,說的就是redolog。

redo log寫日誌是迴圈寫的,它有2個物件,writepos 和 checkpos。writepos 和 checkpos

資料每次寫入redo log,writepos就會往前移動,當writepos到達checkpos的時候,checkpos就會往後移動。

在這個移動的過程中(比如圖中pos 到 pos2的距離,圖中所表達的意思是check pos移動到check pos2的距離,不是說redo log有多個checkpos)所涉及的對mysql硬碟資料頁的更改全部實施到響應的頁中,這樣writepos才有新的空間繼續寫。

這個時候的資料庫的表現就是處理突然變低,如果你發現你的資料庫執行在某一時刻突然效能變低了,可以考慮一下是否是這種情況。

redo log的大小由2個引數控制:

innodb_log_files_in_group #redolog檔案的個數

innodb_log_file_size #每個redolog檔案的大小

redolog總大小=innodb_log_files_in_group*innodb_log_file_size

一般我們設定innodb_log_files_in_group的個數為4個,每個的大小為1個g。

在mysql中,除了redo log還有乙個也很重要的日誌——bin log,它與redo log相互配合,一塊來保證資料的一致性

3、binlog

binlog也成為二進位制日誌,它記錄了mysql中資料的更改,它一共有3種格式,分別為:

statement #binlog中記錄sql日誌。

rows #rows格式記錄每乙個行的每乙個欄位的具體改動

mixed #預設記錄sql, 由mysql判斷,可能會造成資料不一致的情況便會使用rows格式進行記錄。

在效能上statement>mixed>rows, 在資料一致性上rows>mixed>statement,很顯然資料的一致性是資料庫中的重中之重,所以大家很願意犧牲一點效能來換取資料的可靠性。

到這裡我們已經對bin log,redo log有了乙個雞蛋的了解,接下來我們再來看看,在mysql中redo log和bin log是如何相互配合一起工作的。

4、資料是如何保證不會丟失的

mysql中不管是redo log還是bin log,語句從執行到寫到磁碟的過程中,都是先要寫到cache(redolog稱之為buffer)中然後再寫到磁碟,換言之就是先寫記憶體再寫磁碟。

而寫到磁碟也分2種狀態,1是資料在硬碟的paga cache中,這個過程稱之為write,2是資料真正持久化到磁碟這個過程稱之為fsync。

資料寫cache很快,寫到硬碟的page cahe也快,真正慢且消耗io的地方再持久化的過程,也就是fsync。

記憶體空間劃分上,redolog buffer是所有事務共用的,binlog cache是每個執行緒分配乙個。可以通過binlog_cache_size來控制它的大小,如果事務的binlog日誌大小超出了binlog_cache_size的定義的大小,多出來的部分會存到硬碟中。

事務執行的過程中,更改(update、delete、insert)語句只要執行就會生成redolog buffer。

事務在執行的過程中,只有事務commit了binlog_cache中的資料才會被寫到硬碟上,這是為了保證事務的完整性。

硬碟空間劃分上,redolog只有乙個且所有事務共用,binlog也是乙個且所有事務共用。(注意:這裡的乙個是指乙個物件,實現上mysql可能會分成多個檔案去儲存)

我們先通過2張圖來了解2個日誌的從寫記憶體到寫硬碟的過程。

redolog寫入過程:redolog寫入過程

事務任何改變資料的操作都會被記錄到redolog buffer中,不管事務有沒有提交都會寫redolog,然後redolog buffer中的資料會寫到硬碟,也就是追加寫到硬碟的redo log檔案。

這裡有3種情況redolog buffer會寫到硬碟:redolog buffer是否超過innodb_log_buffer_size(redolog buffer的總大小)的一半。

事務是否提交

一秒一次自動寫

資料從記憶體寫到硬碟的過程中是否能到write或fsync由引數innodb_flush_log_at_trx_commit控制,它有三種可能取值:

0 :表示每次事務提交時都只是把 redo log 留在 redo log buffer 中 。

1 :表示每次事務提交時都將 redo log 直接持久化到磁碟。

2 :表示每次事務提交時都只是把 redo log 寫到 page cache。

一般這個引數設定為1

這裡有個特點就是由於事務提交就會寫硬碟,那麼寫硬碟的時候有可能會使還未提交的事務也可能會被寫進去redolog檔案中去。

下面是binlog 寫入過程:

事務執行,產生binlog cache,直到事務提交,binlog cache中的日誌資料會全部寫進硬碟binlog中,這個時候資料處於硬碟的page cache中。

是否fsync由引數 sync_binlog 控制,它的值也有3中可能的狀態:

0:表示每次提交事務都只 write,不 fsync。

1:表示每次提交事務都會執行 fsync。

n:表示每次提交事務都 write,但累積 n 個事務後才 fsync。

sync_binlog 這個引數一般設定為1,與上面 innodb_flush_log_at_trx_commit 設定為1一起被dba稱為"雙1模式"

在了解了它們的落盤過程後我們在來看看它們在事務提交後是如何配合來保護資料不會丟失的。

在事務提交後mysql是先寫redolog,再寫binlog。

這個過程再細分後的步驟為,先寫redolog這個時候redolog先處於乙個prepare狀態,然後mysql寫binlog,最後再讓redlog處於commit狀態。這個事務就算真正寫到磁碟上了。

為什麼需要這樣做?原因是2個日誌需要保持一致,並且奔潰恢復的邏輯也需要這一過程。如mysql異常重啟後,怎麼樣判斷事務有沒有生效?

mysql的處理方式是如果redo log處於prepare狀態,bin log處於commit狀態,且2個日誌中的資料完整,這個情況下的事務是有效的,否則事務就會被回滾。

這個過程稱之為兩階段提交。

用上面redolog和binlog的寫入過程組合起來的話就如下圖所示:

第一次redo log提交,資料處於prepare狀態,然後提交bin log,最後redolog再傳送commit表示,則代表整個事務被持久化到硬碟。

由圖可知,一次資料寫入的過程可能會有3次fsync,對應3三次io操作。

這樣看來,一次事務可能會照成3次fsync,你可能會覺得這樣弄得話mysql的效能不就會很爛?實際上,mysql做了優化,用了組提交機制來減少io的消耗。

mysql的具體做法是:每個事務在寫入log都會有乙個日誌邏輯序列號(log sequence number)稱之為lsn。

資料在fsync的過程中,lsn會隨著其他事務的提交而增長,日誌fsync完成的時候會提交最新的lsn。

其他lsn為小於最新提交的lsn的事務就就不需要fsync了,直接返fsync成功,原因就是已經被較前fsync的事務提交了。

舉個例子:事務1的lsn為10,它處於write階段準備呼叫fsync,在fsync的過程中事務2事務3也提交了等待去fsync,導致事務1攜帶的lsn增長為了100,那麼他fsync的時候順便會把事務2事務3的資料fsync。這個過程如下圖所示:

這裡mysql充分利用了io的等待時間來減少了io的消耗。

並且,mysql還做了優化,讓binlog的fsync在redolog的fsync之後,這樣redo log和binlog fsync都有一定的時間讓lsn增長,所以都能使用組提交的優化。

如果你想人為控制這個過程可以使用binlog_group_commit_sync_delay與binlog_group_commit_sync_no_delay_count引數來控制

5、總結

到這裡,redolog與binlog的介紹就結束了,讀完這篇文章,相信你應該知道。什麼是redolog

什麼是binlog

redolog和binlog是怎麼高效配合的。

日誌寫入hbase Hbase系列 寫流程

前言 讀寫流程是hbase中最重要也是最複雜的乙個過程,本文主要是介紹hbase的讀寫是乙個怎麼樣的過程 1 hbase寫入流程 1.1 lsm樹簡介 hbase是採用lsm log structured merge tree 架構,儲存引擎和b樹儲存引擎一樣,同樣支援增 刪 讀 改 順序掃瞄操作。...

mysql 寫binlog 大字段流程

當寫binlog大於8192既io cache 的大小時,不寫io cache 直接寫入檔案pagecache 當io cache 剩餘空間無法寫入當前binlog時,則先把io cache 裡的內容寫入直接寫入檔案pagecache 0 my b write info 0x2d9b248 840 ...

如何將syslogng的日誌寫入MySQL資料庫

在 使用syslog ng搭建日誌伺服器 中已經講了如何將syslog ng配置為中心日誌伺服器,下面介紹如何將syslogng的日誌寫入mysql資料庫,系統 gentoo 2007 1 修改 etc syslog ng syslog ng.conf,新增 source s remote dest...