MySQL——binlog,redo log
一、什么是binlog、redo log
binlog屬于邏輯日志,是邏輯操作。innodb redo屬于物理日志,是物理變更。邏輯日志有個缺點是難以并行,而物理日志可以比較好的并行操作。
二、binlog
即二進制日志,它記錄了數據庫上的所有改變,并以二進制的形式保存在磁盤中;它可以用來查看數據庫的變更歷史、數據庫增量備份和恢復、Mysql的復制(主從數據庫的復制)。語句以“事件”的形式保存,它描述數據更改。
因為有了數據更新的binlog,所以可以用于實時備份,與master/slave復制。高可用與數據恢復。
1.恢復使能夠最大可能地更新數據庫,因為二進制日志包含備份后進行的所有更新。
2.在主復制服務器上記錄所有將發送給從服務器的語句。
2.1 binlog格式
binlog有三種格式:Statement、Row以及Mixed。從安全性來看,ROW(最安全)、MIXED(不推薦)、STATEMENT(不推薦)。
–基于SQL語句的復制(statement-based replication,SBR),
–基于行的復制(row-based replication,RBR),
–混合模式復制(mixed-based replication,MBR)。
2.1.1 Statement
每一條會修改數據的sql都會記錄在binlog中。在5.6.24中默認格式。
優點:不需要記錄每一行的變化,減少了binlog日志量,節約了IO,提高性能。
缺點:由于記錄的只是執行語句,為了這些語句能在slave上正確運行,因此還必須記錄每條語句在執行的時候的一些相關信息,以保證所有語句能在slave得到和在master端執行時候相同 的結果。另外mysql 的復制,像一些特定函數功能,slave可與master上要保持一致,會有很多相關問題。
ps:相比row能節約多少性能與日志量,這個取決于應用的SQL情況,正常同一條記錄修改或者插入row格式所產生的日志量還小于Statement產生的日志量,但是考慮到如果帶條件的update操作,以及整表刪除,alter表等操作,ROW格式會產生大量日志,因此在考慮是否使用ROW格式日志時應該跟據應用的實際情況,其所產生的日志量會增加多少,以及帶來的IO性能問題。
2.1.2 Row
5.1.5版本的MySQL才開始支持row level的復制,它不記錄sql語句上下文相關信息,僅保存哪條記錄被修改。
優點: binlog中可以不記錄執行的sql語句的上下文相關的信息,僅需要記錄那一條記錄被修改成什么了。所以row level的日志內容會非常清楚的記錄下每一行數據修改的細節。而且不會出現某些特定情況下的存儲過程,或function,以及trigger的調用和觸發無法被正確復制的問題.
缺點:所有的執行的語句當記錄到日志中的時候,都將以每行記錄的修改來記錄,這樣可能會產生大量的日志內容。
ps:新版本的MySQL中對row level模式也被做了優化,并不是所有的修改都會以row level來記錄,像遇到表結構變更的時候就會以statement模式來記錄,如果sql語句確實就是update或者delete等修改數據的語句,那么還是會記錄所有行的變更。
2.1.3 Mixed
從5.1.8版本開始,MySQL提供了Mixed格式,實際上就是Statement與Row的結合。
在Mixed模式下,一般的語句修改使用statment格式保存binlog,如一些函數,statement無法完成主從復制的操作,則采用row格式保存binlog,MySQL會根據執行的每一條具體的sql語句來區分對待記錄的日志形式,也就是在Statement和Row之間選擇一種。
2.1.4 查看與配置binlog格式
查看binlog_format
show variables like 'binlog_format'三、Undo Log
Undo Log是為了實現事務的原子性,在MySQL數據庫InnoDB存儲引擎中,還用UndoLog來實現多版本并發控制(簡稱:MVCC)。
-事務的原子性(Atomicity)
事務中的所有操作,要么全部完成,要么不做任何操作,不能只做部分操作。如果在執行的過程中發了錯誤,要回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過。
-原理
Undo Log的原理很簡單,為了滿足事務的原子性,在操作任何數據之前,首先將數據備份到一個地方(這個存儲數據備份的地方稱為UndoLog)。
然后進行數據的修改。如果出現了錯誤或者用戶執行了ROLLBACK語句,系統可以利用UndoLog中的備份將數據恢復到事務開始之前的狀態。
除了可以保證事務的原子性,Undo Log也可以用來輔助完成事務的持久化。
-事務的持久性(Durability)
事務一旦完成,該事務對數據庫所做的所有修改都會持久的保存到數據庫中。為了保證持久性,數據庫系統會將修改后的數據完全的記錄到持久的存儲上。
-用Undo Log
實現原子性和持久化的事務的簡化過程
假設有A、B兩個數據,值分別為1,2。
A.事務開始.
B.記錄A=1到undolog.
C.修改A=3.
D.記錄B=2到undolog.
E.修改B=4.
F.將undolog寫到磁盤。
G.將數據寫到磁盤。
H.事務提交
這里有一個隱含的前提條件:‘數據都是先讀到內存中,然后修改內存中的數據,最后將數據寫回磁盤’。
之所以能同時保證原子性和持久化,是因為以下特點:
A.更新數據前記錄Undo log。
B.為了保證持久性,必須將數據在事務提交前寫到磁盤。只要事務成功提交,數據必然已經持久化。
C.Undo log
必須先于數據持久化到磁盤。如果在G,H之間系統崩潰,undo log是完整的,可以用來回滾事務。
D.如果在A-F之間系統崩潰,因為數據沒有持久化到磁盤。所以磁盤上的數據還是保持在事務開始前的狀態。
缺陷:每個事務提交前將數據和Undo Log寫入磁盤,這樣會導致大量的磁盤IO,因此性能很低。
如果能夠將數據緩存一段時間,就能減少IO提高性能。但是這樣就會喪失事務的持久性。因此引入了另外一種機制來實現持久化,即Redo log
四、Redo log
記錄的是新數據的備份。在事務提交前,只要將Redo Log持久化即可,不需要將數據持久化。當系統崩潰時,雖然數據沒有持久化,
但是RedoLog已經持久化。系統可以根據RedoLog的內容,將所有數據恢復到最新的狀態。
InnoDB有buffer pool(簡稱bp)。bp是數據庫頁面的緩存,對InnoDB的任何修改操作都會首先在bp的page上進行,然后這樣的頁面將被標記為dirty并被放到專門的flush list上,后續將由master thread或專門的刷臟線程階段性的將這些頁面寫入磁盤(disk or ssd)。這樣的好處是避免每次寫操作都操作磁盤導致大量的隨機IO,階段性的刷臟可以將多次對頁面的修改merge成一次IO操作,同時異步寫入也降低了訪問的時延。然而,如果在dirty page還未刷入磁盤時,server非正常關閉,這些修改操作將會丟失,如果寫入操作正在進行,甚至會由于損壞數據文件導致數據庫不可用。為了避免上述問題的發生,Innodb將所有對頁面的修改操作寫入一個專門的文件,并在數據庫啟動時從此文件進行恢復操作,這個文件就是redo log file。這樣的技術推遲了bp頁面的刷新,從而提升了數據庫的吞吐,有效的降低了訪問時延。帶來的問題是額外的寫redo log操作的開銷(順序IO,當然很快),以及數據庫啟動時恢復操作所需的時間。
總結
以上是生活随笔為你收集整理的MySQL——binlog,redo log的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL集群搭建——主备模式
- 下一篇: 小米助手怎么用?