【入門編】 デッドロック検出器 – PostgreSQL

こんにちは!世界最高峰(自称ですけど、あながち間違いでもないんですよ?)のデータベースエンジニア、そして人気技術ブログ「DBの心臓」を運営している私です。いつも読んでくれてありがとうございます!

データベースって、私たちの生活のいろんなところで活躍している、まるで縁の下の力持ちみたいな存在ですよね。通販サイトの注文履歴も、銀行の残高も、SNSの投稿も、ぜーんぶデータベースがしっかり守ってくれています。

そんな頼れるデータベースですが、たまーに、ちょっと困った状況に陥ることがあるんです。それが今日お話しする「デッドロック」という現象。名前だけ聞くと、なんだか物々しいですよね。「ロックされた死」なんて聞くと、ちょっと怖いかも?でもご安心ください。PostgreSQLには、このデッドロックという困った状況をしっかり見つけて、解決してくれる「デッドロック検出器」という、とっても賢い仕組みがあるんです。

今日は、この「デッドロック検出器」がどんなものなのか、IT初心者さんや初めてデータベースに触れる方にもわかるように、日常の出来事に例えながら、優しくひも解いていきましょう!

—

デッドロックって、いったい何者? ── 譲り合えない状況

まず、「デッドロック」がどんな状態なのか、想像してみましょう。

例えば、あなたが友人と二人で、おもちゃで遊んでいるとします。
手元には、赤いブロックと青いブロックが一つずつ。

1. あなた:「よし、まず赤いブロックを使って、秘密基地の土台を作ろう!」と、赤いブロックを手に取ります。
2. 友人:「じゃあ僕は青いブロックで、屋根を作るね!」と、青いブロックを手に取ります。

ここまでは順調ですよね。

ところが、もし秘密基地を作るためには、途中で「赤いブロック」と「青いブロック」の両方が必要になったとしたらどうでしょう?

  • あなた:「あ、屋根を作るには青いブロックが必要だ。友人が持ってるから、返してくれるまで待とう…」
  • 友人:「おっと、土台を作るには赤いブロックが必要だ。あなたが持ってるから、返してくれるまで待とう…」

…どうでしょう?あなたも友人も、相手が持っているブロックを待っているので、お互い一歩も動けなくなってしまいましたよね?
これが、まさにデッドロックなんです!

データベースの世界では、この「ブロックを手に取る」という行為が「データのロック(鍵をかける)」に当たります。誰かが使っているデータには、他の人が勝手に変更を加えないように、一時的に鍵をかけるんですね。そうしないと、例えば「残高照会中に引き落としがあったら、数字が合わなくなっちゃう!」なんてことになりかねませんから。

そして、「お互いに相手の持っているものを待って身動きが取れない状態」が、デッドロックの核心です。

—

PostgreSQLのデッドロック検出器、ここがすごい! ── 賢い交通整理員さん

さて、先ほどの例だと、あなたたち二人はいつまでも動けず、秘密基地は永遠に完成しませんよね。困りました。

そこで登場するのが、PostgreSQLの「デッドロック検出器」です!
これは、例えるなら、賢い交通整理のお巡りさんみたいな存在だと思ってください。

このお巡りさんは、常に交通の状況をじーっと見ています。

  • 「あ、あの車は今、あの交差点で止まって、別の方向から来る車を待っているな」
  • 「ん?そっちの車も、あっちの車が動くのを待っているぞ?」

こんな風に、「誰が、何を使っていて、誰が、何を待っているのか」という関係を、まるで地図に書き込むように常に把握しているんです。専門用語で「ロック待ちグラフを解析している」なんて言ったりしますが、要するに、その関係図をしっかり見ているってことですね。

そして、その地図の中に、「お互いに相手を待っていて、一歩も進めないループ(循環参照)」を見つけたら、それがデッドロック!と即座に判断するわけです。

「あ、これはもう誰かが諦めないと、永遠に動けないパターンだ!」と、お巡りさんはすぐに気づいてくれるんです。すごいですよね!

—

見つけたらどうするの? ── 痛み分けで解決!

デッドロックを発見したら、この賢いお巡りさんはどうするのでしょう?
はい、ここがポイントです。そのままでは誰も動けないので、どちらか一方に「ごめんね、一旦諦めてもらえないかな?」とお願いするんです。

データベースの世界では、この「諦めてもらう」ことを「トランザクションを強制終了させる」と言います。
先ほどの例だと、あなたか友人のどちらか一方に「ごめん、一旦ブロックを戻して、最初からやり直そうか?」とお願いするイメージです。

「え、なんで片方だけ?」と思うかもしれませんね。
全員が止まっている状況では、何も進みません。そこで、どちらか一人に犠牲になってもらうことで、もう一方が先に進めるようになり、結果的に全体の滞りを解消する、という考え方なんです。

PostgreSQLは、どちらを強制終了させるかについても、ちゃんと考えてくれます。例えば、「先に処理を始めた方を優先しよう」「後から来た方にごめんねしよう」とか、「影響が少ない方を選ぼう」といった賢い判断基準を持っています。これによって、デッドロックが起きた時のシステムへの影響を最小限に抑えようと努力してくれるんですね。

強制終了された側の処理は、残念ながら「失敗」として扱われますが、ほとんどの場合、アプリケーション側で「もう一度やり直してみよう」と自動的に再試行されるので、ユーザーが気づかないうちにデッドロックは解決されている、なんてことも多いんですよ。

—

デッドロックを避けるには? ── ちょっとした心がけ

PostgreSQLのデッドロック検出器はとっても優秀ですが、そもそもデッドロックが起きないように工夫することも大切です。

例えば、先ほどのおもちゃの例で言うと…

  • ものを取る順番を決めておく: 「まず赤、次に青」とルールを決めておけば、お互いに待つことはありませんよね。
  • 一度にたくさんのものを持たない: 必要なブロックだけを最小限で持つようにすれば、他の人が使いたいブロックを独占せずに済みます。

データベースの世界でも、

  • SQLの実行順序を揃える: 複数のテーブルを更新する際に、常に同じ順番で更新するようにする。
  • ロックする範囲を最小限に: 必要なデータだけをロックし、ロックする時間を短くする。

といった工夫で、デッドロックの発生頻度を減らすことができます。

—

まとめ ── 頼れる守護神!

今日は、PostgreSQLの「デッドロック検出器」について、日常の例を交えながらお話ししてきました。

  • デッドロックとは、お互いに相手が使っているものを待ってしまい、身動きが取れなくなる状態のこと。
  • PostgreSQLのデッドロック検出器は、この困った状況を常に監視し、「誰が何を待っているか」の関係図の中から、行き詰まりのループを発見する賢い交通整理員さん。
  • 見つけたら、どちらか一方の処理に「ごめんね、一旦やり直してね」とお願いすることで、全体の滞りを解消してくれる。

PostgreSQLは、ただデータを保存するだけでなく、こういった複雑な状況にもしっかり対応してくれる、本当に頼れるデータベースなんです。普段私たちが意識しないところで、こんなにも賢い仕組みが動いているって、なんだかワクワクしますよね!

もし、あなたがデータベースの勉強を始めたばかりなら、デッドロック検出器のような「縁の下の力持ち」的な機能にも目を向けてみると、きっとデータベースの世界がもっと面白く、奥深く感じられるはずです。

これからも、データベースの「なんで?」「どうなってるの?」を、もっともっと楽しく、わかりやすくお伝えしていきますので、どうぞお楽しみに!また次の記事でお会いしましょう!

コメント

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