Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ゲームで体感!Aurora DSQL の OCC(楽観的同時実行制御)

ゲームで体感!Aurora DSQL の OCC(楽観的同時実行制御)

JAWS ミート 2025
2025/7/5

Avatar for hmatsu47

hmatsu47

July 05, 2025
Tweet

More Decks by hmatsu47

Other Decks in Technology

Transcript

  1. 自己紹介 松久裕保(@hmatsu47) • https://qiita.com/hmatsu47 • 現在: ◦ 名古屋で Web インフラのお守り係をしています

    ◦ SRE チームに所属しつつ技術検証の支援をしています ◦ 普段カンファレンス・勉強会では DB の話しかしていません (ほぼ) 2
  2. 本日の内容 • Aurora DSQL おさらい ◦ 今年の 5/30 に GA

    ▪ 東京・大阪でシングルリージョン構成をリリース • OCC(楽観的同時実行制御)おさらい ◦ 通常の RDBMS(PCC)との違い • ゲームで確かめよう! • 答え合わせ 3
  3. サーバーレス分散 SQL データベース 5 • PostgreSQL ワイヤープロトコル互換 ◦ psql コマンドが使える

    • シングルリージョン構成とマルチリージョン構成がある ◦ マルチリージョン構成は US 3 リージョン/欧州 3 リージョン/ 東京+大阪+ソウルの組み合わせでサポート ▪ エンドポイントは 2 リージョン、残り 1 つは Witness リージョンで構成
  4. シャーディングを使わずにスケールする…? • 楽観的同時実行制御(OCC)を採用 ◦ 一般の RDBMS は悲観的同時実行制御(PCC)を採用 ▪ ロック機構を使う ◦

    OCC ではロックを使わない ▪ コミット時に他のトランザクションとの更新競合を検知したらアボート ▪ アボート後必要に応じてリトライ処理(アプリケーション側で実装) ◦ ロックしないので他のトランザクションを待たせることがない ▪ ただし更新競合が頻発するとアプリケーションの性能が下がる欠点がある 9
  5. トランザクション A トランザクション B テーブル X の id = 1

    の行 (コミット済み) 開始(BEGIN) 10(初期値) 開始(BEGIN) テーブル X の id = 1 の値を +1 →id = 1 の行ロック獲得成功 (11) (別の処理を実行) テーブル X の id = 1 の値を +1 →id = 1 の行ロック獲得待ち コミット(COMMIT)→成功 (↑行ロック獲得待ち) 11 id = 1 の行ロック獲得成功 (12) (別の処理を実行) コミット(COMMIT)→成功 12 例 [1] 通常の RDBMS(PCC / READ COMMITTED) 10
  6. トランザクション A トランザクション B テーブル X の id = 1

    の行 (コミット済み) 開始(BEGIN) 10(初期値) 開始(BEGIN) テーブル X の id = 1 の値を +1 →id = 1 の行 : 11 (別の処理を実行) テーブル X の id = 1 の値を +1 →id = 1 の行 : 11 コミット(COMMIT)→成功 (別の処理を実行) 11 コミット(COMMIT) →失敗・アボート 例 [2] Aurora DSQL(OCC / SNAPSHOT ISOLATION) 11 必要ならリトライする
  7. トランザクション A トランザクション B テーブル X の id = 1

    の行 (コミット済み) 開始(BEGIN) 10(初期値) 開始(BEGIN) テーブル X の id = 1 の値を +1 →id = 1 の行 : 11 (別の処理を実行) テーブル X の id = 1 の値を +1 →id = 1 の行 : 11 コミット(COMMIT)→?? ?? コミット(COMMIT)→?? ?? さて問題です 12 成功するのはどっち? どちらかの タイミングで 11 に
  8. 「最後にコミットした人が勝ち!」ゲーム • https://dsql.hmatsu47.nagoya/ または • https://bit.ly/4nxEYrw • 2. ゲームが始まったら制限時間内に攻撃ボタンを押す ◦

    押すと DSQL 上のテーブル行を UPDATE → 1 秒待つ→ COMMIT ◦ 同時に複数の人が攻撃した場合、COMMIT が成功した人が勝ち ▪ 勝つと UPDATE → COMMIT の待ち時間が 1 秒増える(最大 5 秒まで) ▪ 負けると 1 秒にリセット 15
  9. 「最後にコミットした人が勝ち!」ゲーム • https://dsql.hmatsu47.nagoya/ または • https://bit.ly/4nxEYrw • 3. 攻撃ボタンは時間内に何度押しても OK

    • 4. 制限時間内で一番最後に COMMIT した人が優勝! ◦ ボタンを押した後の COMMIT が制限時間外なら攻撃失敗 16
  10. トランザクション A トランザクション B テーブル X の id = 1

    の行 (コミット済み) 開始(BEGIN) 10(初期値) 開始(BEGIN) テーブル X の id = 1 の値を +1 →id = 1 の行 : 11 (別の処理を実行) テーブル X の id = 1 の値を +1 →id = 1 の行 : 11 コミット(COMMIT)→?? ?? コミット(COMMIT)→?? ?? もうお分かりですね? 18 成功するのはどっち? どちらかの タイミングで 11 に
  11. トランザクション A トランザクション B テーブル X の id = 1

    の行 (コミット済み) 開始(BEGIN) 10(初期値) 開始(BEGIN) テーブル X の id = 1 の値を +1 →id = 1 の行 : 11 (別の処理を実行) テーブル X の id = 1 の値を +1 →id = 1 の行 : 11 コミット(COMMIT)→成功 11 コミット(COMMIT)→失敗 答え 19 成功するのは B!(コミットまでの所要時間が長いトランザクションが不利) こちらの タイミングで 11 に
  12. トランザクション A トランザクション B テーブル X の id = 1

    の行 (コミット済み) 開始(BEGIN) 10(初期値) 開始(BEGIN) テーブル X の id = 1 の値を +1 →id = 1 の行 : 11 (別の処理を実行) テーブル X の id = 1 の値を +1 →id = 1 の行 : 11 コミット(COMMIT)→成功 11 コミット(COMMIT)→失敗 答え 20 成功するのは B!(コミットまでの所要時間が長いトランザクションが不利) こちらの タイミングで 11 に 最初の更新から コミットまでの 所要時間の長さ
  13. ロックしないので 21 「BEGIN / UPDATE が A のほうが先だから」という理由で A を優先するのであれば、

    B はここで失敗することになる(A のコミットを待たずに B を失敗させるしかない) トランザクション A トランザクション B テーブル X の id = 1 の行 (コミット済み) 開始(BEGIN) 10(初期値) 開始(BEGIN) テーブル X の id = 1 の値を +1 →id = 1 の行 : 11 (別の処理を実行) テーブル X の id = 1 の値を +1 →id = 1 の行 : 11 コミット(COMMIT)→成功 11 コミット(COMMIT)→失敗
  14. ところが 22 A のコミットを待たないのに B が失敗するのであれば、後でコミットした A が 何らかの理由で失敗した場合、結果的に A

    も B も失敗することになる→ TPS 低下 トランザクション A トランザクション B テーブル X の id = 1 の行 (コミット済み) 開始(BEGIN) 10(初期値) 開始(BEGIN) テーブル X の id = 1 の値を +1 →id = 1 の行 : 11 (別の処理を実行) テーブル X の id = 1 の値を +1 →id = 1 の行 : 11 コミット(COMMIT)→成功 11 コミット(COMMIT)→失敗
  15. トランザクション A トランザクション B テーブル X の id = 1

    の行 (コミット済み) 開始(BEGIN) 10(初期値) 開始(BEGIN) テーブル X の id = 1 の値を +1 →id = 1 の行 : 11 (別の処理を実行) テーブル X の id = 1 の値を +1 →id = 1 の行 : 11 コミット(COMMIT)→成功 11 コミット(COMMIT)→失敗 一方で、トランザクションの一貫性を保つには 23 B も A も成功なら最終的に値が 12 になる必要があるがそうならない
  16. つまり • 先に COMMIT した者勝ち! ◦ 先に BEGIN しても INSERT

    / UPDATE しても関係なし ◦ 結果として無用な待ち時間が発生せず、一貫性も保たれる 24