本文是一篇CockroachDB官方博客的譯文,主要闡述數據庫實現串行化隔離的必要性。關於事務隔離性,Ivan曾經在「分佈式數據庫之事務隔離性」中從理論方面進行過系統的介紹,本文則是從數據庫廠商的角度來闡述對隔離性的理解,你們能夠將兩篇文章結合起來,對隔離性有更加全面客觀的理解。CockroachDB的理念是首先保證安全性然後追求高性能,因此花了很大精力實現Serializable Snapshot Isolation
,是目前極少的有實用價值的SERIALIZABLE
實現。固然,業界也有廠商對可串行化方面投入的必要性持不一樣觀點。Ivan猜想CockroachDB的理念多是受到了PostgreSQL的影響,畢竟後者是率先支持Serializable Snapshot Isolation
的商業數據庫,而且CockroachDB在SQL層面也是以兼容PostgreSQL爲目標。sql
大多數數據庫都提供了事務隔離級別的選擇,能夠在正確性和性能之間進行權衡。然而,高性能的代價就是開發人員必須當心研究事務交互不然就會引入一些微妙的錯誤。CockroachDB 默認提供了強隔離(SERIALIZABLE
)能夠確保你的應用老是看到指望的數據。在本文中咱們將解釋這意味着什麼以及不充分的隔離在如何影響真實世界的應用。數據庫
SQL標準定義四個隔離級別瀏覽器
SERIALIZABLE
安全
REPEATED READ
併發
READ COMMITTED
分佈式
READ UNCOMMITTED
工具
SERIALIZABLE
事務運行時好像在同一時刻僅有一個事務運行;其餘隔離級別容許出現SQL標準稱做的「三種phenomena」髒讀、不可重複讀、幻讀。後續的研究(此處指Critique,Ivan在文章「分佈式數據庫之事務隔離性」中已經進行了介紹)定義了額外的「phenomena」和隔離級別。
在現代研究中,這些「phenomena」更廣泛被稱爲「anomalies」,或者更直接稱爲」lies」。當你使用一個非SERIALIZABLE
隔離級別時,你是在容許數據庫返回錯誤答案,但願它能比正確答案更快。SQL標準認爲這是危險的,須要SERIALIZABLE
置爲默認的隔離級別。更弱的隔離級別只是爲那些能夠容忍「anomalies」的應用提供了潛在的優化手段。性能
多數的數據庫忽略了將 SERIALIZABLE
做爲默認隔離級別的規約,而是默認替換爲更弱的RC
或RR
隔離級別,它們的性能優先於安全性。更使人擔憂的是,一些數據庫(包括Oracle,PostgreSQL V9.1之前)根本不提供 SERIALIZABLE
級別的事務隔離。Oracle實現的 SERIALIZABLE
隔離級別其實是更弱的「Snapshot Isolation
」。Snapshot Isolation
(快照隔離,簡稱SI
)的出現晚於SQL標準的制定,可是已經被多種數據庫系統實現,由於它提供了很好的性能與一致性的平衡。它強於RC
但弱於 SERIALIZABLE
,很相似RR
但不徹底等同(RR
容許幻讀,但禁止寫偏序,SI
更好相反)。實現SI
的數據庫,在如何將其歸入到四個SQL標準隔離級別上有不一樣的選擇。Oracle的選擇最激進,直接將他們的SI
實現稱爲 SERIALIZABLE
。CockroachDB 和SQL Server則保守一些,將SI
做爲獨立的第五個隔離級別。PostgreSQL(9.1版本之後)介於二者之間,使用SI
替換了RR
。由於數據庫不多使用 SERIALIZABLE
模式,而是默認採用更弱的隔離級別,因此它一般不多通過完全的測試和優化。例如PostgreSQL有一個固定大小的內存池,用來跟蹤可串行化事務間的衝突,但在高負載狀況下會耗盡。
多數的數據庫廠商將更強的事務隔離做爲給應用程序的一個特殊選項用於應對額外的一致性需求。多數應用程序被認爲能夠運行在更快可是不安全的弱隔離模式下。這種處理問題的落後方式致使將應用程序暴露在大量細微的bug中。在Cockroach Labs,咱們喜歡思考事務anomalies,以致於咱們用它們來命名會議室。但我很難有信心的建議何時選擇 SI
替代 SERIALIZABLE
是安全有益的。
咱們的哲學是從安全性出發向着高性能方向前進,這是比其餘方式更優的。學習
斯坦福最近的研究展現了弱隔離性對真實世界的影響程度。 Todd Warszawski and Peter Bailis測試了12個電子商務應用程序並發現了22個事務相關的Bug,其中5個在更高的隔離級別下能夠避免。多數bug能夠被簡單得利用並形成財務方面的影響。例如,在5個被測試的應用程序中,當操做一個瀏覽器進行結算的同時,操做另外一個瀏覽器向購物車增長一項商品,可能致使新增的商品在帳單中免費。這些研究人員開發工具以半自動化的方式去肯定這些脆弱點,爲相似的更廣泛的攻擊(研究者將其稱爲ACIDRain 「酸雨」)鋪平了道路。
大多數默認弱隔離的數據庫都提供瞭解決方法,例如 FOR UPDATE
和 LOCK IN SHARE MODE
(非標準語法)做爲SQL語句的修飾符。當正確使用時,即便在弱隔離級別下,這些修飾符也可使事務安全。然而,這很容易出錯,並且即便是使用這些擴展方式,也會同時引入 SERIALIZABLE
模式大多數的缺點。(事實上,在RC
事務中濫用 SELECT FOR UPDATE
能夠致使比 SERIALIZABLE
更差的性能,由於在那些串行化操做的地方能夠僅使用共享鎖,卻使用了排他鎖) ACIDRain的研究顯示了這種技術的侷限性:3個應用程序中僅有一個正確使用了 SELECT FOR UPDATE
特性,其餘兩個都存在漏洞。開發工具
鼓勵弱隔離級別(性能優先於數據安全性)的數據庫,讓你去學習事務間細微的交互並實現易錯的解決方法。CockroachDB默認提供了 SERIALIZABLE
事務,確保總能看到你所指望的事務數據庫的一致性
原文連接 https://www.cockroachlabs.com/blog/acid-rain/