MYSQL事務隔離與事務日誌

一 序:

在看《高性能MySQL》書的時候,講到了MVCC。這個概念我是模糊的,腦子印象就是讀不加鎖,讀寫不衝突。

咋實現的?看書專門整理下,後面加上網上關於MVCC的理解。

二 事務隔離級別

2.1 事務

 數據庫事務(Database Transaction),是指作爲單個邏輯工作單元執行的一系列操作,要麼完全執行,要麼完全地不執行。

原子性(Atomicity)
一個事物被視爲不可分割的最小工作單元,整個事務中所有操作要麼全部提交成功,要麼全部失敗回滾。不可能只執行其中的一部分操作。
一致性(Consistency)
一致性是指事務必須使數據庫從一個一致的狀態變到另外一個一致的狀態,也就是執行事務之前和之後的狀態都必須處於一致的狀態。
隔離性(Isolation)
隔離性通常來說,一個事務所做的修改在提交之前,對其他事務是不可見的。
持久性(Durability)
持久性是指一個事務一旦被提交了,那麼對於數據庫中的數據改變就是永久性的,即便是在數據庫系統遭遇到故障的情況下也不會丟失提交事務的操作。

書上的舉例還是經典的銀行轉賬的例子,當然上面介紹的是數據庫的通用原則,並非MySQL專有特性。

2.2 mysql 使用事務

MySQL默認採用自動提交(autocommit )模式,當然可以修改啓用或者禁用自動修改模式。

show variables like 'autocommit'
    -> ;
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.00 sec)

回滾舉例:

set autocommit = 0 禁止自動提交
start transaction;
update account set money=money-100 where name="justin";
rollback;

2.3 事務隔離級別

Read Uncommitted(讀取未提交內容)
       在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。本隔離級別很少用於實際應用,因爲它的性能也不比其他級別好多少。讀取未提交的數據,也被稱之爲髒讀(Dirty Read)。
Read Committed(讀取提交內容)
       這是大多數數據庫系統的默認隔離級別(但不是MySQL默認的)。它滿足了隔離的簡單定義:一個事務只能看見已經提交事務所做的改變。這種隔離級別 也支持所謂的不可重複讀(Nonrepeatable Read),因爲同一事務的其他實例在該實例處理其間可能會有新的commit,所以同一select可能返回不同結果。
Repeatable Read(可重讀)
       這是MySQL的默認事務隔離級別,它確保同一事務的多個實例在併發讀取數據時,會看到同樣的數據行。不過理論上,這會導致另一個棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當用戶讀取某一範圍的數據行時,另一個事務又在該範圍內插入了新行,當用戶再讀取該範圍的數據行時,會發現有新的“幻影” 行。InnoDB和Falcon存儲引擎通過多版本併發控制(MVCC,Multiversion Concurrency Control)機制解決了該問題。
Serializable(可串行化) 
       這是最高的隔離級別,它通過強制事務排序,使之不可能相互衝突,從而解決幻讀問題。簡言之,它是在每個讀的數據行上加上共享鎖。在這個級別,可能導致大量的超時現象和鎖競爭。
         這四種隔離級別採取不同的鎖類型來實現,若讀取的是同一個數據的話,就容易發生問題。例如:
         髒讀(Drity Read):某個事務已更新一份數據,另一個事務在此時讀取了同一份數據,由於某些原因,前一個RollBack了操作,則後一個事務所讀取的數據就會是不正確的。
         不可重複讀(Non-repeatable read):在一個事務的兩次查詢之中數據不一致,這可能是兩次查詢過程中間插入了一個事務更新的原有的數據。

         幻讀(Phantom Read):在一個事務的兩次查詢中數據筆數不一致,例如有一個事務查詢了幾列(Row)數據,而另一個事務卻在此時插入了新的幾列數據,先前的事務在接下來的查詢中,就會發現有幾列數據是它先前所沒有的。


mysql 中的隔離級別設置:

查看 select @@tx_isolation;

select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+
1 row in set (0.00 sec)

修改隔離級別

set  [global | session]  transaction isolation level 隔離級別名稱;

