【えむぶいしーしー】
MVCC(多版型同時実行制御) とは?
最終更新:
💡 過去の版を残し、読む人と書く人の待ち合わせを減らす
データの過去の状態を参照できるようにし、読み取りと書き込みの待ち合わせを減らす同時実行制御の仕組み。参照するスナップショットはデータベースや隔離レベルに依存し、更新などではロックも使う。
📌 このページのポイント
- 過去の行やその復元情報を保持し、読み取りに必要な時点の状態を参照できるようにする
- 通常の読み取りと書き込みの競合を減らすが、更新やロック付き読み取りではロックも使う
- 参照する版はデータベースと隔離レベルに依存し、常にトランザクション開始時点ではない
- PostgreSQLやMySQLのInnoDBなどで採用。不要になった過去の情報のクリーンアップが必要
MVCCって何をする仕組みなの?
データの過去の状態を残し、読む人と書く人の待ち合わせを減らす仕組みだよ。図書館で本を書き直している間も、別の人が必要な時点のコピーを読めるイメージ。読み取り側に見せる一貫した状態をスナップショットと呼ぶんだ。
ロックしなくていいってこと?
すべてのロックがなくなるわけではないよ。通常の読み取りは、書き込みの完了を待たずに見える版を読める場合がある。一方、同じ行を更新する処理同士や、SELECT FOR UPDATEのようなロック付きの読み取りでは、ロックを使って待つことがあるんだ。
読むのは、いつのデータなの?
データベースと隔離レベルによるよ。PostgreSQLのRead Committedでは、通常のSELECTは各クエリ開始時点でコミット済みのデータを読むので、同じトランザクション内でも次のクエリで結果が変わりうる。Repeatable Readでは、最初のデータ操作時点のスナップショットを使う。どちらも、自分のトランザクションが行った変更は見えるんだ。
過去の版はどこに保存しているの?
実装によって違うよ。PostgreSQLでは更新前の行をテーブル内に残す。MySQLのInnoDBではUndoログの情報から過去の行を復元できるようにする。どちらも過去の状態を参照するための仕組みだけれど、すべてのデータベースが同じ形で行を丸ごと複製するわけではないんだ。
古いデータがどんどん増えない?
不要になった過去の情報はクリーンアップする必要があるよ。PostgreSQLにはVACUUMと、その実行を自動化するautovacuumがあり、InnoDBには不要な履歴を取り除くpurgeがある。長時間のトランザクションが古い版を必要とする間は、その情報を削除できない場合がある。処理時間や履歴の蓄積を見て運用しよう。
まとめ:ざっくりこれだけ覚えればOK!
「MVCC」って出てきたら「データの過去の状態を参照できるようにして、読み書きの待ち合わせを減らす仕組み」と思えばだいたいOK!
📖 おまけ:英語の意味
「Multi-Version Concurrency Control」 = 多版型同時実行制御
💬 Multiple Versions(複数バージョン)で Concurrency(同時実行)を Control(制御)するという意味だよ