0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DB(データベース)のMVCCとロックベースについて

Last updated at Posted at 2025-12-30

1. MVCC、ロックベースとは

MVCC(Multi-Version Concurrency Control, 多版本並行制御) は「読み取りは過去バージョンを参照することでロックを不要にする方式」です。SELECT文等の参照では過去バージョンを読むことでロック競合を避けます。
MVCCを採用している代表的なデータベースはOracle, PostgreSQL, MySQL等があります。

ロックベース(Two-Phase Locking; 2PL, 二相ロック方式) は「読み取りと更新と共に必ずロックを取得し、コミットまで保持する」方式です。ロックで整合性を保持します。
ロックベースを採用している代表的なデータベースはHiRDB, DB2, SQL Server(既定モード)等があります。

SQL Serverは既定モードではロックベースですが、設定を変更してMVCCとすることもできます。

2. MVCC と ロックベースの違い

MVCCロックベース の主な違いは以下の通りです。

2.1. 読み取りの扱いの違い

  • MVCC
    • SELECT はロックを取らない
    • Undo や行バージョンを参照して「過去の一貫した状態」を読む
    • 読み取りと更新が競合しない
       
  • ロックベース
    • SELECT でも共有ロックを取得
    • 更新は共有ロックと競合する
    • 読み取りと更新がブロックし合う

2.2. 更新の違い

  • MVCC
    • 更新すると「新しいバージョン」を作る
    • 古いバージョンは他トランザクションのために残す
       
  • ロックベース
    • 更新対象の行に排他ロックを取得
    • コミットまで他トランザクションはその行を読めない

2.3. 並行性(スケーラビリティ)

  • MVCC
    • 読み取りと書き込みが干渉しないため並行性が高い
    • 高負荷 OLTP に強い
  • ロックベース
    • 読み取りと書き込みが競合するため並行性が低い
    • ロック待ち・デッドロックが発生しやすい

2.4. 一貫性の保証方法

  • MVCC
    • スナップショットで一貫性を保証
    • 分離レベルによっては「読み取りの揺れ」が起きる(READ COMMITTED など)
       
  • ロックベース
    • ロックで厳密に整合性を保証
    • 読み取りの揺れは起きないが、ロック待ちが増える

2.5. まとめ( MVCCとロックベースの違い)

観点 MVCC ロックベース
SELECTのロック 取らない 共有ロックを取る
読み取りと更新の競合 しない する
更新方式 新バージョン作成 排他ロックで更新
並行性 高い 低い
読み取りの一貫性 Undo/スナップショット依存 ロック依存
ダーティーリード 原則不可 分離レベル次第
デッドロック 少ない 多い
向いている用途 高並行 OLTP 厳密整合性が必要な処理

3. 主なMVCC型DBの違い

主なMVCC型のDBである OraclePostgreSQLMySQL (InnoDB) の特徴は以下の通りです。

DB MVCCの実装方式 可視性判定の仕組み 特徴・課題
Oracle Undoセグメント方式 Undoに保存された過去イメージを参照 SELECTは常にUndoから一貫性読み取り。Undo管理が複雑で、長時間トランザクションでUndo肥大化の課題あり。
PostgreSQL 行バージョン(Tuple)方式 xmin/xmaxフィールド+スナップショット 更新は新しい行を挿入し、旧行に削除マーク。不要バージョンはVACUUMで回収。シンプルだがVACUUM負荷やXIDラップアラウンド問題が課題。
MySQL (InnoDB) Undoログ+Gap Lockのハイブリッド方式 Undoログ+ReadView+Gap Lock Undoで過去バージョンを参照しつつ、Gap Lockで範囲挿入を制御。ファントムリードを物理的に防ぐが、Gap Lockによる競合が増える場合あり。
  • 共通点:読み取りはロックを取らず、過去バージョンを参照する
  • 違い:Undo依存か、行バージョン依存か、Gap Lockを併用するか、の違いがある

4. 主なロックベース型DBの違い

主なロックベース型のDBである HiRDBDB2SQL Server の特徴は以下の通りです。

