More Related Content
Similar to Serializabilityとは何か (20)
More from Takashi Hoshino (20)
Serializabilityとは何か
- 2. 自己紹介
• 星野 喬 (@starpoz)
• サイボウズ・ラボ (2009〜)
• 最近の活動
• トランザクション処理などの研究
• セキュリティキャンプ データベースゼミ講師 (2018〜2022)
• 「データベースシステム自作入門」
https://github.com/starpos/develop-transaction-system/releases
• サイボウズ・ラボユース
• 「C++初心者からの脱出」同人誌
• https://github.com/starpos/get-out-of-cpp-beginners
2
- 3. トランザクション処理
• トランザクション
• データベース上の一連の操作をひとまとまりにした単位
• (この資料では Tx と略す)
• トランザクション処理
• データベースに対する複数のトランザクションを正しく実行し、結果が Tx 単位で残る
(ACID を短く説明)
• アプリケーションソフトウェアやそれを使う人の利便性のため
• 効率良く処理するという大前提はある
• 効率良く
• ハードウェア(CPU、メモリ、ディスク、ネットワーク機材など)を活用して
• 良い性能(高スループット、低レイテンシ)で
• (無駄遣いせずに)
3
- 4. 正しい実行とは?
• ユーザ/アプリケーションの要件を満たす実行のうち、
アプリケーション側が担わなくてすむように DBMS が頑張る部分
• Consistency: データを正しい状態に保つための補助
• Isolation: Tx を並行(並列)実行したときの正しさを担保
• C と I は共同で正しさについての役割を担う
• 諸説あり: https://fauna.com/blog/demystifying-database-systems-introduction-to-
consistency-levels
• Consistency という言葉に込められた様々な意味(文脈依存)
• 最新の値を読める(Non-stale reads)こと
• 外部の因果関係と矛盾しないこと
• 複数レプリカが同じ内容に収束すること
• ……
4
- 5. Serializabilityとは何か?
• 直列化可能性 (Serializability の訳)
• Tx 集合があたかも直列実行されたかのように(並行)実行されること
• 直列実行: Tx をひとつずつ実行すること
• 直列実行したら正しく動くという仮定を置いている
• 各 Tx にとっては世界でデータベースを読み書きしているのは自分だけとい
う仮定の元で実行できる、つまり任意の不変条件を検証可能
• Serializability (を実現する技術)はあくまで便利な道具である点に注意
• 世界は Serializable ではない。例えば Git repository の履歴は Merge commit が作れる。
つまり、一部のアプリケーションにとって Serializability は余計なお世話。
• Serializability はデータや Tx の正しさを担保するための極端な性質ともいえる
• 直列実行で済む要件の場合は迷いなく直列実行すべき
5
- 6. トランザクションの直列実行
• トランザクション 𝑡𝑖 をひとつずつ順番に実行する
• 𝑡𝑖 はデータベース状態 𝑠𝑖−1 を読んで、計算し、書き、𝑠𝑖 を生成する
• 結果として対応する Tx 全順序(状態の全順序)がひとつ決まる
• 世界に自分しかいないので、どう読むか、どう書くかという詳細に踏み込む
必要がない
• これだけだと、どのように並行に読み書きするかという議論ができないので、
もう少し詳細なモデルを作る必要がある
6
𝑠0 𝑠1
𝑡1 𝑡2
𝑠2
𝑡𝑁
𝑠𝑁
…
- 7. ページモデル
• データベースをページの集合として捉える
• ページは読み(R) or 書き(W) の操作 (Op) ができる
• Tx は、ページと操作のペアの集合と捉える
• Single-version モデル: 各ページ上の Op の(実行)順序を主に扱う
• 𝑟1 𝑥 𝑤1 𝑦 𝑟2 𝑥 𝑟2 𝑦 𝑤2(𝑦) (ここでは Op 列順 = Op 実行順序とする)
• Multi-version モデル: View を主に扱う
• 𝑟1 𝑥0 𝑤1 𝑦 𝑟2 𝑥0 𝑟2 𝑦1 𝑤2(𝑦) (Op 順序はない or 重要ではない)
7
ページモデルの詳細については Transactional Information Systems (Weikum and Vossen, Amazon) などを参照。
表記も概ねその作法に従っている。
ページ: 𝑥, 𝑦
𝑡1 = 𝑟1 𝑥 𝑤1 𝑦 (𝑥 を読んで、𝑦 を書く)
𝑡2 = 𝑟2 𝑥 𝑟2 𝑦 𝑤2 𝑦 (𝑥 と 𝑦 を読んで、𝑦 を書く)
𝑇 = {𝑡1, 𝑡2}
- 8. View
• View: 各 Read op について、どの Tx が書いた値を読んだかの対応
• 同一ページについての Write op を含む(自分自身でない) Tx が対応する
• Reads from 関係とも言う: 𝑡𝑖 reads 𝑥 from 𝑡𝑗 や 𝑡𝑖 reads from 𝑡𝑗 など
• 𝑡1 = 𝑟1 𝑥 𝑤1 𝑦 と 𝑡2 = 𝑟2 𝑥 𝑟2 𝑦 𝑤2 𝑦 があったとき、
その直列実行は 𝑡1𝑡2 か 𝑡2𝑡1 のいずれか (与えられた Tx 集合の順列)
• 直列実行における View 制約
• 直前にそのページを書いた Tx を View の対象とする (Tx 列から一意に決まる)
• 𝑡1𝑡2 のとき 𝑟1 𝑥0 𝑤1 𝑦 𝑟2 𝑥0 𝑟2 𝑦1 𝑤2 𝑦 となる
• Single-version モデルには直列実行と同様の View 制約がある
• Op 順序から View が一意に決まる (Standard version function と呼ばれる)
• Multi-version モデルでの View の扱い
• Serializability 判定問題において、View は与えられるもの
• Concurrency Control プロトコルにおいて、View は自分で決めるもの
8
- 9. View Serializable
• View が同じ直列実行が存在するような(並行)実行のこと
• ℎ1 = 𝑟2 𝑥0 𝑟1 𝑥0 𝑤1 𝑦 𝑟2 𝑦1 𝑤2 𝑦 は、
ℎ1
′
= 𝑟1 𝑥0 𝑤1 𝑦 𝑟2 𝑥0 𝑟2 𝑦1 𝑤2 𝑦 = 𝑡1𝑡2 という View が同じ直列実行が
存在するから View serializable
• CV-rule: Tx 集合上の半順序 𝑅 について、
• C-rule: 𝑡𝑖 reads from 𝑡𝑗 のとき、𝑡𝑗 <𝑅 𝑡𝑖
• V-rule: 𝑡𝑖 reads from 𝑡𝑗 かつ 𝑡𝑘 が同一ページを書いているとき、𝑡𝑘 <𝑅 𝑡𝑗 ∨ 𝑡𝑖 <𝑅 𝑡𝑘
• CV-equivalent Theorem
• C-rule と V-rule を満たす半順序 R が存在 View serializable
• View があれば View serializable かどうか決まるので、Single-version でも
Multi-version でも使える
9
もう少し詳しく知りたい人はこちら: https://qiita.com/starpoz/items/266ab514bbc308d438a6
- 10. Conflict Serializable
• 競合関係(Conflicts)が同じ直列実行が存在するような(並行)実行のこと
• Reader-writer Lock の理屈で競合関係を考える
• 原則として Single-version モデルで有効
• Operation 順序を 𝑂 とする(Tx 集合を 𝑇、op(𝑇) = ⨆ {𝑜 ∈ 𝑡 ∣ 𝑡 ∈ 𝑇)、𝑂 ⊂ 𝑜𝑝(𝑇) × 𝑜𝑝(𝑇))
• Multi-version でもうまく 𝑂 相当の情報を与えて Conflicts を定義すれば議論は可能
• 𝑝𝑖 𝑥 <𝑂 𝑞𝑗 𝑥 となる 𝑥 が存在する 𝑖, 𝑗 について 𝑡𝑖, 𝑡𝑗 ∈ conf𝑝𝑞(𝑇, 𝑂)
• ただし、(𝑝, 𝑞) は (𝑤, 𝑟), (𝑤, 𝑤), (𝑟, 𝑤) のいずれか
• conf 𝑇, 𝑂 ≔ conf𝑤𝑟 𝑇, 𝑂 ∪ conf𝑤𝑤 𝑇, 𝑂 ∪ conf𝑟𝑤(𝑇, 𝑂)
• Conflict-equivalent Theorem
• conf 𝑇, 𝑂 が半順序 Conflict serializable
• Conflict serializable ならば View serializable
• 逆は必ずしも成り立たない
10
- 12. 例1: Predicate Reads
• 物理的に存在しないレコードも含めて読む
• Table full scan や Range scan など
• 問題: Phantom anomaly
• 𝑡1: Table に 4 を Insert
• 𝑡2: Table の Full scan 結果 1, 5
• 𝑤1 𝑧 𝑟2(𝑥0, 𝑦0) と解釈してしまうと、𝑡1𝑡2 は OK (View が一致する直列実行) となってしまう
• しかし、𝑡1𝑡2 直列実行による 𝑡2 の Full scan 結果は 1, 4, 5 となるはず
• 物理的に存在しないレコードについて直接 Lock することなどができない
• 典型的な Phantom anomaly 回避方法
• 存在しないレコードに対応するデータ構造単位をページとみなす
• Table を読んだ(Full scan) vs Table を書いた(Insert)した
• Tree index の Leaf node を読んだ(Range scan) vs Leaf node を書いた(Insert)した
12
𝑠0: {1,5} 𝑠1: {1,4,5}
𝑡1 𝑡2?
参考: Adya による Predicate の扱い http://pmg.csail.mit.edu/pubs/adya99__weak_consis-abstract.html
- 13. 例2: 口座間の資金移動
• データベース状態: 𝑠 = {𝐴, 𝐵} 預金額を表す非負整数 2 口座分
• 操作: 口座間の資金移動(引き出し+預け入れ)
• 例
• 𝑠0 = 𝐴: 0, 𝐵: 100
• 𝑡1: 𝐵 から 𝐴 に 10 移動
• 𝑡2: 𝐵 から 𝐴 に 20 移動
• 𝑡3: 𝐴 から 𝐵 に 30 移動
• ページモデルで表現: A,B を Read および Write (Read-modify-write)
• 𝑟1 𝐴0, 𝐵0 𝑤1(𝐴, 𝐵)𝑟2 𝐴1, 𝐵1 𝑤2(𝐴, 𝐵)𝑟3 𝐴2, 𝐵2 𝑤3(𝐴, 𝐵)
• この表現だと 𝑡1𝑡2𝑡3 しか OK にできないが、𝑡2𝑡1𝑡3 も OK としたい
13
𝑠0: {𝐴: 0, 𝐵: 100} 𝑠1: {𝐴: 10, 𝐵: 90}
𝑡1
𝑠2: {𝐴: 30, 𝐵: 70} 𝑠3: {𝐴: 0, 𝐵: 100}
𝑡2 𝑡3
参考(例のみ、提案モデルは異なる): https://dl.acm.org/doi/10.1145/3486601.3486707
- 14. 例3: SQL Insert/Delete
• SQL Insert/Delete は条件付き操作
• 対応するレコードが存在しないときのみ Insert 可能
• 対応するレコードが存在するときのみ Delete 可能
• ページモデルでの素朴な解釈では Read-modify-write 扱いとなる
• 例
• 初期状態: 𝑥 に対応するレコードが存在
• 𝑡1 = 𝑟1 𝑥 𝑤1(𝑥) 𝑥 に対応するレコードを Delete する操作
• 𝑡2 = 𝑤2(𝑥) Upsert (存在していたら Update、していなかったら Insert)
• 𝑟1 𝑥0 𝑤1(𝑥)𝑤2 𝑥 としてしまうと、𝑡1𝑡2 のみが OK となるが、
本来 𝑡2𝑡1 も OK として問題ないはず
14
- 15. 解決方針: View の抽象化
• View は「Tx の実行を再現するための十分条件」であると再定義する
• 再現性がある(View の一致)とは、再現に必要なデータベース状態の観測結果
が一致すること
• 再現に影響しない観測行為を実際には行っていたとしても View には含まれない
• View serializable は「View が同じ直列実行が存在するような(並行)実行」な
ので、 View の定義があればページモデルに依存せず使える
15
𝑠𝑖−1 𝑠𝑖
𝑡𝑖
状態の観測結果 状態変更の再現
呼び出し側への返り値の再現
呼び出し側からの入力(固定)
- 16. 例1〜3の再解釈
• 例1: Predicate Reads
• 𝑡1: Insert 4
• 𝑡2: Full scan 結果 {1,5}。(再現条件そのもの)
• 𝑡1𝑡2 は、再現のための観測結果({1,4,5})が一致しないので NG (View が一致しない直列実行)
• 例2: 口座間の資金移動
• 𝑠0 = 𝐴: 0, 𝐵: 100
• 𝑡1: 𝐵 から 𝐴 に 10 移動。再現条件は 𝐵 ≥ 10。
• 𝑡2: 𝐵 から 𝐴 に 20 移動。再現条件は 𝐵 ≥ 20。
• 𝑡3: 𝐴 から 𝐵 に 30 移動。再現条件は 𝐴 ≥ 30。
• 𝑡1𝑡2𝑡3 も 𝑡2𝑡1𝑡3 も OK
• 例3: SQL Insert/Delete
• 𝑡1: 𝑥 が存在していたら Delete。再現条件は 𝑥 が存在していること。
• 𝑡2: 𝑥 の Upsert。再現条件ナシ (どんなデータベース状態に対しても必ず実行可能)
• 𝑡1𝑡2 も 𝑡2𝑡1 も OK
16