MySQL讀書筆記-事務日誌,MySQL中的事務
WLA(Write-Ahead Logging)
事務日誌,可以幫助提高事務的效率。使用事務日誌,儲存引擎在修改表的資料時,只需要修改其記憶體拷貝,再把該修改行為記錄到硬碟上的事務日誌中,而不用每次都將修改的資料本身持久到磁碟。事務日誌採用的是追加的方式,因此寫日誌的操作是磁碟上一小塊區域內的順序I/O,而不是隨機I/O,所以快很多。事務日誌持久以後,記憶體中被修改的資料在後臺可以慢慢地刷回到磁碟。此方式稱之為,預寫式日誌,修改資料需要寫兩次磁碟。
如果資料的修改已經紀錄到事務日誌中,但資料本身還沒有寫回磁碟,此時系統崩潰,儲存引擎在重啟時,能夠自動恢復這部分修改的資料(具體恢復方式則視儲存引擎而定)。
MySQL中的事務
MySQL提供了兩種事務儲存引擎:InnoDB和NDB Cluster。另外還有一些第三方的儲存引擎(例如,XtraDB)也支援事務。
- 自動提交(AUTOCOMMIT)
MySQL預設採用自動提交模式。即,如果不是顯示地開始一個事務,則每個查詢都被當作一個事務執行提交操作。在當前連線中,可以通過設定AUTOCOMMIT變數來啟用或禁用自動提交模式。1或者ON表示啟用,0或者OFF表示禁用。
(1)當
AUTOCOMMIT=0
時,所有的查詢都是在一個事務中,直到顯示地執行COMMIT
,或者ROLLBACK
時,該事務結束。
(2)修改AUTOCOMMIT對非事務型的表(例如,MyISAM),不會有任何影響,相當於一直處於AUTOCOMMIT啟用的模式。
(3)一些命令,在執行前會強制執行COMMIT提交當前的事務。例如,使用DDL(資料定義語言)。
(4)MySQL可以通過執行SET TRANSACTION ISOLATION LEVEL
命令來設定隔離級別,新的隔離級別會在下一個事務開始時生效。
# 檢視AUTOCOMMIT狀態和啟用
SHOW VARIABLES LIKE 'AUTOCOMMIT';
SET AUTOCOMMIT = 1;
# 設定下一個會話的隔離級別為READ COMMITED
SET TRANSACTION ISOLATION LEVEL READ COMMITED;
- 在事務中混合使用儲存引擎
MySQL伺服器層不管理事務,事務是由下層的儲存引擎實現的。所以,在同一個事務中,使用多種儲存引擎是不可靠的。
(1)為每張表選擇合適的儲存引擎非常重要。
(2)在非事務型表上執行事務相關操作,MySQL通常不會發出提醒,也不會報錯(即,大多數情況下,對非事務型表的操作都不會有提示)。
- 隱式和顯式鎖定
InnoDB採用的是兩階段鎖定協議(two-phase locking protocol)。
隱式鎖定,InnoDB會根據隔離級別在需要的時候自動加鎖,並在執行COMMIT或ROLLBACK時釋放。
顯式鎖定,InnoDB也支援通過特定的語句進行顯式鎖定,這些語句不屬於SQL規範。
SELECT ... LOCK IN SHARE MODE;
SELECT ... FOR UPDATE;
MySQL也支援LOCK TABLES
和UNLOCK TABLES
語句,這是在伺服器層實現的,和儲存引擎無關。它們有自己的用途,但並不能代替事務處理,如果應用需要用到事務,還是應該選擇事務型儲存引擎。
思考:InnoDB的行級鎖比MyISAM中使用LOCK TABLES開銷要小。