資料系統的事務

2022-09-22 03:39:07 字數 4245 閱讀 6514

資料密集型應用設計讀書筆記第七章

事務可以解決很多資料系統半路故障導致的各種問題。

事務是乙個抽象層,允許應用程式假裝某些併發問題和某些型別的硬體和軟體故障不存在。各式各樣的錯誤被簡化為一種簡單情況:事務中止(transaction abort),而應用需要的僅僅是重試。

從概念上講,事務將多個物件上的多個操作合併為乙個執行單元:整個事務要麼成功(提交(commit))要麼失敗(中止(abort)回滾(rollback)

有時候不使用事務是為了更高的效能,一些安全屬性也並不必須要事務來實現。

怎樣知道你是否需要事務?為了回答這個問題,首先需要確切理解事務可以提供的安全保障,以及它們的代價。

本章主要討論單節點資料庫的事務問題,這些對分布式事務也是有意義的。如果需要了解分布式事務(第九章還會在講),看分布式事務有這一篇就夠了! - 知乎 (zhihu.com)

事務所提供的安全保證,即acid

資料庫通常會用日誌的崩潰恢復來保證原子性,用加鎖來保證隔離性,這些顯然都帶來了效能開銷。也就是為什麼說有時候不用事務的原因。(可以看到,後面的討論其實是集中在原子性和隔離性,這兩個性質可討論的東西多一些。)

事務分為單物件操作和多物件操作,保證了原子性和隔離性的單物件操作有時候會被稱為「輕量級事務」。有一些場景中,單物件插入,更新和刪除是足夠的。但很多場景仍舊需要協調多個物件。這種時候,如果不支援多物件事務的話,沒有原子性,錯誤處理就要複雜得多,缺乏隔離性,就會導致併發問題

可序列化的效能代價太大了,所以有一些弱事務隔離級別。但弱意味著會有些微妙的併發錯誤。所以在本節中,我們將看幾個在實踐中使用的弱(不可序列化(nonserializable))隔離級別,並詳細討論哪種競爭條件可能發生也可能不發生,以便您可以決定什麼級別適合您的應用程式。

讀已提交,最基本的隔離級別,兩個保證

從資料庫讀時,只能看到已提交的資料(沒有髒讀(dirty reads))。

寫入資料庫時,只會覆蓋已經寫入的資料(沒有髒寫(dirty writes))。

實現這個隔離級別,最常見的資料庫做法是行鎖(row-level lock)來防止髒寫。要寫前必須獲得鎖,在事務結束或中止時才釋放鎖。對於髒讀而言,加鎖的效果並不太好。資料庫一般會在事務寫某個物件的過程中,記錄這個物件舊的值。在事務未成功之前,其它事務讀這個物件得到的都是舊值。

快照隔離和可重複讀,在「讀已提交」這個級別中,可能發生這樣一種異常,愛麗絲執行轉賬事務,從a到b轉錢。讀a的餘額時,轉賬還未成功,讀b的餘額時,轉賬已經成功。此時愛麗絲發現自己兩個賬戶的總計餘額和之前對不上了。這種異常被稱為不可重複讀(nonrepeatable read)讀取偏差(read skew)。這個問題在某些情況不能接受,例如做備份或者掃瞄全庫做檢查的時候。最常見的解決方案就是實現快照隔離(每個事務都從資料庫的一致快照(consistent snapshot)中讀取,也就是對某個事務而言,所有資料只能讀到某一時刻的值,而非動態變化的)

防止髒寫,仍舊用鎖

防止不可重複讀,使用多版本併發控制(mvcc, multi-version concurrency control)。每個物件的值,都維護了多個版本。這個技術同樣可以用來實現「讀已提交」的髒讀,即保留乙個物件的兩個版本就足夠了:提交的版本和被覆蓋但尚未提交的版本。對於快照隔離級別而言,同一事務讀的多個物件應該是處於同一快照下。

怎麼實現mvcc?

一種辦法是為每個事務賦予乙個遞增的id,然後事務id會被作為版本號,與那個版本的物件的值儲存在一起。對於乙個事務而言,它應該能看到滿足以下條件的物件的值:

1.讀事務開始時,建立該物件的事務已經提交。

2.物件未被標記為刪除,或如果被標記為刪除,請求刪除的事務在讀事務開始時尚未提交。

所以資料庫會在事務開始時提供正在進行中但未結束的事務的id列表,那麼再結合自己當前的事務id,就可以取乙個最小值id,大於這個id的版本都會被忽略。

防止丟失更新。前面兩個隔離級別主要保證了唯讀事務如果遇到了併發寫入出現衝突的情況。對於兩個寫入的併發事務,可能存在其它問題。例如「丟失更新」。就是說,乙個事務的寫入,如果還涉及資料返回到應用->應用計算->寫入資料庫這些步驟。這樣的兩個事務同時發生時,其中乙個更新可能被丟失(覆蓋)掉。(比如,兩個往賬戶a轉錢的事務併發衝突丟失更新,效果變成了只有乙個起效)那麼有以下解決方法。

原子寫。資料庫自己提供了一些原子操作,如果能用這些代替返回應用計算的過程,則再好不過了。(原子操作通常通過在讀取物件時,獲取其上的排它鎖來實現,或者強制原子操作按順序執行)

顯式鎖定。資料庫提供了鎖定某個物件的操作(例如,for update子句告訴資料庫應該對該查詢返回的所有行加鎖)

自動檢測丟失的更新。由資料庫自動檢查是否丟失更新並中止。一些作者【28,30】認為,資料庫必須能防止丟失更新才稱得上是提供了快照隔離

比較並設定(cas,compare and set)。乙個針對單物件的原子操作。會比較物件的值是否與之前儲存的值一樣,一樣才會設定新值。

衝突解決和複製。以上方法只限於單節點資料庫的情況。對於複製資料庫,多個節點上存在副本,可能同時被寫入,鎖和cas就不適用了。解決方法見第五章。(有些適用於多節點資料庫的原子操作,例如+1操作或者向集合增加元素的操作)

寫入偏差與幻讀。在多個事務並行發生,讀了相同的物件,並且寫某些物件時(特殊的,如果寫相同的物件,就發生髒讀或者丟失更新(取決於時機)),則可能發生寫偏差。寫偏差形容這樣的問題,乙個事務的寫是否成立,取決於讀的某些條件是否達到,如果兩個事務順序執行,前乙個事務成功後乙個失敗。但是兩個同時進行,那麼兩者的條件可能都是成功的。想要真正自動解決這個問題需要「可序列化」的隔離級別。其他有一些比較損失效能的方法,那就是對所有的讀物件加鎖或者是把衝突物化出來(把條件物化成乙個物件,然後查詢條件就是把這個物件加鎖)。

乙個事務中的寫入改變另乙個事務的搜尋查詢的結果,被稱為幻讀。快照隔離避免了唯讀查詢中幻讀,但是在像我們討論的例子那樣的讀寫事務中,幻讀會導致特別棘手的寫入偏差情況。

可序列化隔離級別很好,但為什麼有時候不實現到這個級別呢。先了解下常見的三種實現可序列化隔離級別的技術:

字面意義的序列執行。這裡需要了解「互動型事務」和「儲存過程」的區別。儲存過程與記憶體儲存,使得在單個執行緒上執行所有事務變得可行。由於不需要等待i/o,且避免了併發控制機制的開銷,它們可以在單個執行緒上實現相當好的吞吐量。(如果事務所需的所有資料都在記憶體中,則儲存過程可以非常快地執行,而不用等待任何網路或磁碟i/o。)另外,如果採用分割槽技術,那麼每個節點上的單執行緒之間都需要對跨分割槽事務進行協調以保證序列性,這樣很慢且有上限。

2pl,兩階段鎖,結合讀寫鎖。加鎖影響併發,以及死鎖檢測和中止。這些都是很大的效能開銷。

樂觀併發控制技術,例如可序列化的快照隔離(serializable snapshot isolation,ssl)。 ssi是相當新的:它在2023年首次被描述。

基於過時前提的決策:之前提到的「寫入偏差與幻讀」,其本質是事務執行提交時的前提發生了變化,而快照隔離無法解決這樣的過時前提問題。那麼想要實現序列化隔離,就要能檢測到前提是不是過時了。有兩種情況需要考慮:

檢測對舊mvcc物件版本的讀取(讀之前存在未提交的寫入)

檢測影響先前讀取的寫入(讀之後發生寫入)

檢測舊mvcc讀取:資料庫需要跟蹤乙個事務由於mvcc可見性規則而忽略的另乙個事務的寫入。當事務想要提交時,資料庫檢查是否有任何被忽略的寫入現在已經被提交。如果是這樣,事務必須中止。

檢測影響先前讀取的寫入:當事務寫入資料庫時,它必須在索引中查詢最近曾讀取受影響資料的其他事務。這個過程類似於在受影響的鍵範圍上獲取寫鎖,但鎖並不會阻塞事務指導其他讀事務完成,而是像警戒線一樣只是簡單通知其他事務:你們讀過的資料可能不是最新的啦。

因為是樂觀併發控制技術,ssl最大的優點就是沒有像加鎖那些的效能損耗。中止率顯著影響ssi的整體表現。例如,長時間讀取和寫入資料的事務很可能會發生衝突並中止,因此ssi要求同時讀寫的事務盡量短(唯讀長事務可能沒問題)。簡單點說,樂觀併發控制,在最後要提交的適合才會檢查是否合法,所以如果要執行很長時間的事務,更容易衝突的事務,都會影響其表現。

簡述資料庫系統之事務

一.事務的定義 事務是訪問並可能更新各種資料項的乙個操作集合。該集合是乙個不可分割的整體,即集合中的操作要麼全部執行成功要麼全部未成功,不存在部分執行成功部分執行失敗的最終結果。二.事務的性質 1.原子性 事務中的多個操作要麼全部執行成功,要麼全部未成功 與全部未執行一樣 2.一致性 事務執行前與執...

事務,分布式系統實現事務

1.事務概念 事務是指邏輯上的一組操作,組成該操作的各個單元,要麼全部執行成功,要麼全部執行失敗 只有全部執行成功後,事務才會提交,若有乙個單元執行失敗,那麼所有資料都會通過回滾自動恢復.回滾機制 當事務內部有乙個操作執行失敗後,那麼將會撤銷所有已完成的更新操作 2.事務的四大特性 1 原子性 即不...

URTracker事務跟蹤系統

urtracker事務跟蹤系統是一款通用的問題跟蹤 issue tracking 軟體。它用於幫助企業和團隊建立各種型別的問題處理流程,管理所有的問題並跟蹤記錄這些問題的處理過程,同時為使用者提供乙個分配 流轉和協作處理問題的工作平台。它還內建了知識庫功能,方便使用者轉化問題中的有價值的資訊 積累和...