binlog,redo log的一致性分析

2021-10-05 03:09:40 字數 2094 閱讀 9110

mysql中binlog和redo log的一致性問題

binlog和redo log都是在事務提交階段記錄的。這時我們不禁會有一些疑問:

是先寫redo log 還是先寫binlog,是先寫binlog,還是先提交?

寫binlog和redo log的順序對於資料庫系統的永續性和主從複製會不會產生影響?

如果有影響,mysql又是怎麼做到binlog和redo log的一致性的呢?

帶著這些問題,我深入地研究了mysql中binlog和redo log的一致性問題。

針對這個疑問,我們可以做出兩個假設。

假設一:先寫redo log再寫binlog

想象一下,如果資料庫系統在寫完乙個事務的redo log時發生crash,而此時這個事務的binlog還沒有持久化。在資料庫恢復後,主庫會根據redo log中去完成此事務的重做,主庫中就有可這個事務的資料。但是,由於此事務並沒有產生binlog,即使主庫恢復後,關於此事務的資料修改也不會同步到從庫上,這樣就產生了主從不一致的錯誤。

假設二:先寫binlog再寫redo log

想象一下,如果資料庫系統在寫完乙個事務的binlog時發生crash,而此時這個事務的redo log還沒有持久化,或者說此事務的redo log還沒記錄完(至少沒有記錄commit log)。在資料庫恢復後,從庫會根據主庫中記錄的binlog去回放此事務的資料修改。但是,由於此事務並沒有產生完整提交的redo log,主庫在恢復後會回滾該事務,這樣也會產生主從不一致的錯誤。

通過上面的假設和分析,我們可以看出,不管是先寫redo log還是先寫binlog,都有可能會產生主從不一致的錯誤,那麼mysql又是怎麼做到binlog和redo log的一致性的呢?

mysql內部xa事務:

在mysql內部,在事務提交時利用兩階段提交(內部xa的兩階段提交)很好地解決了上面提到的binlog和redo log的一致性問題:

第一階段: innodb

prepare階段。此時sql已經成功執行,並生成事務id(xid)資訊及redo和undo的記憶體日誌。此階段innodb會寫事務的redo

log,但要注意的是,此時redo

log只是記錄了事務的所有操作日誌,並沒有記錄提交(commit)日誌,因此事務此時的狀態為prepare。此階段對binlog不會有任何操作。

第二階段:commit

階段,這個階段又分成兩個步驟。第一步寫binlog(先呼叫write()將binlog記憶體日誌資料寫入檔案系統快取,再呼叫fsync()將binlog檔案系統快取日誌資料永久寫入磁碟);第二步完成事務的提交(commit),此時在redo

log中記錄此事務的提交日誌(增加commit 標籤)。 可以看出,此過程中是先寫redo

log再寫binlog的。但需要注意的是,在第一階段並沒有記錄完整的redo

log(不包含事務的commit標籤),而是在第二階段記錄完binlog後再寫入redo log的commit

標籤。還要注意的是,在這個過程中是以第二階段中binlog的寫入與否作為事務是否成功提交的標誌。

通過上述mysql內部xa的兩階段提交就可以解決binlog和redo log的一致性問題。資料庫在上述任何階段crash,主從庫都不會產生不一致的錯誤。

此時的崩潰恢復過程如下:

如果資料庫在記錄此事務的binlog之前和過程中發生crash。資料庫在恢復後認為此事務並沒有成功提交,則會回滾此事務的操作。與此同時,因為在binlog中也沒有此事務的記錄,所以從庫也不會有此事務的資料修改。

如果資料庫在記錄此事務的binlog之後發生crash。此時,即使是redo log中還沒有記錄此事務的commit 標籤,資料庫在恢復後也會認為此事務提交成功(因為在上述兩階段過程中,binlog寫入成功就認為事務成功提交了)。它會掃瞄最後乙個binlog檔案,並提取其中的事務id(xid),innodb會將那些狀態為prepare的事務(redo log沒有記錄commit 標籤)的xid和binlog中提取的xid做比較,如果在binlog中存在,則提交該事務,否則回滾該事務。這也就是說,binlog中記錄的事務,在恢復時都會被認為是已提交事務,會在redo log中重新寫入commit標誌,並完成此事務的重做(主庫中有此事務的資料修改)。與此同時,因為在binlog中已經有了此事務的記錄,所有從庫也會有此事務的資料修改。

Denoise auto encoder的乙個理解

這幾天反覆的看denoise auto encoder的解釋,尤其是geometric interpretation。作者寫道,本來的資料假定是在乙個低緯度的流行結構上,加了噪音之後,這些噪音點就距離這個流行結構要有點遠,或者不在這個流行結構上了,那麼學習的過程就會去學習在這個本來的流行結構。個人認...

erlang lists keyfind的乙個小坑

key 2 2,findreuslt lists keyfind key,1,case findreuslt of find false not find end.這段 會報沒有匹配的錯誤 原因是 key 2 2 其實 key被賦值為1.0 摔,這個基礎概念都能忘記 lists keyfind 文件...

WM DRAWITEM,DrawItem的一些總結

1 當在mfc中要對某個控制項自繪時,就需要重寫drawitem或者ondrawitem函式,要實現重繪 首先要允許重繪 1 可以在控制項屬性中設定 網上很多,自己搜吧 2 在控制項類中實現,比如我實現了class cmybutton public cbutton自己的按鈕類,然後在cmybutto...