MySQL 中的事務及其實現原理

2021-10-04 03:05:40 字數 2372 閱讀 7165

說到資料庫,那就一定會聊到事務,事務也是面試中常問的問題,我們先來乙個面試場景:

面試官:

"事務的四大特性是什麼?"

我:"acid,即原子性(atomicity)、隔離性(isolation)、永續性(durability)、一致性(consistency)!"

面試官:

"在 mysql 資料庫的 innodb 引擎是怎麼實現這四大特性的?"

我:"這個...這個....,還真沒有了解過哎"

面試官:

"那我們就先這個吧,先回去吧,我們會通知你的~"

資料庫的事務有四大特性:原子性、隔離性、永久性、一致性,下面將介紹這四大特性的定義和在 innodb 引擎中是怎麼實現的。

一次操作是不可分割的,要麼全部成功,要麼全部失敗。比如我們的轉賬操作,不允許出款方成功,收款方失敗這種情況,要麼都成功,要麼多失敗,不可能出現中間狀態。

innodb 引擎使用 undo log(歸滾日誌)來保證原子性操作,你對資料庫的每一條資料的改動(insert、delete、update)都會被記錄到 undo log 中,比如以下這些操作:

當事務執行失敗或者呼叫了 rollback 方法時,就會觸發回滾事件,利用 undo log 中記錄將資料回滾到修改之前的樣子。

多個事務併發執行的時候,事務內部的操作與其他事務是隔離的,併發執行的各個事務之間不能互相干擾。

隔離性可能會引入髒讀(dirty read)、不可重複讀(non-repeatable read)、幻讀(phantom read)等問題,為了解決這些問題就引入了「隔離級別」的概念。

sql 標準的事務隔離級別包括:讀未提交(read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和序列化(serializable)

sql標準中規定,針對不同的隔離級別,併發事務可以發生不同嚴重程度的問題,具體情況如下:

隔離級別

髒讀不可重複讀

幻讀讀未提交可能

可能可能

讀提交不可能

可能可能

可重複讀不可能

不可能可能

序列化不可能

不可能不可能

上面就是幾種隔離級別可能出現的併發問題,但是有必要說一下,你隔離得越嚴實,效率就會越低。

innodb 引擎是如何保證隔離性的?利用鎖和 mvcc 機制。這裡簡單的介紹一下 mvcc 機制,也叫多版本併發控制,在使用 read committd、repeatable read 這兩種隔離級別的事務下,每條記錄在更新的時候都會同時記錄一條回滾操作,就會形成乙個版本鏈,在執行普通的 select 操作時訪問記錄的版本鏈的過程,這樣子可以使不同事務的讀-寫、寫-讀操作併發執行,從而提公升系統效能。

事務一旦提交,它對資料庫的改變就應該是永久性的。接下來的其他操作或故障不應該對其有任何影響。

要保證永續性很簡單,就是每次事務提交的時候,都將資料刷磁碟上,這樣一定保證了安全性,但是要知道如果每次事務提交都將資料寫入到磁碟的話,頻繁的 io 操作,成本太高,資料庫的效能極低,所以這種方式不可取。

innodb 引擎是怎麼解決的?innodb 引擎引入了乙個中間層來解決這個永續性的問題,我們把這個叫做 redo log(歸檔日子)

為什麼要引入 redo log?redo log 可以保證持久化又可以保證資料庫的效能,相比於直接刷盤,redo log 有以下兩個優勢:

innodb 引擎是怎麼做的?當有一條記錄需要更新的時候,innodb 引擎就會先把記錄寫到 redo log 裡面,並更新記憶體,這個時候更新就算完成了。當資料庫宕機重啟的時候,會將 redo log 中的內容恢復到資料庫中,再根據 undo log和 binlog 內容決定回滾資料還是提交資料。

一致性簡單一點說就是資料執行前後都要處於一種合法的狀態,比如身份證號不能重複,性別只能是男或者女,高考的分數只能在0~750之間,紅綠燈只有3種顏色,房價不能為負的等等, 只有符合這些約束的資料才是有效的,比如有個小孩兒跟你說他高考考了1000分,你一聽就知道他胡扯呢。資料庫世界只是現實世界的乙個對映,現實世界中存在的約束當然也要在資料庫世界中有所體現。如果資料庫中的資料全部符合現實世界中的約束(all defined rules),我們說這些資料就是一致的,或者說符合一致性的。

要保證資料庫的資料一致性,要在以下兩個方面做努力:

mysql索引及其實現原理筆記

1 mysql索引的型別 mysql主要有以下幾種索引型別 fulltext,hash,btree,rtree。hash 只能用於等值查詢,不能用於範圍查詢。btree,rtree 可用於等值查詢 範圍查詢,btree為mysql的預設索引型別。2 索引種類 普通索引 唯一索引 主鍵索引 組合索引 ...

c 中多型及其實現原理

有繼承 有虛函式 virtual 重寫 有父類指標 引用 指向子類物件。在基類中使用virtual定義虛函式,告訴編譯器這個函式要支援多型 而不是根據指標型別判斷如何呼叫 而是要根據引用或指標所繫結的物件的真實型別。一旦某個函式被宣告為虛函式,則在所有派生類中它都是虛函式 不管有沒有virtual ...

跳表的原理及其實現

作用 目的 跳表作為一種資料結構通常用於取代平衡樹。起因平衡樹可以用於表示抽象的資料型別如字典和有序鍊錶,它通過樹旋轉 tree rotation 操作強制使樹結構保持平衡來保證節點搜尋的效率。在資料為隨機插入的情況下,平衡樹效能表現良好 但資料為順序插入或者需要刪除節點的情況下,平衡樹的效能就會有...