MYSQL-->InnoDB引擎底層原理( 三 )


  1. 客戶端A對innoDB存儲引擎的表進行增刪改事務操作
  2. 先訪問內存結構中的緩沖池,如果增刪改數據在其中不存在,
    就會從磁盤中讀取數據再刷新到緩沖池(這個數據必須是唯一索引 , 否則會先進入到更改緩沖區)
  3. 在緩沖池中變成臟頁,并記錄在redolog buffer中,后直接刷新到磁盤中
  4. 如果臟頁在一段時間后刷新到磁盤中報錯了,可以通過redo log進行恢復 。

MYSQL-->InnoDB引擎底層原理

文章插圖
使用redo log直接刷新到磁盤結構的好處
事務一般是一組多條的增刪改查操作 , 故事務提交的時候會隨機的操作多條的記錄 。
這些記錄會操作多條數據頁,這樣會產生大量的隨機磁盤IO
而直接將redo log文件異步刷新到磁盤io中,由于它是日志文件,日志文件都是追加的,此時是順序磁盤IO , 這樣會節約大量的磁盤IO
這種機制叫WAL(Write-Ahead Logging)(先寫日志)
然后過一段時間臟頁日志才會刷新到磁盤中 。
故倆份日志是循環清理的
事務的redo log日志是為了解決臟頁刷新到磁盤出錯時進行數據的恢復使用的,用來保證數據的持久性
undo logundo log日志是用來保證事務的原子性的 。
undo log也叫回滾日志,用于記錄數據被修改前的信息,作用為:提供回滾和MVCC
redo log記錄的是物理日志!
undo log記錄的是邏輯日志,可以認為當執行delete 一條記錄時,undo log中會記錄一條對應的insert記錄,反之同理 。
當執行rollback時,就可以從undo log中的邏輯記錄讀取到對應內容,從而進行回滾 。
Undo log銷毀
undo log在事務執行時產生 , 事務提交時,并不會馬上刪除undo log,因為這些日志可能還用于MVCC
Undo log存儲
undo log采用,段的方式進行管理和記錄,存放在前面介紹的rollback segment回滾中,內部包含了1024個undo log segment
這個段是邏輯存儲結構的段哦~
MVCC(多版本并發控制)(高頻面試題)MVCC的幾個基本概念當前讀我們讀取的是記錄的最新版本 , 讀取時還要保證其他并發事務不能修改當前記錄,會對讀取的記錄進行加鎖,
對于我們日常的操作,如:select...lock in share mode(共享鎖),select...for update,update , insert,delete(排他鎖)
都是一種當前讀 。
案例:
在RR的隔離級別下
  1. 事務A進行查詢操作,事務B進行更新操作并提交事務
  2. 事務A使用當前讀select...此時讀取的是事務B更新之前的數據(原因是隔離級別)
  3. 事務A使用select...lock in share mode(當前讀)此時讀取的是事務B更新之后的數據 。
快照讀簡單的select(不加鎖)就是快照讀,讀取的是記錄數據的可見版本,可能是歷史數據,不加鎖是非阻塞讀 。
  1. Read Committed隔離級別:每次select都生成一個快照讀
  2. Repeatable Read隔離級別:開啟事務后第一個select語句才是快照讀的地方(后續查的就是這個快照數據)
  3. Serializable隔離級別:快照讀會退化為當前讀
MVCC介紹全稱Multi-Version Concurrency Control 多版本并發控制 。
指的是維護一個數據的多個版本,使得讀寫操作沒有沖突 。
快照讀為MYSQL實現MVCC提供了一個非阻塞讀功能,MVCC的具體實現,還需要依賴,數據庫的三個隱藏字段、
undo log日志、readView
MVCC-實現原理記錄中的隱藏字段當我們創建了表除了自己本身創建的字段,innoDB引擎會自動給我們創建三個字段
分別是:
  1. DB_TRX_ID
  2. DB_ROLL_PTR
  3. DB_ROW_ID
隱藏字段含義DB_TRX_ID最近修改事務ID,記錄插入這條記錄或者最后一次修改該記錄的ID(事務id)DB_ROLL_PTR回滾指針,指向這條記錄的上一個版本,用于配合undo log指向上一個版本DB_ROW_ID隱藏主鍵,如果表結構沒有指定主鍵,就會生成該隱藏字段
可以查看表空間文件內容來查看隱藏字段信息
事務id是自增的!
在MYSQL中提供了一個命令來查看表空間文件的記錄信息
ibd2sdi xxx.ibdundo log版本鏈回滾日志,在insert、update、delete的時候產生的便于數據回滾的日志
當insert的時候,產生的undo log日志只在回滾時需要,在事務提交后 , 可被立即刪除 。

推薦閱讀