1. 程式人生 > 其它 >MySQL InnoDB事務講解

MySQL InnoDB事務講解

1. 資料庫事務的ACID特性:A(atomicity,原子性)、C(consistency,一致性)、I(isolation,隔離性)、D(durability,永續性)

2. 事務隔離級別:檢視事務隔離級別命令,show variables like '%isolation%';或select @@transaction_isolation;

  讀未提交(RU/read uncommitted):一個事務讀取到另一個事務未提交的資料,造成髒讀;

  讀已提交(RC/read committed):一個事務讀取到另一個事務已提交的資料,導致同一條記錄讀取兩次以上的結果不一致,造成不可重複讀;

  可重複讀(RR/repeatable):一個事務在讀取到資料後,如果其他事務修改了相同記錄的資料並提交,再次讀取的資料仍為第一次讀取到的記錄一樣;而對於insert或delete操作,會讀取到另一個事務提交後的資料,導致兩次讀取結果不一樣,這就是幻讀;

  序列化(serializable):所有事務序列執行,不會出現髒讀、不可重複讀、幻讀問題,但效能最差

3. 資料庫解決併發問題的兩種方案:LBCC(Lock Based Concurrency Control,基於鎖的併發控制)和MVCC(Multi Version Concurrency Control,多版本併發控制),其中LBCC效能低下,MySQL InnoDB採用的是MVCC,普通的select讀取資料不會加鎖,提高了資料庫併發處理能力,而MVCC只對RR和RC兩個事務隔離級別起作用。

4. InnoDB MVCC機制:資料操作過程中生成的多版本記錄行,會通過purge執行緒進行清理

  1)、對每行資料的修改操作都會生成一個副本記錄行,每個記錄行上都有隱藏的兩個欄位,事務ID和行的回滾指標;開始新事務時,都會將當前事務ID放到影響資料行記錄的事務ID欄位上,注意事務ID是遞增且不重複的,當查詢時,會用當前事務ID和每行記錄的事務ID進行比較;行的回滾指標則指向上一個版本記錄行。

  select:藉助readview和undo log,遍歷每個版本的記錄行找到要查詢的資料

   insert: 新插入一行,且儲存當前事務編號作為版本號

   delete:生成刪除行記錄,且將當前事務編號作為行刪除標識

   update:新插入一行,且儲存當前事務編號作為版本號,同時將當前事務編號儲存到原來行記錄作為刪除標識

  2)、undo log:InnoDB為了更好支援併發,多版本一致性讀(當前讀和快照讀)採用基於回滾段(副本記錄行)的方式。如果是Insert操作,會產生insert undo log,由於insert操作只對當前事務可見,其他事務不可見,所以insert undo log在事務提交後直接刪除,不需要purge操作;如果是delete和update操作,會產生update undo log,由於update undo log會用於後續的MVCC中,也就是其他事務可能會用到這些記錄,所以事務提交後不能立即刪除,而是放到undo log連結串列(多個副本記錄行)中,等待purge執行緒清理。

  3)、read view:包含了當前系統中所有活躍的讀寫事務ID,放在一個名為m_ids的列表中。在RR或RC隔離級別下,用來判斷undo log版本鏈中的哪個版本是當前事務可見的。RR隔離級別下,同一個事務中,只在第一次查詢時生成read view;RC隔離級別下,同一個事務中,會在每次查詢時生成最新的readview。判斷版本可見步驟如下:

    - 被訪問版本的事務ID如果小於m_ids列表中最小的事務ID,表明該版本的事務已經在生成readview前提交,所以該版本可以被當前事務訪問;

    - 被訪問版本的事務ID如果大於m_ids列表中最大的事務ID,表明該版本的事務在生成readview後才生成,所以該版本不可以被當前事務訪問;

    - 被訪問版本的事務ID如果在m_ids列表中最大值和最小值之間,那就要判斷該版本的事務ID是否在m_ids列表中,如果在,則表示事務還是活躍的,不可被訪問,如果不在,表示事務已經提交,可以被訪問。

5. MVCC下的讀操作分為快照讀和當前讀

  1)、快照讀(一致性非鎖定讀):如簡單的select(非加鎖的select)操作,讀取的是歷史版本,不會對記錄加鎖;

  2)、當前讀:如insert、update、delete操作,需要加鎖,屬於當前讀,每次操作時會對行加鎖,讀取當前版本資料,除insert、update、delete外還有select for update等加X鎖(排它鎖)操作語句

6. MVCC下事務回滾操作:就是將對應事務ID的所有版本undo log記錄刪除,就類似連結串列中刪除節點。

7. MVCC下啟動事務,資料寫入時,會先將undo log寫入redo log,如果undo log沒有成功寫入redo log,表示事務沒有提交且沒有undo log記錄,系統奔潰,當系統恢復時無需操作;如果undo log寫入redo log成功且落盤,而buffer pool中髒頁落盤失敗,也就是沒有成功落盤到redo log檔案,沒有提交事務,系統奔潰,當系統恢復時,需要根據redo log將未提交的事務進行回滾。