mysql-innodb-事務
寫在最前
這是讀書筆記,Mysql,innodb系列一共3篇。
Mysql-innodb-B+索引
Mysql-innodb-鎖
Mysql-innodb-事務
ACID
A:原子性,要麼成功,要麼失敗
C:一緻性,事務将資料庫從一種狀态轉換為另一種穩定狀态,不違反限制條件
I:隔離性,多個事務互不影響
D:持久性
事務的隔離級别
隔離級别 說明
READ UNCOMMITTED 未送出讀,會造成髒讀,違反持久性D
READ COMMITTED 讀已送出資料, 會造成幻讀 違反一緻性C
REPEATABLE READ 可重複讀,預設隔離級别
SERIALIZABLE 不會使用mysql的mvcc機制,而是在每一個select請求下獲得讀鎖,在每一個update操作下嘗試獲得寫鎖
SELECT@@global.tx_isolation檢視全局事務隔離級别
事務的實作
Force Log at Commit機制
當事務送出時,必須先将該事務的所有日志寫入到日志檔案進行持久化,之後進行COMMIT操作完成。
日志寫入日志檔案時,日志緩沖先寫入檔案系統緩存,為了確定寫入磁盤,需要調用一次fsync操作。
由于fsync的效率取決于磁盤的性能,是以磁盤的性能決定了事務送出的性能,也就是資料庫的性能。
3種日志檔案
redolog
概念
實作事務的持久性。
InnoDB存儲引擎層産生,實體日志,記錄的是對頁的修改,innodb1.2版本後,最大512GB
一個事務多個日志記錄,每個事務内部是順序寫的。并發寫入多個事務的日志,不随事務送出順序寫入
兩部分:重做日志緩沖(redo log buffer)易失的;重做日志檔案(redo log file),持久的
log buffer重新整理政策
由innodb_flush_log_at_trx_commit控制
innodb_flush_log_at_trx_commit值 說明
0 送出時,不寫入日志檔案
1 預設值,送出時調用一次fsync操作
2 送出時寫日志檔案,不進行fsync操作
log buffer重新整理到磁盤的規則
事務送出時
log buffer已經有一半空間被使用
log checkpoint時
innodb恢複時如何使用redolog
checkpoint存儲了已經重新整理到磁盤頁上的LSN,是以僅需恢複checkpoint開始的日志部分
innodb,順序讀取,并行操作,提高性能
實體日志,幂等的,恢複快
LSN存儲了checkpoint的位置。
undolog
基本概念
存儲在undo段中,位于共享表空間,邏輯日志
支援mvcc,支援復原
undolog 會生産redo log
復原時,undo生産反向操作,insert對應delete,delete對應一條insert,update對應一個反向update
格式
類型 說明
insert undo log insert産生,事務本身可見,其他事務不可見,commit後直接删除
update undo log
delete,update産生,其他事務可見,commit後放入清單中,供purge操作
比insert undo log大
commit後
undo加入history list中,供後續purge操作
判斷undo頁 的使用空間是否小于3/4,是新的undo log 記錄到老的undo log後邊
binlog
MySQL資料庫的上層産生的,并且二進制日志不僅僅針對于InnoDB存儲引擎,
邏輯日志,記錄的是SQL語句
事務送出後一次性寫入
purge
purge是清理的delete和update之前行記錄的版本。
從history list中找undo log,然後再從undo page中找undo log,防止大量随機讀寫,提高性能
相關參數 :
innodb_purge_batch_size設定每次需要purge清理的undo page數量,innodb1.2以後預設為300
innodb_max_purge_lag用來控制history list的長度,預設值為0,不做任何限制
大于0,延後DML操作,對每行資料延緩:
delay=((length(history_list)- innodb_max_purge_lag)*10)-5
group commit
提高磁盤fsync的效率,一次重新整理多個事務日志檔案
綜述:5.7版本innodb開啟binlog的commit過程
注意:
THD是MySQL server層最核心的類
LSN:
日志序列号
重做日志寫入的總量
checkpoint的位置
頁的版本
原文位址
https://my.oschina.net/floor/blog/4296143