三  事務日誌

       事務日誌用於保證事務的可靠性,在進行事務操作時先將操作寫進事務日誌,而事務日誌會記錄老數據和新數據從而實現回滾。並且不用每次都將修改的數據本身持久到磁盤,事務日誌採用的是追加的方式記錄。因此寫日誌操作時磁盤上一小塊區域內的順序I/O,而不像隨機I/O需要在磁盤的多個地方移動磁頭。所以採用事務日誌的方式相對來說要快得多。事務日誌持久以後,內存中被修改的數據在後臺可以慢慢地刷回磁盤。目前大多數存儲引擎都是這樣設計的。我們通常稱之爲預寫式日誌,修改數據需要寫兩次磁盤。

      如果數據的修改意見記錄到事務日誌並持久化,但數據本身還沒有寫回磁盤,此時系統崩潰,存儲引擎在重啓時能夠自動恢復這部分修改的數據。具體的恢復方式視存儲引擎而定。

   以上是書上1.3.3事務日誌的內容,沒有展開。其實這塊內容挺多的。開個頭,後續在整理吧

MySQL中有六種日誌文件,分別是:重做日誌(redo log) 回滾日誌(undo log) 二進制日誌(binlog) 錯誤日誌(errorlog) 慢查詢日誌(slow query log) 一般查詢日誌(general log) 中繼日誌(relay log)。其中重做日誌和回滾日誌與事務操作息息相關,二進制日誌也與事務操作有一定的關係。參見網上這篇文章《MySQL主庫CrashSafe與Binlog關係?

3.1 redo

作用:確保事務的持久性。防止在發生故障的時間點,尚有髒頁未寫入磁盤,在重啓mysql服務的時候,根據redo log進行重做,從而達到事務的持久性這一特性。

內容:物理格式的日誌,記錄的是物理數據頁面的修改的信息,其redo log是順序寫入redo log file的物理文件中去的。

什麼時候產生:事務開始之後就產生redo log,redo log的落盤並不是隨着事務的提交才寫入的,而是在事務的執行過程中,便開始寫入redo log文件中。

對應的物理文件:data目錄下ib_logfile*。

關於文件的大小和數量,由以下兩個參數配置:
innodb_log_file_size 重做日誌文件的大小。
innodb_mirrored_log_groups 指定了日誌鏡像文件組的數量,默認1

上面提到的Dirty page:髒頁 什麼意思呢?
       一般業務運行過程中,當業務需要對某張的某行數據進行修改的時候,innodb會先將該數據從磁盤讀取到緩存中去,然後在緩存中對這條數據進行修改,這樣緩存中的數據就和磁盤的數據不一致了,這個時候緩存中的數據就稱爲dirty page,只有當髒頁統一刷新到磁盤中才會是clean page。
     一般情況下,mysql在崩潰之後,重啓服務,innodb通過回滾日誌undo將所有已完成並寫入磁盤的未完成事務進行rollback,然後redo中的事務全部重新執行一遍即可恢復數據,但是隨着redo的量增加,每次從redo的第一條開始恢復就會浪費長的時間,所以引入了checkpoint機制。

Checkpoint:如果在某個時間點,髒頁的數據被刷新到了磁盤,系統就把這個刷新的時間點記錄到redo log的結尾位置,在進行恢復數據的時候,checkpoint時間點之前的數據就不需要進行恢復了,可以縮短時間。

3.2 undo log

undo log不是redo log的逆向過程,其實它們都算是用來恢復的日誌:
1.redo log通常是物理日誌,記錄的是數據頁的物理修改,而不是某一行或某幾行修改成怎樣怎樣,它用來恢復提交後的物理數據頁(恢復數據頁,且只能恢復到最後一次提交的位置)。

2.undo用來回滾行記錄到某個版本。undo log一般是邏輯日誌,根據每行記錄進行記錄。

作用:提供回滾和多個行版本控制(MVCC)。

內容:邏輯格式的日誌,在執行undo的時候,僅僅是將數據從邏輯上恢復至事務之前的狀態,而不是從物理頁面上操作實現的,這一點是不同於redo log的。

什麼時候產生:事務開始之前,將當前是的版本生成undo log,undo 也會產生 redo 來保證undo log的可靠性

文件:從MySQL 5.6開始,Undo使用的表空間可以分離爲獨立的Undo log文件。

存儲:爲了提高undo log的併發操作,InnoDB將Undo log拆分爲很多的浮動程序段(relocatable segment)來進行維護,每個RSEG當中又有多個Undo log slot,每個事務佔用一個slot。

這裏內容還很多。待續。。。

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