Jepsen發現PostgreSQL重大Bug:在單個PostgreSQL例項上以可序列化隔離執行的事務實際上是不可序列的

banq發表於2020-06-13

PostgreSQL是一個眾所周知的關聯式資料庫系統。我們使用Jepsen的新事務隔離檢查器Elle評估了PostgreSQL ,發現在單個PostgreSQL例項上以可序列化serializability隔離執行的事務實際上是不可序列化的。

在正常操作下,事務有時可能會顯示G2項:這是涉及一組事務的異常(大致而言),它們相互之間無法觀察到彼此的寫操作。

此外,我們在PostgreSQL“可重複讀取”下發現了G2-item的頻繁例項,這是由可重複讀取的常見形式正式禁止的。正如Martin Kleppmann先前報導的那樣,這是由於PostgreSQL的“可重複讀取”實際上是快照隔離。

由於長期討論ANSI SQL標準中的歧義,因此可以允許這種行為,但是對於熟悉該文獻的使用者來說,這可能是令人驚訝的。我們在8月13日釋出了下一個次要版本的可序列化性錯誤修補程式,可通過文件輕鬆解決G2項在可重複讀取下的存在。這項工作是獨立進行的,沒有任何補償,並且是根據Jepsen道德政策執行的

建議

使用者應注意,PostgreSQL的“可重複讀取”實際上是快照隔離,這在PostgreSQL社群中早已為人所知,並且先前由Kleppmann報告。由於在可重複讀取的常見形式化中禁止使用G2項,因此使用者可能已經設計了應用程式,而這對於PostgreSQL而言是正確的。在這種情況下,使用者可能希望改為在可序列化隔離下執行選定的事務,新增顯式鎖定或重新設計這些事務,以使它們不再對G2項敏感。

我們建議PostgreSQL團隊更新其併發控制文件,以解決圍繞“可重複讀取”的歧義。在當前文件中沒有提到的術語“快照隔離” -stating是PostgreSQL的“可重複讀”,其實就是快照隔離會立即澄清事實。通過用G-single,G2-item和G2代替模稜兩可的“序列化異常”,文件還可以為使用者提供更清晰的指導;SI禁止使用單G,但允許G2和G2。

關於快照隔離是否比可重複讀取強,一種可能的解決方案是採用Berenson等人的定義,這樣做將使PostgreSQL與BerensonAdyaBailis等人在事務隔離方面的25年學術獎學金保持[url=https://www.vldb.org/pvldb/vol7/p181-bailis.pdf]一致[/url]。

似乎沒有PostgreSQL版本可以保證可序列化。使用者應注意,併發更新和插入事務可能會出現G2專案。高爭用的工作負載尤其容易受到影響。PostgreSQL團隊已經編寫了測試來重現該問題,並正在評估補丁。我們建議在下一個次要版本可用時進行升級。

點選標題見原文詳細分析。

相關文章