《MySQL技術內幕五》-InnoDB-數據庫事務

《MySQL技術內幕-InnoDB存儲引擎》學習筆記五-數據庫事務

2019-07-18 ヾ(◍°∇°◍)ノ゙ 不要攔着我 我還能學一會兒

第7章 事務的東東

簡單的說說:就是數據庫區別於文件系統的重要特徵之一了。就是事務是訪問更新數據庫數據的一個單元,在這個事務單元中所有的修改,要麼都成功,要麼都失敗。好像就醬紫。


概述與分類

常說的數據庫特性

  • **原子性(atomicity):**就是事務操作爲最小單位,要麼都成功,要麼都失敗。
  • **一致性(consistency):**不知道是啥 (ノ`Д)ノ
  • **隔離性(isolation):**不同事務之間的數據不會相互影響。
  • **持久性(durability):**事務完成後,數據就爲永久性的了(數據不可逆並持久化存儲於存儲系統當中)

就是常說的啥ACID特性。具體幹啥用的,不知道。但並不是所有數據庫都完全滿足這4個特性的。【比如:oracle 數據庫,默認事務級別爲READ COMMITTED,就不滿足隔離性的了。】

事務的分類

  • 扁平事務 :就是簡單的單個 begin 、commit、rollback這樣子。
  • 帶有保存點的扁平事務:在一個事務中有好幾個保存點用於部分回滾的東東。
  • 鏈事務:一個事務結束之後調用另一個事務。(之間有數據結果傳遞)
  • 嵌套事務:一個事務中 調用另外的子事務。(常見存儲過程之間調用,好像相互調用會死鎖或死循環的樣子)
  • 分佈式事務: 是多個節點間的扁平事務集合。(栗子:招行轉賬到工行,這個操作了兩個節點的數據。需要分佈式事務,要麼都成功,要麼都失敗。雖然這個事務常見處理時在業務層面完成的。)

注意InnoDB是不支持嵌套事務的,ε=(´ο`*)))唉 。。。。。

事務特性的實現

數據庫的事務是要滿足ACID特性的:

  • 隔離性:由 鎖 來實現
  • 原子性、一致性、持久性:由數據庫的redo log 和 undo log 來實現;

redo log爲重做日誌,用來保證事務的原子性和持久性。(物理頁日誌)

undo log爲回滾日誌,用來保證事務的一致性。(邏輯行日誌)

關於各種日誌

redo 重做日誌

是InnoDB開啓事務的時候,就一直在記錄重做日誌,在commit的時候,會把所有日誌寫到重做日誌文件進行持久化保存。【這個動作爲同步fsync操作】

默認配置操作爲commit的時候同步,但是也可以配置 略

重做日誌,分爲兩個部分:內存中的重做日誌緩衝,和 重做日誌文件。

然後這裏面還有啥log block (重做日誌塊)、log group(重做日誌組)、LSN(日誌序列號)等等的東西,都不用管啦,引擎自行處理就好了。

查看重做日誌情況:SHOW ENGINE INNODB STATUS;中的Log sequence ...Log flushed up to ...Last checkpoint at ....... 看看就好了。

undo 回滾日誌

是一種邏輯日誌,用於將數據庫邏輯地恢復到原來的樣子。

show VARIABLES LIKE 'innodb_undo%' 可以用這個語句來查詢一點簡單的信息。

而關於這個回滾日誌的其他的東東,我也看不懂了(ノ`Д)ノ 反正都是InnoDB自己處理的。

其他操作

purge 清空操作

delete 和update 操作,並不會真正的刪除原有的記錄,只是標記頁記錄中的標誌位。真正的刪除是有purge這裏來操作完成的。

是按照一個history list 進行undo log 的查找,並處理清除數據的。對已其他的配置,正常人就不用去調整了。。。

group commit

就是一次同步刷新多個事務日誌到文件。略


以上這些亂七八糟的操作,反正都是建議按InnoDB原本的配置就可以了。(:з」∠)


事務控制

默認情況下,MySQL是自動提交的。就是在執行完一個sql之後,自動就會commit。

常用的語句命令

  • start transaction | begin :顯示開啓事務
  • commit: 顯示事務提交
  • rollback:回滾操作,回滾會結束用戶事務,並撤銷爲提交的修改。
  • savepoint identifier : 允許始終中添加多個保存點
  • release savepoint identifier : 刪除事務保存點,如果沒有保存點會拋出異常
  • rollback to [savepoint] identifier:回滾事務到保存點,但是並沒有結束事務
  • set transaction:設置事務隔離級別。在前一篇鎖的筆記裏面有

這些的事務控制的命令,在做存儲過程的時候是會用上了,普通代碼的CURD是不會用到的

分佈式事務

InnoDB存儲引擎是支持XA事務的,也就是分佈式事務。(XA使用的是兩次提交的事務解決方案)

通常來說,分佈式事務是使用編程語言來完成操作的。比如:**Java的JTA(Java Transaction API)**可以很好的支持Mysql的分佈式事務,具體怎麼用。。。。。鬼知道啊。。。(ノ`Д)ノ 用到的時候再說吧,現在接手的業務還沒到這個級別。

事務的問題

循環提交

正常在存儲過程中循環更新數據的時候,雖然沒有顯示的提交【commit】,但是數據庫默認會自動提交的。也就是說,每一次的更新都會進行一次的日誌同步,這個是很會花時間的。【即使是用了BEGIN,並且在循環中沒有顯示commit】

所以,正確的加快速度的做法是,顯示的START TRANSACION開始事務,在完成後COMMIT。這樣只會進行一次的重做日誌同步。

自動提交

這個就是前邊說的情況,默認情況下Mysql是自動提交的,在大數據更新的時候可能會影響速度。

自動回滾

說的是代碼(存儲過程)中使用異常捕獲,然後自動回滾:像這樣

CREATE PROCEDURE XXXXXXX()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK ;
-- DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ...插入異常日誌... END ;
.........
END;

我覺的挺好啊,不過就是會丟失了,數據庫異常返回的信息而已 ╮(╯_╰)╭;

覺得這個異常捕獲可以做一些日誌的插入,還是很好的;

長事務

就是執行時間幾個小時的事務,需要進行分解爲小的事務來處理。(比如處理n億級別的數據)

雖然,這個級別的數據量我是遇不到的╮(╯_╰)╭


小結一下

這裏由於事務的情況,會建議使用row格式的二進制日誌。

然後主要就是最後一些事務上的問題需要開發的時候注意一下,以及事務開啓的命令要會用【在存儲過程中】。就醬紫即可

2019-07-26 小杭

最近一週一篇的學習進度,好累。。"( ̄(エ) ̄)ゞ


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章