參考書籍《mysql是怎樣執行的》
以及極客時間《mysql實戰45講》
本文總結事務相關的概念,事務相關的命令等,具體永續性,原子性,隔離性如何實現,會在後續的學習中進行補充
上一篇關於buffer pool的學習中,我們學習Buffer pool相關知識,innodb再對某個頁面進行讀寫存取時,會將這個頁面讀到buffer pool 中,之後如果修改了某個頁面,也不會立即重新整理到磁碟,而只是將緩衝頁面的控制塊新增到flush 連結串列中,之後某個時間點(後臺定時任務執行緒每隔一定時間將flush 連結串列中的髒頁重新整理到磁碟,或者新的頁面需要緩衝,將LRU連結串列中一些髒頁刷盤)。那麼如果mysql服務突然崩潰,或者伺服器突然斷電,豈不是已經提交的事務
將丟失?
事務是指是程式中一系列嚴密的邏輯操作,而且所有操作必須全部成功完成,否則在每個操作中所作的所有更改都會被撤消
這裡保證已經提交事務一定可以持久化到磁碟的就是redo log。類似如果事務執行到一半需要回滾如何實現暱,這就是undo log實現的版本控制鏈的作用。
要麼多個操作都執行,要麼多個操作都不執行,不可存在中間狀態。但是現實世界中一個業務存在多個步驟,這些步驟抽象為資料庫操作又存在多個,一個資料庫操作又可分為多步(比如先修改緩衝頁,再重新整理磁碟)任何一個時間點都可能發生意想不到的錯誤,使操作無法執行下去,所以需要保證:如果再執行過程中發生了錯誤
,就把已經執行的操作恢復為執行前的樣子。
對於現實世界中狀態轉換對應的某些資料庫操作來說,不僅僅需要保證原子性,還需要保證其他資料庫操作造成狀態轉換不會影響到本次狀態轉換。這便是隔離性
只有符合約束的資料才是有效(年齡再符合規定的範圍,房價不能為負數)如果資料中的資料全部符合現實世界的約束,我們就說這些資料具備一致性
。如何實現一致性
如果資料庫操作不符合原子性(轉錢扣了轉賬者,但是收款的人錢數沒有增加)或者不符合隔離性(兩個操作並行,第二個操作讀到第一個操作沒有提交的資料,然後第二個操作後寫回,發生了髒寫)這也是不符合一致性要求——資料庫中原子性和隔離性都是保證一致性的一種手段
當現實世界中的一個狀態轉換完成後,這個轉換結果需要永久保留,這稱為永續性
,現實世界中狀態轉換對映到資料中時,永續性意味著轉換對應的資料需要持久化到磁碟中,無論發生什麼事故,本次轉換操作的影響都不應該丟失(損壞磁碟除外doge)
回滾
,當回滾操作執行完畢,稱為終止的部分狀態的事務
對應操作重新整理到磁碟,稱為提交的Begin
Start Transaction
該命令可以跟隨如下修飾符,多個修飾符使用逗號分隔,如Start Transaction read only,with consistent snapshot
read only
標識當前事務是一個唯讀事務,屬於該事務的資料庫操作只能進行讀操作(但是可以改當前對談中的臨時表)(為什麼唯讀還需要事務,因為需要獲得一致性檢視,不同的隔離級別會讀到不同的資料,比如你想統計流水錶中本月每一個顧客的消費資訊,先統計了總流水Sum,然後依次統計每一個使用者的流水,如果沒用事務,第後續的對每一個顧客的統計之和可能讀到最新的資料(使用者新增了消費),而導致總流水和每一個使用者流水之和不等的情況)
read write
標記當前事務是讀寫事務
with consistent snapshot
啟動一致性讀
begin/start transaction 命令並不是一個事務的起點,在執行到它們之後的第一個操作
InnoDB 表的語句,事務才真正啟動。(一致性檢視是在第執行第一個快照讀語句時建立的)
如果你想要馬上啟動一個事務,可以使用 start transaction with consistent snapshot 這個命令。(一致性檢視是在執行 start transaction with consistent snapshot 時建立的)
commit
commit work and chain
提交當前事務並開啟下一個事務,如果執行 commit work and chain,則是提交事務並自動啟動下一個事務,這樣省去了再次執行 begin 語句的開銷
roll back
,程式設計師可以手段roll back進行回滾事務,如果事務在執行的過程中遇到一些錯誤,比如發生了死鎖,會回滾整個事務
mysql 有一個系統變數autocommit
來控制是否自動提交事務,如果不顯示的使用開啟事務的命令,那麼每一條語句就視為一個獨立的事務。關閉自動提交的方式有:手動開啟事務,設定自動提交為OFF,這時候需要手動提交或者進行回滾。
mysql中如果輸入了一些特定的語句,即便不是commit 命令也會提交事務。如
執行ddl,定義資料庫物件的命令,比如建立表,修改表,以及檢視,儲存過程等
隱式的使用或者修改mysql資料庫中的表
使用alter user
,create user
,drop user
等語句的時候會提交前面語句屬於的事務
事務控制or關於鎖定的語句
如果一個事務還沒有提交,或者回滾的時候,又開啟一個新事務,或者修改autocommit
的值從OFF 到ON的時候也會提交事務。使用lock tables,unlock tables等關於鎖定的語句也會提交事務
載入資料的語句
比如使用load data等語句也會提交事務
關於mysql複製的語句
比如start slave
,stop slave
也會提交事務
其他語句
比如optimize table
等
savepoint 儲存點名稱
,可以開啟一個儲存點,使用rollback to 儲存點名稱
可以回滾到指定儲存點,使用release savepoint 儲存點
可以釋放儲存點,儲存點如同遊戲的存檔,避免我們從頭開始,心態炸裂
長事務意味著系統裡面會存在很老的事務檢視。由於這些事務隨時可能存取資料庫裡面的任何資料,所以這個事務提交之前,資料庫裡面它可能用到的回滾記錄都必須保留,這就會導致大量佔用儲存空間(記錄回滾資訊的undo log,需要一致儲存,佔用空間)可以在information_schema
庫的innodb_trx
這個表中查詢長事務的資訊