1
0

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-分散トランザクションの比較検証(8): TiDB分散トランザクションの基本動作

Last updated at Posted at 2022-05-10
[前回] 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分散トランザクションの例として、銀行振込みを検証してみます。
お楽しみに。

[次回] MySQL vs. TiDB-分散トランザクションの比較検証(9): TiDBで銀行振込みのシミュレーション
1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?