Mysql InnoDB如何保證事務

2021-10-12 12:31:00 字數 2571 閱讀 6276

mysql儲存引擎innodb支援事務操作,即支援原子性、一致性、隔離性、永續性(acid)特性。下面介紹一下innodb是怎樣做到這幾個特性的。

原子性:原子性是指事務中的語句要麼全部執行成功、要麼全部不執行,原子性是通過undo log實現的。

永續性:永續性是指事務一旦提交,它對資料庫的改變就應該是永久性的,不會因為宕機等原因而丟失資料,永續性是通過redo log實現的。

一致性:事務前後的資料必須保持一致性。一致性是通過redo log+undo log實現的。

隔離性:隔離性是指,事務內部的操作與其他事務是隔離的,併發執行的各個事務之間不能互相干擾。隔離性是通過鎖+mvcc來控制的。

redo log保障永續性能

innodb為了保證高速寫入,不會直接寫入庫中,而是會寫入redo log這種日誌系統。redo log 分為兩部分:一部分是記憶體中的重做日誌緩衝(redo log buffer),是易丟失的;二部分是重做日誌檔案(redo log file),是持久的。innodb通過force log at commit機制來實現永續性,當commit時,必須先將事務的所有日誌寫到重做日誌檔案進行持久化,待commit操作完成才算完成。所以事務提交以後,資料都寫入了redo log中,即使發生宕機的故障,在機器恢復後,能夠從redo log中恢復之前寫入的資料而不丟失。

undo log保障原子性

為了滿足事務的原子性,在操作任何資料之前,首先將資料備份到乙個地方(這個儲存資料備份的地方稱為undo log),然後進行資料的修改。如果出現了錯誤或者使用者執行了 rollback語句,系統可以利用undo log中的備份將資料恢復到事務開始之前的狀態。此時資料庫會生成乙個和之前的語句相反的sql,例如之前是insert 語句,回滾時會執行一條delete語句來刪除之前插入的資料,從而保障原子效能。

redo log+undo log保障一致性

如果事務中的sql全部成功執行,需要redo log來保障;如果執行失敗,需要回滾,這需要undo log來保障。

鎖+mvcc來保障隔離性

sql標準中定義了四種隔離級別,並規定了每種隔離級別下上述幾個問題是否存在。一般來說,隔離級別越低,系統開銷越低,可支援的併發越高,但隔離性也越差。隔離級別與讀問題的關係如下:

隔離性要求同一時刻只能有乙個事務對資料進行寫操作,innodb通過鎖機制來保證這一點。

鎖機制的基本原理可以概括為:事務在修改資料之前,需要先獲得相應的鎖;獲得鎖之後,事務便可以修改資料;該事務操作期間,這部分資料是鎖定的,其他事務如果需要修改資料,需要等待當前事務提交或回滾後釋放鎖。

為了提高事務的併發性,innodb引入了mvcc(多版本併發控制),在同一時刻,不同的事務讀取到的資料可能是不同的(即多版本)——在t5時刻,事務a和事務c可以讀取到不同版本的資料。

mvcc最大的優點是讀不加鎖,因此讀寫不衝突,併發效能好。innodb實現mvcc,多個版本的資料可以共存,主要基於以下技術及資料結構:

1)隱藏列:innodb中每行資料都有隱藏列,隱藏列中包含了本行資料的事務id、指向undo log的指標等。

2)基於undo log的版本鏈:前面說到每行資料的隱藏列中包含了指向undo log的指標,而每條undo log也會指向更早版本的undo log,從而形成一條版本鏈。

3)readview:通過隱藏列和版本鏈,mysql可以將資料恢復到指定版本;但是具體要恢復到哪個版本,則需要根據readview來確定。所謂readview,是指事務(記做事務a)在某一時刻給整個事務系統(trx_sys)打快照,之後再進行讀操作時,會將讀取到的資料中的事務id與trx_sys快照比較,從而判斷資料對該readview是否可見,即對事務a是否可見。

trx_sys中的主要內容,以及判斷可見性的方法如下:

low_limit_id:表示生成readview時系統中應該分配給下乙個事務的id。如果資料的事務id大於等於low_limit_id,則對該readview不可見。

up_limit_id:表示生成readview時當前系統中活躍的讀寫事務中最小的事務id。如果資料的事務id小於up_limit_id,則對該readview可見。

rw_trx_ids:表示生成readview時當前系統中活躍的讀寫事務的事務id列表。如果資料的事務id在low_limit_id和up_limit_id之間,則需要判斷事務id是否在rw_trx_ids中:如果在,說明生成readview時事務仍在活躍中,因此資料對readview不可見;如果不在,說明生成readview時事務已經提交了,因此資料對readview可見。

總結

mysql的儲存引擎innodb通過redo log、undo log、鎖、mvcc來支援事務操作,即滿足了資料操作的正確,又兼顧了高效能。

質量如何保證

讀書主要是為了緩解非利益既得者的焦慮,有人懂嗎?之前對於質量的把控,主要是從 層面,從實現機制 業務邏輯 編碼規範等方面去用功,直到最近才忽然想到這可能是個謬論,只關注了乙個孤立的體系,說是閉門造車也不為過。傳統的生產製造領域早就有qc和qa,而對於像我們這種經歷的網際網路創業人員團隊,對於這一塊是...

MySQL InnoDB 如何避免髒讀

事務隔離級別 repeatable read 能避免髒讀 rr隔離級別下的隱患 幻讀,另外一篇文章的重點 必須提前了解 當前讀和快照讀的區別 mysql 的 innodb 會維護一系列不暴露給使用者的隱藏字段,其中有3個用於實現快照讀 非阻塞讀 undo log 實現了快照讀的資料結構。read v...

MySQL Innodb如何找出阻塞事務之定位問題

查詢 正在執行的事務 select from information schema.innodb trx 檢視正在鎖的事務 select from information schema.innodb locks 檢視等待鎖的事務 select from information schema.inno...