【入門編】 MVCC可視性判定ルール – PostgreSQL

こんにちは!データベースの世界へようこそ。

PostgreSQLを触っていると、「MVCC(多版同時実行制御)」という、いかにも難しそうな言葉に出会ったことはありませんか?「読み書きが衝突しない魔法の仕組み」なんて呼ばれることもありますが、中身を紐解くと、実はとっても人間味のあるルールで動いているんです。

今回は、PostgreSQLが「このデータ、今の私に見せていいかな?」と判断する、その裏側の仕組みをこっそり覗いてみましょう。

—

データの「名札」を読み解こう

PostgreSQLの中に保存されているデータ(タプル)には、私たちには見えない「隠れた名札」がついています。これが、データの運命を握る重要な情報です。

  • xmin: このデータが「生まれた(作成された)」時のトランザクションID
  • xmax: このデータが「消えた(削除された)」時のトランザクションID

この2つの数字が、データベースにとっての「戸籍」のような役割を果たしています。

—

混雑したカフェでの出来事:スナップショットの正体

想像してみてください。あなたは今、大人気のカフェに並んでいます。
お店の店員さんは、あなたが注文する瞬間に「スナップショット」という魔法のカメラで店内の様子をパシャリと撮影します。

この写真に写っている範囲でしか、あなたは「メニュー」を見ることができません。これがPostgreSQLの「トランザクション分離レベル」の仕組みです。

あなたがカメラのシャッターを切った(トランザクションを開始した)その瞬間、あなたはこんな風に判断します。

  • 「あ、このメニュー(データ)、私が来る前に置かれていたんだな(xminが今のIDより小さい)」

→ よし、見てもいいよね!

  • 「あれ、このメニュー、まだ準備中みたいだ(xminが未来のID)」

→ まだ見ちゃダメだ。

  • 「おっと、このメニューはもう片付けられちゃったんだね(xmaxに数字が入っている)」

→ 私が来た時にはもうないから、見えないフリをしよう。

—

判定のアルゴリズム:意外とシンプルなルール

PostgreSQLがデータを表示するかどうかを決めるとき、内部ではこんな会話が行われています。

1. 「生まれたのはいつ?」
自分のトランザクションIDより前に生まれたデータなら、基本的には「見てもOK」です。
2. 「死んだ(削除された)のはいつ?」
もし`xmax`に数字が入っていたら、それは「削除済み」を意味します。でも、その削除処理が「まだ実行中(未確定)」だとしたら? PostgreSQLは「おっと、まだ片付け中だから、とりあえず今は見えることにしておこう」と判断します。これが、データベースの「一貫性」を保つ秘訣なんです。

—

なぜこんな面倒なことをしているの?

「そのまま書き換えちゃえばいいじゃん!」と思うかもしれませんよね。でも、もし書き換えてしまったら、他の人が「あれ?さっきまであったはずのメニューがない!」とパニックになってしまいます。

だからPostgreSQLは、古いデータをこっそり残しておいて、新しいデータと並行して置いておくという贅沢な方法をとっているんです。これを「多版(Multi-Version)」と呼びます。

スペースは少し使っちゃうけれど、そのおかげで私たちは「読み込み」と「書き込み」を同時に行っても、お互いの邪魔をせずにスムーズにお仕事ができるんですね。

—

最後に:データベースは「記憶の積み重ね」

こうして見てみると、PostgreSQLがやっていることって、実は私たちの日常と同じなんです。

過去の記録(xmin)を大切にし、終わったこと(xmax)を整理し、今この瞬間の自分に見えるものだけを丁寧に選別する。この地道な積み重ねが、私たちが普段何気なく使っている「安全なデータベース」を支えています。

次に`SELECT`文を叩くとき、裏側で一生懸命「このデータ、見せていいかな?」と名札をチェックしているPostgreSQLの姿を、少しだけ想像してみてください。きっと、今までよりもっと、データベースが愛おしく感じられるはずですよ。

それでは、また次回のブログでお会いしましょう!Happy Querying!

コメント

タイトルとURLをコピーしました