什麼是資料庫事務的寫偏斜write-skew?- justinjaffray

發表於2020-12-09

這篇文章是關於寫歪斜write-skew的知識以及擴充套件快照隔離的知識。快照隔離被稱為事務隔離級別,它在效能和正確性之間提供了很好的組合,但是此處“正確性”的確切含義通常含糊不清。在這篇文章中,我想分解並準確記錄何時發生“寫偏斜”事件。

 

事務快速入門

資料庫中的執行單位是事務。事務是工作的集合,這些工作要麼全部完成,要麼根本不執行。沒有半成品事務。通常圍繞事務提供許多保證,但是我們將重點放在隔離上。隔離使資料庫的使用者不必擔心併發性,它決定了事務顯示的程度,好像它在資料庫中單獨執行一樣。

各種可能的隔離級別的分類是一個有趣的話題,但是在這裡,我們將只關注它們之間的關係:SERIALIZABLE和“ Anomaly SERIALIZABLE”(有時稱為SNAPSHOT快照)。

 

可序列化SERIALIZABLE

從某種意義上說,可序列性是“完美”的隔離。似乎每個事務實際上都是完全在資料庫中單獨執行的,即使這可能這不是真正的幕後情況(我的伺服器有很多核心,我們需要充分利用它們)。如果我們獨自執行所有事務,則將其稱為“序列化”。由於這等效於單獨執行它們,因此稱為可序列化。

序列執行是指我們一次只執行一次事務,而不會由於併發而交錯操作。

我們可以將可序列化性視為一種方案,其中每個事務在一個唯一的時間戳上邏輯上完成其所有工作。由於每筆交易至少在概念上都是瞬時發生的,因此使用者不必擔心麻煩的併發性。

順便說一句,值得注意的是“ SERIALIZABLE序列化隔離級別”和“可序列化的執行”是兩個不同的概念。我所見過的大多數討論都將它們混為一談,儘管這會引起一些令人困惑的問題,例如“被表示為“可序列化”的事務如何與非序列化事務進行互動”?

 

異常序列化Anomaly SERIALIZABLE(快照)

可序列化性很奇怪,它是事務理論中為數不多的概念之一,具有非常簡單和明確的定義,但仍以某種方式設法具有兩種完全不同的主流含義。

過去,當ANSI定義SERIALIZABLE隔離級別時,它們的定義雖然正確,但可以解釋為不排除較低的隔離級別(現在稱為“快照隔離”),少數進取的資料庫供應商利用了這一事實。最著名的例子是,如果您向Oracle請求SERIALIZABLE,實際上得到的是SNAPSHOT(快照)。

從某種意義上說,整篇文章都是關於瞭解快照隔離的處理方法。

快照隔離的主要特徵有兩個:

  • 快照隔離中的事務有兩個重要的時間戳:一個是執行讀操作的時間戳,另一個是執行寫操作的時間戳。讀取的時間戳定義了事務看到的資料庫的“一致快照”。如果其他人在事務T的讀取時間戳記之後的某個時間提交寫操作,則將看不到這些更改(通常使用MVCC強制執行。我們將名為“ x”的事務稱為T x,並將讀取和寫入時間戳記分別記為R x和W x。
  • 如果兩個事務執行的間隔重疊(R 1 <W 2和W 1 > R 2),則兩個事務併發。在“快照隔離”中,資料庫強制兩個併發的已提交事務具有不相交的寫集(這意味著它們不會寫到任何相同的記憶體位置)。提交將導致違反此限制的任何事務都將被迫中止並重試。

 

寫偏斜

快照隔離中發生的異常稱為“寫入偏斜”。

其典型示例如下所示:

考慮兩個事務P和Q。P將暫存器x中的值複製到y,Q將暫存器中的值從y複製到x。只有兩個序列執行:P,Q或者Q,P。無論哪種方式,最終結果都是x = y。但是,快照隔離允許另一個結果:

  • 事務P讀取x
  • 事務Q讀取y
  • 事務P將其讀取的值寫入y
  • 事務Q將其讀取的值寫入x

這在“快照隔離”中是可以有效的發生:每個事務維護資料庫的一致檢視,並且其寫集與任何併發事務的寫集不重疊。但是其實x和y已被交換,這兩種序列執行都無法實現結果。

 

更多點選標題見原文。

 

結論

如果您執行的是主流資料庫,則您執行的隔離級別很可能是SNAPSHOT,甚至更低。幾乎沒有主流資料庫預設為真正序列化SERIALIZABLE,許多根本沒有提供它。考慮到SNAPSHOT的盛行,我認為了解確切含義很重要。

正如我希望您已經說服的那樣,“寫偏斜”這一公認的例子是不夠的。如果您想了解更多有關此主題的資訊,那麼我不能說太多:

感謝Arjun Narayan,Ben Darnell,Sean Loiselle,Ilia Chtcherbakov和Forte Shinko閱讀此帖子並提供反饋。

 

相關文章