[前回] MySQL vs. TiDB-分散トランザクションの比較検証(2): MySQL XA
はじめに
前回に続き、MySQLの分散トランザクション、 XAの検証です。
その前に、XAトランザクションの状態遷移のおさらい
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サーバー異常終了したらどうなるか検証しました。
次回も検証続きます、お楽しみに。