1、redo log基本概念
redo log的相關概念這里就不再過多闡述,網上有非常多的好的資料,可以看下縹緲大神的文章:https://www.cnblogs.com/cuisi/p/6525077.html,個人感覺介紹的非常詳細。
?
2、數據更改過程簡述
MySQL 在更新數據的時候,都是將數據先從磁盤拉到 buffer pool 中,在buffer pool中修改完成后再寫到磁盤中,也就是說MySQL中數據的更改都是要經過buffer pool的。
回到這個更新數據的過程中來看:當數據在buffer pool中更改完成的這一刻,更新后的數據是“最新”的,因為此時磁盤中的數據還是更改前的“舊數據”,而我們都是將磁盤中已經持久化的數據作為“標準數據”,因此此時 buffer pool 中的“最新”數據也常人們被稱為“臟數據(dirty data)”。
比如將 update 一百行記錄作為一個事務,在這個事務執行過程中會將更新后的數據先寫入redo log buffer,redo log buffer 再將數據刷入(請注意刷入這個用語,而非寫入,后面會詳細介紹)redo log中(這點和 binlog 不同,binlog 是在事務 commit 后一次性寫入,而 redo log 在事務執行過程中就會寫入)。
?
3、redo log刷新過程
首先需要明白兩個概念:
fsync:傳統的unix系統在內核中都設有緩沖區,并且大多數的I/O都會通過緩沖進行。當將數據寫入文件時,內核通常先將該數據復制到其中一個緩沖區中,如果該緩沖區尚未寫滿,則并不將其排入輸出隊列,而是等待其寫滿或者當內核需要重用該緩沖區以便存放其他磁盤塊數據時,再將該緩沖排入輸出隊列,然后待其到達隊首時,才進行實際的 I/O 操作。這種輸出方式被成為延遲寫。
unix提供了sync、fsync、fdatasync三個函數,sync只是將所有修改過的塊放入寫隊列,不管它是否寫磁盤結束就返回;fsync會等待寫磁盤結束才會返回。
O_DIRECT選項:O_DIRECT選項是Linux文件寫入中的一個選項,開啟了這個選項以后,數據就可以跳過系統層的緩存,直接寫入磁盤。
redo log并沒有打開O_DIRECT選項,所以redo log buffer只是先刷入redo log file,此時刷入的數據并沒有落到磁盤上,而是放在文件系統的緩存中。之后為了確保redo log寫入磁盤,就通過fsync操作將數據寫入磁盤。(redo log buffer到redo log file只是“刷入”的過程,這個時候并沒有寫入磁盤,而是寫入了OS層的文件系統緩存。)
4、重要參數
innodb_flush_log_at_trx_commit:用來控制redo log刷新到磁盤的策略。
默認值是1,表示每次事務提交的時候都調用fsync來寫入到磁盤;
0表示事務在執行過程中,日志一直放在redo log buffer中,但是在事務commit的時候,不寫入redo log file,而是通過master線程每秒操作一次,從redo log buffer寫入到redo log file中。
2表示事務提交時將redo log buffer刷入redo log file,也即刷入系統文件緩存中,不進行fsync操作,由系統來進行fsync操作。此時如果數據庫層宕機,則不會丟失redo log,但是如果服務器宕機,這個時候文件系統中的緩存還沒有fsync到磁盤文件中,這個時候就會丟失這一部分數據。
?