db tech showcase に参加しました。オンライン開催。簡単に所感をまとめます。
所感
Twitter に流れてきたのをたまたま見つけて参加しました。とは言っても最終日の1セッションのみ。今後、Cloud Spanner を使う予定なので。
前に見つけたこちらの記事では、Cloud Spanner には SELECT FOR UPDATE がないような感じで書かれてましたが、どうやら LOCK_SCANNED_RANGES=exclusive
というヒント句がありそう。
ただし、ヒント句なので必ず排他ロックされるわけではない模様。このあたりはイマイチ理解できてないのでもう少し調べたい。(ヒント句なのでっていうところがよく分かってない)
ただ、Cloud Spanner のクライアントライブラリには abort したときにでリトライする仕組みがあるようで、排他ロックじゃなくても abort + リトライ でいいのかなと思いました。たぶん。
あと、リトライの仕組みでは、クライアント側のコードブロックごとリトライされるようです。なので、冪等でない処理はリトライ対象のコードに含めない方がいいとのこと。なるほど。
今回の話を聴いて、Cloud Spanner は SERIALIZABLE なのでわりと考え方としてはシンプルな感じがしたけど、SQL を書いたりレビューする際には特にロックについてかなり意識する必要がありそうな気がしました。ロックの粒度がセル単位ということもあり、いかに不要なロックを取らないかがポイントかもしれない。
以下、メモから抜粋。
分散データベース Cloud Spanner のトランザクションの仕組み
- 可用性に特化している
- 1ノードであっても冗長化される
- デフォルトで3ゾーンに冗長化される
- ダウンタイムなしでノード削除可
- マルチリージョンで冗長可
- リージョンごとに act/standby ではない
- 分散ストレージ (Colossus)
- 自動シャーディング
- スプリットごと
- SQL
- Google 標準 SQL
- PostgreSQL
- NoSQL の上に SQL レイヤーを構築している
- ACID トランザクション
- 分離レベルが下がると異常 (Anomaly) が起こる
- Phantom Read を許容するかどうか
- Write Skew
- 原子時計のタイムスタンプでコミット順序を判断している
- Lost Update は起こらない
- Lost Update を引き起こす更新は abort する
- ヒント句で排他ロックを取るのは可
- LOCK_SCANNED_RANGES=exclusive
- Write Skew は起こらない
- トランザクションの追い越しは禁止
- External Consistency (外部整合性)
- Serializable より強い
- 発生したイベントは実時間ベースの順序でコミットしたい
- abort は自動リトライする
- クライアントのコードブロックごとリトライする
- 冪等ではない処理はリトライ対象のコードに含めない
- セルロック
- 同じ行であっても異なる列の更新は衝突しない
- 代表的なロック3種類
- ReaderShared
- UPDATE の WHERE 句も ReaderShared ロックの対象に含まれる
- WriterShared
- SQL実行時ではなくコミット時にロックを取る
- Exclusive
- WriterShared + ReaderShared と同等
- ReaderShared
- トランザクション統計テーブル
_exists
はレコードの存在チェックのための隠しカラム
- 読み込みだけなら読み取り専用トランザクションを使う
- readonly transaction
- ロックを取得しない
- トランザクション内で不要なロックは避ける
- ロックの対象はセル単位
- SELECT 対象の列は絞る (
SELECT * FROM ...
にしない)
- SELECT 対象の列は絞る (
- transaction tag