redo log
redo log是基于磁盤資料結構記錄的日志,用于在db崩潰時恢複由未完成的事務寫入的正确資料。在正常操作期間,redo log會對SQL語句或低級API調用産生的更改表資料的請求進行編碼。在意外關閉之前沒有完成資料檔案更新的修改将在初始化期間和連接配接被接受之前自動重放。關于redo log在崩潰恢複中的作用,請參見“InnoDB恢複”章節14.19.2 Section 14.19.2, “InnoDB Recovery”
預設redo log在磁盤上由兩個檔案表示 ib_logfile0 and ib_logfile1。MySQL以循環的方式寫redo log檔案。redo log中的資料根據受影響的記錄進行編碼;此資料統稱為重做資料。通過redo log的資料通道由不斷增加的LSN(log sequence number)值表示。
undo log
undo log撤消日志是與單個讀寫事務關聯的撤消日志記錄的集合,一個undo log包含怎樣撤銷一個事務對聚簇索引(主鍵索引)記錄最近的變更資訊。如果另一個事務需要一緻性讀操作檢視原始資料,從undo log記錄中檢索未發生變更的資料傳回(事務未送出前)。Undo日志存在于Undo日志段中,Undo日志段包含在復原段中。復原段位于system表空間、undo表空間和臨時表空間中。
位于臨時表空間中的Undo logs用于使用者定義的臨時表資料變更的事務。這些undo logs不需要redo-logged,因為他們不需要崩潰恢複。他們僅用于服務運作時的rollback。這類undo log避免了redo日志I/O提高了性能。
InnoDB支援最大128的復原段,其中32個被配置設定給臨時表空間。這樣就剩下96個復原段可以配置設定給修改正常表中的資料的事務。The
innodb_rollback_segments
參數定義InnoDB使用復原段的數量。
一個復原段支援的事務數依賴于復原段中undo slot的數量與每個事務需要的undo log數量。
根據InnoDB頁面的大小,復原段中的undo槽的數量是不同的。
InnoDB Page Size | Number of Undo Slots in a Rollback Segment (InnoDB Page Size / 16) |
---|---|
| |
| |
| |
| |
| |
一個事務被配置設定的最大4個undo log,每一個對應以下操作類型:
-
操作在使用者定義的表INSERT
-
andUPDATE
操作在使用者定義的表DELETE
-
操作在使用者定義的臨時表INSERT
-
andUPDATE
操作在使用者定義的臨時表DELETE
Undo log被按需配置設定。例如,一個事務執行
INSERT
,
UPDATE
, and
DELETE
操作正常表與臨時表需要4個undo log全部配置設定。一個事務僅執行
INSERT
操作正常表需要一個undo log。正常表執行操作的事務由已配置設定的系統表空間或undo表空間的復原段配置設定undo log。臨時表執行操作的事務由已配置設定的臨時表空間的復原段配置設定undo log。
配置設定給事務的undo log在事務期間保持與事務綁定。例如,配置設定給正常表
INSERT
操作事務的undo log,用于該事務正常表上執行的所有
INSERT
操作。
考慮到上述因素,可以使用以下公式來估算InnoDB能夠支援的并發讀寫事務的數量。
- 如果每個事務執行一個
或者 (一個INSERT
或者UPDATE
)操作,DELETE
能夠支援的并發讀寫事務數量為:InnoDB
(innodb_page_size / 16) * (innodb_rollback_segments - 32)
- 如果每個事務執行一個
與 (一個INSERT
或者UPDATE
)操作,DELETE
能夠支援的并發讀寫事務數量為:InnoDB
(innodb_page_size / 16 / 2) * (innodb_rollback_segments - 32)
- 如果在臨時表上操作的每個事務執行一個
,INSERT
能夠支援的并發讀寫事務數量為:InnoDB
(innodb_page_size / 16) * 32
- 如果在臨時表上操作的每個事務執行一個
與 (一個INSERT
或UPDATE
),DELETE
能夠支援的并發讀寫事務數量為:InnoDB
事務四大特性
ACID
atomicity, consistency, isolation, and durability首字母簡寫。這些屬性在資料庫系統中都是理想的,并且都與事務的概念密切相關。InnoDB的事務特性遵循了ACID原則。
A:事務是可送出或復原的原子工作單元。當一個事務産生多個DB變更,要麼所有變更全部成功在事務送出時,要麼所有變更全部撤銷在事務復原時。
C:在事務每次送出或復原後以及事務進行時,資料庫始終保持一緻性狀态。如果相關資料變更橫跨多張表,查詢看到的要麼全部是舊值,要麼全部是新值,不會是混合的新舊值
I:所有進行中的事務彼此之間是互相保護(隔離的);他們不能相關幹涉或者看到彼此未送出的資料。這種隔離是通過鎖定機制實作的。有經驗的使用者可以調整隔離級别,在確定事務确實不會互相幹擾的情況下,減少保護以提高性能和并發性。
D:事務的結果是持久性的;一旦送出操作成功,由事務産生的變更不會發生電源故障,系統崩潰,競态條件,或許多非資料庫應用程式容易受到的其他潛在危險。持久性通常涉及到對磁盤存儲的寫入,并具有一定的備援,以防止在寫操作期間斷電或軟體崩潰。(在InnoDB中,doublewrite緩沖區有助于提高持久性。)
總結
redo log與binlog差別
- redo log基于磁盤實體資料結構存儲,binlog為邏輯日志結構(即使row模式也是記錄行變更的資料值)
- redo log用于資料持久化(處理緩存與磁盤一緻性問題,可複用),binlog用于主從複制(處理磁盤與磁盤一緻性問題,不可複用,append only)
- redo log可以合并送出以降低IO成本(Group Commit for Redo Log Flushing)
- redo log是面向innoDB引擎,binlog面向DB(包含所有引擎表均會記錄binlog日志)
mysql事務實作原理
原子性:基于undo log實作,undo log可以根據LSN進行撤銷操作。要麼全部成功,要麼全部撤銷
一緻性:個人了解遵循了AID原則的資料庫一定是具備一緻性的
隔離性:基于資料庫排它鎖,共享鎖機制實作,MVCC(undo log+read view)多版本并發控制機制可以實作無鎖情況下避免髒讀/不可重複讀/幻讀,但是不能解決更新丢失。
持久性:基于redo log + undo log實作,doublewrite緩存區即:redo log buffer,undo log buffer
注:DIO模式不經過linux核心緩存
參考
https://dev.mysql.com/doc/refman/5.7/en/innodb-redo-log.html
https://dev.mysql.com/doc/refman/5.7/en/innodb-undo-logs.html
https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_consistent_read