3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

MySQL vs. TiDB-分散トランザクションの比較検証(3): MySQL内部XA

Last updated at Posted at 2022-04-15
[前回] MySQL vs. TiDB-分散トランザクションの比較検証(2): MySQL XA

はじめに

前回に続き、MySQLの分散トランザクション、 XAの検証です。

その前に、XAトランザクションの状態遷移のおさらい

image.png

XAトランザクションの各種状態と遷移条件

  • ACTIVE
    • XA STARTステートメントにより、トランザクションがアクティブ状態に
    • ACTIVE状態で、READ/WRITE関連ステートメントを実行できる
  • IDLE
    • XA ENDステートメントにより、トランザクションがIDEL状態に
    • IDLE状態で、XA PREPAREまたはXA COMMIT ONE PHASEのいずれかを発行できる
  • PREPARED
    • XA PREPAREステートメントにより、トランザクションが準備されPREPARED状態に
  • COMMITTED
    • XA COMMITステートメントにより、トランザクションがCOMMITTED状態になり終了
    • XA COMMIT ONE PHASEは、トランザクションの準備&コミットを1ステップで実行
  • FAILED
    • 処理中エラーにより、トランザクションが失敗しFAILED状態に
  • ABORTED
    • XA ROLLBACKステートメントにより、トランザクションがABORTED状態になり終了

検証開始

検証環境と事前準備は前回と同じです。
操作用端末を二つ開きます。

  • 端末1: アプリケーション操作用
  • 端末2: MySQLサーバー操作用

検証3: MySQLサーバー異常終了時のXA検証

前回は、MySQLクライアントがXA PREPARE直後に異常終了しても、
XAトランザクションが維持され、XA COMMITできることを確認できました。
今回は、MySQLサーバー異常終了時のXAの挙動を検証します。

端末1から、XAトランザクションを実行

  • mysqlコマンドでMySQL接続し、データベース指定
$ mysql -u user -p
mysql> USE test;
  • XAトランザクションを開始
    myxaは、XAトランザクションの一意識別子
mysql> XA START 'myxa';
  • 1行INSERT
mysql> INSERT INTO theater VALUES (3, 'NO');
  • XA END実行し、トランザクションをIDLE状態に
mysql> XA END 'myxa';
  • XA PREPARE実行し、トランザクションを準備
mysql> XA PREPARE 'myxa';
  • XA RECOVER実行し、PREPARED状態のXAトランザクションを確認
mysql> XA RECOVER;
+----------+--------------+--------------+------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+------+
|        1 |            4 |            0 | myxa |
+----------+--------------+--------------+------+
1 row in set (0.00 sec)

端末2から、MySQLサーバーをkillコマンドで強制終了

  • MySQLサーバーのプロセスIDを確認
$ ps -ef | grep mysqld | grep -v grep
mysql      303   152  0 06:21 ?        00:00:03 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib/mysql/plugin --log-error=/var/log/mysql/error.log --pid-file=81KRV93.pid
  • プロセスID(上記例では303)を指定しkill
$ kill -9 <プロセスID>

端末1から、XAトランザクションを確認

  • XA RECOVERコマンド実行します
mysql> XA RECOVER;
ERROR 2013 (HY000): Lost connection to MySQL server during query
No connection. Trying to reconnect...
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (111)
ERROR:
Can't connect to the server

MySQLサーバーがkillされたため、接続すらできません。

  • mysqlコマンドを終了します。
mysql> quit

端末2から、MySQLサーバーを再起動します

  • MySQLサーバー起動
$ sudo service mysql start

端末1から、XAトランザクションを確認

  • 再度、mysqlコマンドでMySQL接続し、データベース指定
$ mysql -u user -p
mysql> USE test;
  • XA RECOVER実行し、PREPARED状態のXAトランザクションを確認
mysql> XA RECOVER;
+----------+--------------+--------------+------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+------+
|        1 |            4 |            0 | myxa |
+----------+--------------+--------------+------+
1 row in set (0.00 sec)

なんと、PREPARED状態のXAトランザクションが残ってくれています。

  • XA COMMIT実行し、PREPARED状態のトランザクションをコミット
mysql> XA COMMIT 'myxa';
  • SELECT実行し、INSERTされたseat_id=3を検索
mysql> SELECT * FROM theater WHERE seat_id=3;
+---------+---------+
| seat_id | ordered |
+---------+---------+
|       3 | NO      |
+---------+---------+
1 row in set (0.00 sec)

結果、期待とおり1レコードヒットしました。
第1フェーズのXA PREPARE後、MySQLサーバーが異常終了しても、
第2フェーズのXA COMMITを続行できました、すごい。

おわりに

MySQL XAに対し、MySQLサーバー異常終了したらどうなるか検証しました。
次回も検証続きます、お楽しみに。

[次回] MySQL vs. TiDB-分散トランザクションの比較検証(4): MySQL内部XA(続)
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?