[前回] MySQL vs. TiDB-分散トランザクションの比較検証(7): TiDB分散トランザクションの理論
はじめに
今回は、TiDB分散トランザクションの基本操作を検証します。
検証準備
端末を三つ用意します
- 端末1: TiDBクラスタを起動
- 端末2: クライアントからTiDBに接続
- 端末3: クライアントからTiDBに接続
端末1から、TiDBクラスタを起動
$ tiup playground --db 2 --pd 3 --kv 3
... ...
CLUSTER START SUCCESSFULLY, Enjoy it ^-^
To connect TiDB: mysql --comments --host 127.0.0.1 --port 4001 -u root -p (no password)
To connect TiDB: mysql --comments --host 127.0.0.1 --port 4000 -u root -p (no password)
To view the dashboard: http://127.0.0.1:2379/dashboard
PD client endpoints: [127.0.0.1:2379 127.0.0.1:2382 127.0.0.1:2384]
To view the Prometheus: http://127.0.0.1:9090
To view the Grafana: http://127.0.0.1:3000
端末2から、TiDBに接続
- tiupコマンドでTiDBに接続
$ tiup client
Enterキーで、ポート番号4000を選択すると、
コマンドプロンプトが表示されます。
my:root@127.0.0.1:4000=>
- データベース
test
を作成/指定
CREATE DATABASE test;
USE test;
- テーブル
theater
を作成
=> CREATE TABLE theater (
seat_id INT PRIMARY KEY,
ordered ENUM('YES', 'NO') DEFAULT 'NO'
);
CREATE TABLE
検証1: 通常パターン
分散トランザクションの基本操作を確認します。
端末2から、分散トランザクション開始
=> START TRANSACTION;
START TRANSACTION
- テーブル
theater
に1レコードをINSERT
=> INSERT INTO theater VALUES (1, 'NO');
INSERT 1
- SELECT実行し、テーブル
theater
を検索
=> SELECT * FROM theater;
seat_id | ordered
---------+---------
1 | NO
(1 row)
あれー、コミットしていないのに、レコードが存在するぞ。。。
- 分散トランザクションモードを確認
=> select @@tidb_txn_mode;
@@tidb_txn_mode
-----------------
pessimistic
(1 row)
デフォルトの悲観的モードになっています。
- 分散トランザクションのステータスを確認
=> select * from information_schema.tidb_trx\G
*************************** 1. row ***************************
ID: 433109652995047425
START_TIME: 2022-05-10T20:30:08.996+09:00
CURRENT_SQL_DIGEST:
CURRENT_SQL_DIGEST_TEXT:
STATE: Idle
WAITING_START_TIME:
MEM_BUFFER_KEYS: 1
MEM_BUFFER_BYTES: 29
SESSION_ID: 407
USER: root
DB: test
ALL_SQL_DIGESTS: ["f53534242526f5f17dd442bf4429823244510563047efdcc0679741ca5833ea6","93ee0752065c0824a984aa0eca2e59e4aedbee5479ae07ed29b924ff5bb09256","157bfd65d62eed0b262a745b7a2d6a37570576ab88b44f56a60d6f0e4e99eeba","c4ef5a83e75b42191d7e4e51ff33f5a712b8b41e743952a668b405076ce134ac","d7815f6adab7ceebe67882038b7d29c081675c0e94751110ff74213523b6998e"]
STATE: Idle
状態になっています。
端末3から、別セッションでTiDBに接続
$ tiup client
- データベース
test
を指定
=> USE test;
USE
- SELECT実行し、テーブル
theater
を検索
=> SELECT * FROM theater;
(0 rows)
同じセッションではレコード確認できたので、別セッションからは確認できません。
なんだ、コミットされたのではなく、下書き(Prewrite)されただけか(分散トランザクションの第1フェーズ)。
端末2から、分散トランザクションをコミット
=> COMMIT;
COMMIT
- 分散トランザクションのステータスを確認
=> select * from information_schema.tidb_trx\G
分散トランザクションがコミットされ終了したため、存在しません。
端末3から、再度テーブルを検索
- SELECT実行し、テーブル
theater
を検索
=> SELECT * FROM theater;
seat_id | ordered
---------+---------
1 | NO
(1 row)
今度は、コミットされたため、レコードが存在します。
検証2: 異常パターン
操作途中でクライアントが異常終了した、といったシナリオです。
端末2から、分散トランザクション開始
=> START TRANSACTION;
START TRANSACTION
- テーブル
theater
に、1レコードをINSERT
=> INSERT INTO theater VALUES (2, 'NO');
INSERT 1
- SELECT実行し、テーブル
theater
を検索
=> SELECT * FROM theater;
seat_id | ordered
---------+---------
1 | NO
2 | NO
(2 rows)
下書き(Prewrite)された(コミットはまだ)ので、
同じセッションから、seat_id=2
の新しいレコードを確認できます。
- 分散トランザクションのステータスを確認
=> select * from information_schema.tidb_trx\G
*************************** 1. row ***************************
ID: 433110027008999425
START_TIME: 2022-05-10T20:53:55.746+09:00
CURRENT_SQL_DIGEST:
CURRENT_SQL_DIGEST_TEXT:
STATE: Idle
WAITING_START_TIME:
MEM_BUFFER_KEYS: 1
MEM_BUFFER_BYTES: 29
SESSION_ID: 407
USER: root
DB: test
ALL_SQL_DIGESTS: ["f53534242526f5f17dd442bf4429823244510563047efdcc0679741ca5833ea6","93ee0752065c0824a984aa0eca2e59e4aedbee5479ae07ed29b924ff5bb09256","157bfd65d62eed0b262a745b7a2d6a37570576ab88b44f56a60d6f0e4e99eeba","d7815f6adab7ceebe67882038b7d29c081675c0e94751110ff74213523b6998e"]
STATE: Idle
状態になっています。
- ここで、
Ctrl+D
でセッションを強制終了
端末3から、別セッションで分散トランザクションを確認
=> select * from information_schema.tidb_trx\G
既に、トランザクションは存在しません(ロールバックされたか)。
- SELECT実行し、テーブル
theater
を検索
=> SELECT * FROM theater;
seat_id | ordered
---------+---------
1 | NO
(1 row)
結果、端末2でINSERTしたseat_id=2
のレコードは存在しません。
以前、MySQL XAで実施した同じ検証と比較すると、
MySQLの場合は、XA PREPARE
直後にセッション異常終了しても、
別セッションからXA COMMIT
続行できましたね。
TiDB vs. MySQL
分散トランザクションの基本動作確認から、
- 分散トランザクションのSQL操作は、TiDBがMySQLよりシンプルでした
- セッション異常終了時に、両者の挙動に差異が存在していました
終わりに
TiDB分散トランザクションの基本動作を確認しました。
次回は、TiDB分散トランザクションの例として、銀行振込みを検証してみます。
お楽しみに。