データベースの「コミット」とは何か?ログバッファと揮発性の問題をわかりやすく整理してみた
はじめに
「コミットってなに?SQLのCOMMIT
と内部処理のコミットって違うの?」
「ログバッファって消えたらヤバいやつ?」
「更新情報がメモリにしかない状態で電源が落ちたらどうなる?」
読書中にこんな疑問が出てきました。
この記事では、DBMSのログバッファ、ログファイル、コミット、そしてそれにまつわるトレードオフについて、記事として残します。
データベースにおける「コミット」とは?
まずSQLでのCOMMIT
文の使い方を思い出してみましょう。
BEGIN;
UPDATE users SET name = 'Taro' WHERE id = 1;
COMMIT;
このCOMMIT
文は、「ここまでの変更を確定してね」という意味です。
でもDBMS内部ではこのとき、ある重要な処理が走っています。
コミットの裏で何が起きているのか?
SQLのCOMMIT
を受け取ったDBMSは、次のようなステップを踏みます:
- ユーザーの更新操作をログバッファ(メモリ)に記録
-
COMMIT
時にそのログをログファイル(ディスク)に書き込む - 書き込みが完了したら「コミット成功」とみなしてOKを返す
ポイントは「ログがディスクに書かれるまでは、更新は“未確定”」 ということです。
ログバッファ vs ログファイル:何が違うの?
名前 | 保存場所 | 性質 | 消える? |
---|---|---|---|
ログバッファ | メモリ | 一時的 | 障害で消える |
ログファイル | ディスク | 永続的 | 基本消えない |
揮発性の問題:ログバッファだけに情報があると?
ここが今回の本題。
たとえばこんな状況を想像してみてください:
- ユーザーがデータを更新 → ログバッファに記録される
- まだ
COMMIT
していない - そのタイミングで電源断(DBMSダウン)
このとき、ログバッファはメモリなので全部消えます。
つまり、更新情報も消えます。
結果、DBMSが復旧しても「更新はなかった」ことになってしまうんです。
なぜ「コミット時にログをディスクに書く」のか?
この揮発性の問題を防ぐため、DBMSは次のようにルールを設けています:
-
COMMIT
時に、ログバッファの内容を必ずログファイルに書き込む - 書き込み完了を確認してから、ようやく「コミット完了」
この処理があるからこそ、障害が起きても更新履歴が残っていて復旧できるのです。
トレードオフ:安全性 vs パフォーマンス
ここで出てくるのがディスク書き込みのタイミングによるトレードオフです。
優先するもの | 方法 | メリット | デメリット |
---|---|---|---|
安全性 |
COMMIT 時にログを即ディスクへ(同期) |
データ損失なし | 書き込みが遅くなる |
パフォーマンス | ログは後でまとめて書く(非同期) | 書き込みが速い | 障害時にログが失われる可能性 |
まとめ
-
COMMIT
は、SQL文だけでなくDBMS内部の“永続化処理”の確定でもある - ログバッファは揮発性(メモリ)なので、障害時に消える可能性がある
- だからこそ
COMMIT
時にディスクに書き込む設計が重要 - 安全性とパフォーマンスにはトレードオフが
最後に
DBMSの内部動作を知ると、何気なく使っているSQLにも深みが出てきますよね。
おしまい。