DBMSは、データの定義・操作、権限、同時実行、障害回復などを管理するソフトウェアです。この章では、ACID・2相コミット・ロック・MVCC・回復処理を役割ごとに整理します。具体的な動作はDBMSや設定で異なります。
DBMSの主な機能
| 機能 | 役割 |
|---|---|
| データ定義 | 表・列・型・制約などを定める |
| データ操作 | 検索・追加・更新・削除などを行う |
| 制御 | 権限やトランザクションの同時実行などを管理する |
| 障害回復 | ログやバックアップなどに基づいて整合した状態へ回復する |
ACIDはトランザクションの特性
| 特性 | 意味 |
|---|---|
| 原子性(Atomicity) | 処理をまとめて確定するか、途中の効果を取り消すかを一つの単位として扱う |
| 一貫性(Consistency) | 正しい制約・業務処理の下で、整合した状態から整合した状態へ移る |
| 独立性/分離性(Isolation) | 同時実行の影響を、採用する分離レベルに従って制御する |
| 永続性(Durability) | 確定した結果を、想定する障害に対して保持する |
ACIDはソフトウェア製品そのものの名前ではありません。分離レベルによって見える現象は異なり、DBMSが業務ルールの誤りまで自動的に直すわけではありません。永続性も、全媒体の同時喪失などあらゆる事象への無条件の保証ではありません。
2相コミットメント制御(2PC)
複数の参加者にまたがる更新について、全体の確定・取消しをそろえるための制御です。コーディネーターと参加者がやり取りします。
- 準備相:各参加者へ準備を求める。参加者はログなど必要な状態を記録し、確定に参加できるかを返す。
- 決定相:全員の準備が整えばコミットを決定し通知する。準備できない参加者がいるなどの場合は、プロトコルに従ってアボートを決定する。
各拠点が全く同時の時刻に確定する、という意味ではありません。準備済みの参加者が最終決定を受け取る前に通信やコーディネーターに障害があると、勝手に取り消せず決定を待つ状態になる場合があります。ロックの長期保持や復旧時の扱いも考える必要があります。
2PCは原子性をそろえるための仕組みで、分離制御などをすべて代わりに行うものではありません。「2相ロック」とも別の用語です。
同時実行で起きる現象
| 現象 | 例 |
|---|---|
| ダーティリード | 他の未コミットの更新を読む |
| ダーティライト | 他の未コミットの更新へ書き重ねる |
| 反復不能読取り | 同じ行を再読すると、他のコミットによる変更が見える |
| ファントムリード | 同じ検索条件を再実行すると、他のコミットで条件に合う行の集合が変わる |
単に「再実行すると結果が変わる」だけでは、どの現象かは決まりません。既存行の値なのか、条件に合う行の集合なのかも確認します。
共有ロックと排他ロック
単純なS/Xロックモデルでは、別トランザクションが同じ対象に取得するロックの互換性を次のように考えます。
| 保持中\新規要求 | 共有S | 排他X |
|---|---|---|
| 共有S | 両立する | 両立しない |
| 排他X | 両立しない | 両立しない |
実際には、行・表などの粒度や追加のロックモードがあります。特にMVCCを使う通常の読取りは、更新中の行の別バージョンを参照できることがあります。「排他ロックがあれば、全DBMSで全ての読取りが禁止される」と一般化しないようにします。SELECT FOR UPDATEなど明示的にロックする読取りも別に考えます。
デッドロック
Aが資源1を保持して資源2を待ち、Bが資源2を保持して資源1を待つような、循環した待ちです。相互排他、保持して待機、横取り不可、循環待機が典型的な必要条件ですが、条件名を並べるだけで特定の実行の発生を断定しません。
取得順序の統一やトランザクションを短くすることなどでリスクを減らし、DBMSの検出・取消し後に適切に再試行します。粒度を細かくするだけで必ず解消するわけではなく、タイムアウトも原因を区別して扱います。
MVCC:複数バージョンで読む
データの複数バージョンを利用し、読取りが参照すべき状態を選ぶ仕組みです。通常の読取りと更新の競合を減らせますが、ロックが完全になくなるわけではありません。更新同士や明示的なロック、DDLなどで待機・失敗が起こる場合があります。
見えるスナップショットが文単位かトランザクション単位かは、製品・分離レベルによって異なります。「常にトランザクション開始時点」と覚えないようにします。古いバージョンを不要になった時点で整理する仕組みも必要です。タイムスタンプ順序付けは別の制御方式で、時刻の順にすべての処理を単純に一列で実行することと同じではありません。
障害回復:取り消す・再適用する
| 用語 | 基本的な役割 |
|---|---|
| ロールバック/UNDO | 未確定のトランザクションなどの効果を取り消す |
| ロールフォワード/REDO | ログなどに基づいて更新を再適用する |
| バックアップからのリストア | 保存済みのデータを戻す |
| WAL | データページを永続領域へ書く前に、必要なログを先に永続化する方式 |
媒体障害ではバックアップと、その後の必要なログを組み合わせる場合があります。クラッシュ回復でどのログを再生し、未確定の効果をどう扱うかはDBMSの回復方式で異なります。常に障害直前まで戻せるとは限らず、利用可能なバックアップ・ログや設定に依存します。
ロールフォワードの注意点
単純な教材モデルでは確定した更新を再現すると説明しますが、実際の回復アルゴリズムでは履歴を再現した後に未完了を取り消すなど、手順が異なる場合もあります。原子性と永続性の両方を、仕組み全体で考えます。
ロールバックの注意点
DBのトランザクションを取り消すことと、データベース全体を任意の過去時点へ復元することは別です。すでに確定した更新を通常のROLLBACKで自由に取り消せるわけではありません。
チェックポイントはコミットではない
回復作業の出発点を進めるため、更新されたページの書出しやログへの記録などを行います。ダーティページはメモリ上で変更され、まだ書き戻されていないページのことで、「未コミットのデータ」と同義ではありません。
チェックポイントは全トランザクションをコミットする操作でも、バックアップの代わりでもありません。必要なログの範囲や、書出しを一度に行うか分散するかは実装に従います。
ストアドプロシージャ
処理をDB側のプログラムとして保存し、呼び出せる仕組みです。複数の操作の共通化や通信回数の削減に役立つ場合がありますが、必ずコンパイル済みで常に高速とは限りません。言語・実行計画・処理内容・権限設定などで結果が変わります。
DB側の負荷や製品依存、テスト・変更管理、実行権限も検討します。ストアドにしただけで安全になるわけではなく、権限と入力処理を適切に設計します。
確認問題:チェックポイントを実行すると、未コミットの取引も確定する?
確定しません。チェックポイントとCOMMITは役割が違います。ダーティページと未コミットも同じ意味ではないことを確認しましょう。
noteでトランザクションの理解を深める
まずACID・同時実行・回復の役割を区別してから、トランザクション教材で復習しましょう。個別製品の運用コマンドは、その製品の仕様で確認します。


コメント