DB ロック方式 分離レベル対応 特徴・課題
HiRDB 強制ロック方式 READ UNCOMMITTEDなし SELECTでも共有ロック必須。基本的にダーティーリード不可(例外あり)。整合性最優先だが並行性は低め。
DB2 標準的な2PL(二相ロック) SQL標準の4分離レベルすべて対応 READ UNCOMMITTEDも選択可能。ロック粒度は行/ページ/テーブル。柔軟性が高い。
SQL Server 2PL+オプションMVCC デフォルトはREAD COMMITTED(ロックベース) RCSIやSnapshot Isolationを有効化するとMVCC風に動作。並行性と整合性のバランスを選べる。
  • 共通点:ロックで整合性を保証する
  • 違い:HiRDBは常に強制ロック、DB2は柔軟、SQL Serverはロック+MVCCを選べる

5. Oracle、PostgreSQL、MySQL(InnoDB)、HiRDB、DB2、SQL Serverの違い(まとめ)

  • MVCC型 は「読み取りは過去バージョンを参照」するが、実装方式が違う
    • Oracle:Undo依存
    • PostgreSQL:行バージョン依存
    • MySQL(InnoDB):Undo+Gap Lockのハイブリッド

 

  • ロックベース型 は「ロックで整合性を保証」するが、制御の強さが違う
    • HiRDB:常に強制ロック、整合性最優先
    • DB2:標準的な2PL、柔軟に分離レベル選択可能
    • SQL Server:ロックベースだがMVCCも選べる

 

  • MVCCは並行性を重視しつつ方式が分かれる。
  • ロックベースは整合性を重視しつつ制御の強さが分かれる。

6. MVCC型のOracleとロックテーブル型のHiRDBのSELECT文の違い

  • OracleSELECT(MVCC方式)
    • 基本挙動
      • SELECTはロックを取得しない
      • 過去のスナップショット(Undoセグメント)を参照して一貫性を保つ
      • 他トランザクションが更新中でも、コミット済みの過去バージョンを読むためブロックされない
    • 結果
      • 読み取りと更新が競合しない → 高並行性
      • ダーティーリードは起きない(未コミットデータは見えない)
      • ただし分離レベルがREAD COMMITTEDだと「非再現読み取り」「ファントムリード」は起き得る
         
  • HiRDBSELECT(ロックベース方式)
    • 基本挙動
      • SELECTはデフォルトでWITH SHARE LOCKが仮定さる
      • 検索した行に共有ロックがかかり、他トランザクションは更新できない
      • WITHOUT LOCKを指定すればロックを取らずに参照できるが、更新中の行は待機となる(または未コミット読み取りが発生する)
    • 結果
      • 読み取りと更新が競合する → 並行性は低い
      • 基本的にダーティーリードは起きないが、共有ロックをかけないと起きる場合もある
      • 整合性は強いが、ロック待ちやデッドロックが発生しやすい

HiRDBのSELECT文で、ロックを取得しない場合、WITHOUT LOCKを付与します。
WITHOUT LOCK NOWAITを付与すると、対象行が他トランザクションで更新中(排他ロック中)の場合は、未コミット読み取り(ダーティリード相当)が発生する可能性があります。
WITHOUT LOCK WAITを付与すると、対象行が他トランザクションで更新中(排他ロック中)の場合は、更新が終わるまで待機してから参照します。
OracleではUndo領域からコミット済みの過去バージョンを読むためエラーや待ちが発生せずに読むことができます。

 

観点 Oracle (MVCC) HiRDB (ロックベース)
SELECT時のロック 取得しない デフォルトで共有ロック
未コミットデータ参照 不可(Undoで防止) 不可(共有ロックで防止)
読み取りと更新の競合 しない する
ダーティーリード 起きない 起きない(ロックで防止)
非再現読み取り 起き得る(READ COMMITTEDの場合) 起きない(ロックで防止)
ファントムリード 起き得る(READ COMMITTEDの場合) 起きない(ロックで防止)
並行性 高い 低い
  • Oracle:SELECTはロックを取らず、Undoで過去バージョンを読む → 並行性が高いが読み取りの揺れは起き得る
    • Oracleは「並行性重視
       
  • HiRDB:SELECTはデフォルトで共有ロック → 並行性は低いが読み取りの揺れは起きない
    • HiRDBは「整合性重視

以上

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?