Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Transactions, Deadlocks & Log-Based Recovery in MySQL

2025年10月04日に「Dev.to」が公開したITニュース「Transactions, Deadlocks & Log-Based Recovery in MySQL」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

MySQLでは、トランザクションが処理の完全実行か取り消しを保証する。複数の処理が互いにロックを待つデッドロックはMySQLが検出し解決。ログを使ったリカバリで、障害時もデータの一貫性を保つ仕組みを学ぶ。

ITニュース解説

データベースは、現代のあらゆる情報システムにおいて、データの保存、管理、そして取り出しを行うための中心的な役割を担っている。特に、MySQLは世界中で広く利用されているリレーショナルデータベース管理システムであり、その信頼性と性能の高さから、多岐にわたるアプリケーションの基盤として機能している。システムエンジニアを目指す上で、このようなデータベースがどのようにしてデータの正確性を保ち、予期せぬ障害から回復するのかを理解することは極めて重要となる。この記事では、MySQLが提供する重要な機能である「トランザクション」「デッドロック対策」「ログベースリカバリ」について、それぞれの概念と具体的な動作を解説する。

まず、「トランザクション」とは、データベースに対して行われる一連の操作を、全体として一つのまとまり、すなわち不可分な単位として扱う仕組みを指す。例えば、銀行口座から別口座へお金を送金する処理を考えてみよう。この処理は、「送金元口座の残高を減らす」と「送金先口座の残高を増やす」という二つの操作で構成される。もし、送金元口座から金額を減らした直後にシステムがクラッシュし、送金先口座への増額処理が完了しなかったら、お金が消滅したかのような不整合な状態が発生してしまう。このようなデータの矛盾を防ぐために、トランザクションは不可欠である。

トランザクションには「アトミック性(Atomicity)」という特性があり、これは「全て実行されるか、全く実行されないか」を保証する。つまり、送金の例であれば、二つの操作がどちらも成功して変更が確定するか、あるいはどちらも失敗して元の状態に戻るかのどちらかであり、中途半端な状態でデータが不整合になることはない。MySQLでトランザクションを開始するにはSTART TRANSACTION文を使用する。一連の操作が全て成功し、変更を確定させたい場合はCOMMITを実行する。逆に、途中で問題が発生したり、処理を取り消したい場合はROLLBACKを実行する。ROLLBACKは、トランザクション開始時点のデータベースの状態に全ての変更を戻す役割を担う。

記事の例では、Aliceの口座からBobの口座へ500の金額を送金する処理がシミュレートされている。UPDATE Accounts SET balance = balance - 500 WHERE name = 'Alice';UPDATE Accounts SET balance = balance + 500 WHERE name = 'Bob';という二つの更新文が実行されるが、その後すぐにROLLBACKが実行される。結果として、SELECT * FROM Accounts;で残高を確認すると、AliceとBobの口座残高は送金前の状態、それぞれ1000と1500に戻っている。これは、トランザクションのアトミック性が保証され、ROLLBACKによって未確定の変更が完全に元に戻されたことを示している。

次に、「デッドロック」について説明する。データベースでは、複数のユーザーやアプリケーションが同時に同じデータを更新しようとすることが頻繁に起こる。このとき、データの整合性を保つために、更新対象のデータには一時的に「ロック」がかかる。ロックとは、他のトランザクションがそのデータを変更できないようにする仕組みである。デッドロックは、複数のトランザクションが互いに相手がロックしているリソース(データ)の解放を待ち続け、結果としてどのトランザクションも処理を進められなくなる状態を指す。これは、相互に譲り合わない二台の車が狭い道で鉢合わせ、どちらも動けなくなるような状況に似ている。

記事の例では、二つの異なるセッション(独立したデータベース接続)を使ってデッドロックをシミュレートしている。 セッション1は、まずSELECT * FROM Accounts WHERE name='Alice' FOR UPDATE;を実行し、Aliceの口座データをロックする。その後、UPDATE Accounts SET balance = balance + 10 WHERE name='Bob';でBobの口座を更新しようとする。 一方、セッション2は、セッション1とは逆の順序で処理を進める。まずSELECT * FROM Accounts WHERE name='Bob' FOR UPDATE;を実行し、Bobの口座データをロックする。その後、UPDATE Accounts SET balance = balance + 20 WHERE name='Alice';でAliceの口座を更新しようとする。 この状況では、セッション1はAliceをロックし、Bobのロックが解除されるのを待つ。同時にセッション2はBobをロックし、Aliceのロックが解除されるのを待つ。このように互いに相手がロックしているデータを待つ状態になり、デッドロックが発生する。

MySQLは、このようなデッドロックを自動的に検出し、どちらか一方のトランザクションを強制的に終了させることでデッドロックを解消する。これにより、システム全体が停止するのを防ぎ、残りのトランザクションは処理を続行できるようになる。終了させられたトランザクションにはERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transactionというエラーメッセージが返され、処理を再試行するよう促される。システムエンジニアは、デッドロックが発生しにくいようにトランザクションの処理順序やロックの範囲を考慮して設計するスキルも求められる。

最後に、「ログベースリカバリ」について解説する。MySQLのような信頼性の高いデータベースシステムでは、システム障害やクラッシュが発生しても、保存されているデータが失われたり、不整合な状態になったりしないように回復するメカニズムが備わっている。その鍵となるのが「ログ」である。MySQLは、全てのデータ変更操作を記録した「バイナリログ(redo log)」と、トランザクションのロールバックに使用される「アンドゥログ(undo log)」という二種類のログを主要なものとして利用する。

バイナリログ(redo log)は、データベースに対する全ての変更操作を記録し、たとえシステムが予期せずクラッシュしても、そこまでの変更内容を再現してデータベースを最新の状態に復元できるようにする。これは、変更がディスクに書き込まれる前にシステムが停止した場合でも、データを失わないようにするための非常に重要な仕組みである。

一方、アンドゥログ(undo log)は、トランザクションがROLLBACKされた際に、そのトランザクションが行った変更を元に戻すために使用される。また、システムクラッシュからの回復時にも、未完了のトランザクションをロールバックして、データベースを整合性のある状態に戻す役割も担う。記事の例では、Charlieの残高を300増やすUPDATE Accounts SET balance = balance + 300 WHERE name = 'Charlie';という文を実行した後、ROLLBACKを行っている。結果としてSELECT * FROM Accounts;で確認すると、Charlieの残高は変更前の2000のままであることが示される。これは、アンドゥログが変更前の情報(この場合はCharlieの元の残高)を記録しており、ROLLBACKによってMySQLがその情報を使ってCharlieの残高を正確に元の状態に戻したからである。

これらの仕組みをまとめると、MySQLは「トランザクションによるアトミック性の保証」を通じてデータの整合性を守り、「デッドロックの自動検出と解決」によって複数の処理が同時に行われる環境でのシステムの停止を防ぐ。そして、「ログベースリカバリ」によって、システム障害や意図的なロールバックが発生した場合でもデータを確実に回復させる。これらの高度な機能が組み合わさることで、MySQLは多くのミッションクリティカルなシステムで信頼性の高いデータベースとして機能しているのである。システムエンジニアとして、これらの基盤技術を深く理解することは、堅牢で安定した情報システムを構築し運用するために不可欠な知識となる。

関連コンテンツ

関連IT用語