## モジュール 2: TiKV MVCC インメモリエンジンを使用します

本モジュールでは、受講者はまず 6 つのテーブルを作成します。これらのテーブルは、それぞれ 2 つのテーブルが以前に定義された PLACEMENT POLICY に基づいて LEADER 役割の Region データを同じ TiKV ノードに配置します。同じ TiKV ノード上の 2 つのテーブルのうち、1 つのテーブルには比較的多くの MVCC 履歴スナップショットデータが含まれており、もう 1 つのテーブルにはほとんど MVCC 履歴データが含まれていません。これらの 3 つの TiKV ノードは TiKV MVCC メモリエンジンの設定が異なり、受講者はそれぞれの 6 つのテーブルをスキャンし、異なる設定の TiKV MVCC メモリエンジンのパフォーマンスを観察します。また、受講者は TiKV MVCC メモリエンジンの設定を変更し、変更後の現象を観察します。

### 手順 1. TiUP コントロールマシンに4つのターミナルで接続します

+ 以下のリンクをクリックして、演習用仮想マシンへの4つのSSH接続を開きます：
  + [ターミナル 1](ssh://monitor1-ssh#1)
  + [ターミナル 2](ssh://monitor1-ssh#2)
  + [ターミナル 3](ssh://monitor1-ssh#3)
  + [ターミナル 4](ssh://monitor1-ssh#4)

+ これで4つのアクティブなターミナルセッションが開かれます。

### 手順 2. テーブルの作成

+ [ターミナル 1](ssh://monitor1-ssh#1) で、TiDBサーバーインスタンスに接続します。

  ```bash
  mysql -h ${HOST_DB1_PRIVATE_IP} --port 4000 -u root
  ```

  ```output
  mysql> 
  ```

+ [ターミナル 1](ssh://monitor1-ssh#1) で、`test` の下に `tbl_no_ime_R1`、`tbl_ime_R1`、`tbl_no_ime_R2`、`tbl_ime_R2`、`tbl_no_ime_R3`、および `tbl_ime_R3` のテーブルを作成し、テーブル作成に使用される DDL ステートメントについて理解します。

  ```sql
  DROP TABLE IF EXISTS test.tbl_no_ime_R1;
  CREATE TABLE test.tbl_no_ime_R1 (
  `ID` bigint (20) NOT NULL AUTO_INCREMENT,
  `pID` bigint (20) NOT NULL,
  `cID` bigint (20) NOT NULL,
  `sID` bigint (20) NOT NULL,
  `pState` varchar (100) NOT NULL,
  `cState` tinyint (4) DEFAULT NULL,
  `created_at` DATETIME,
  `updated_at` DATETIME,
  `txt` varchar(64) DEFAULT 'IMETEST',
  PRIMARY KEY (`sID`, `ID`),
  UNIQUE KEY `pcsID` (`pID`, `cID`, `sID`),
  KEY `pcStateIndex` (`pState`, `cState`)
  ) PLACEMENT POLICY = IME_R1;

  DROP TABLE IF EXISTS test.tbl_ime_R1;
  CREATE TABLE test.tbl_ime_R1 (
  `ID` bigint (20) NOT NULL AUTO_INCREMENT,
  `pID` bigint (20) NOT NULL,
  `cID` bigint (20) NOT NULL,
  `sID` bigint (20) NOT NULL,
  `pState` varchar (100) NOT NULL,
  `cState` tinyint (4) DEFAULT NULL,
  `created_at` DATETIME,
  `updated_at` DATETIME,
  `txt` varchar(64) DEFAULT 'IMETEST',
  PRIMARY KEY (`sID`, `ID`),
  UNIQUE KEY `pcsID` (`pID`, `cID`, `sID`),
  KEY `pcStateIndex` (`pState`, `cState`)
  ) PLACEMENT POLICY = IME_R1;

  DROP TABLE IF EXISTS test.tbl_no_ime_R2;
  CREATE TABLE test.tbl_no_ime_R2 (
  `ID` bigint (20) NOT NULL AUTO_INCREMENT,
  `pID` bigint (20) NOT NULL,
  `cID` bigint (20) NOT NULL,
  `sID` bigint (20) NOT NULL,
  `pState` varchar (100) NOT NULL,
  `cState` tinyint (4) DEFAULT NULL,
  `created_at` DATETIME,
  `updated_at` DATETIME,
  `txt` varchar(64) DEFAULT 'IMETEST',
  PRIMARY KEY (`sID`, `ID`),
  UNIQUE KEY `pcsID` (`pID`, `cID`, `sID`),
  KEY `pcStateIndex` (`pState`, `cState`)
  ) PLACEMENT POLICY = IME_R2;

  DROP TABLE IF EXISTS test.tbl_ime_R2;
  CREATE TABLE test.tbl_ime_R2 (
  `ID` bigint (20) NOT NULL AUTO_INCREMENT,
  `pID` bigint (20) NOT NULL,
  `cID` bigint (20) NOT NULL,
  `sID` bigint (20) NOT NULL,
  `pState` varchar (100) NOT NULL,
  `cState` tinyint (4) DEFAULT NULL,
  `created_at` DATETIME,
  `updated_at` DATETIME,
  `txt` varchar(64) DEFAULT 'IMETEST',
  PRIMARY KEY (`sID`, `ID`),
  UNIQUE KEY `pcsID` (`pID`, `cID`, `sID`),
  KEY `pcStateIndex` (`pState`, `cState`)
  ) PLACEMENT POLICY = IME_R2;

  DROP TABLE IF EXISTS test.tbl_no_ime_R3;
  CREATE TABLE test.tbl_no_ime_R3 (
  `ID` bigint (20) NOT NULL AUTO_INCREMENT,
  `pID` bigint (20) NOT NULL,
  `cID` bigint (20) NOT NULL,
  `sID` bigint (20) NOT NULL,
  `pState` varchar (100) NOT NULL,
  `cState` tinyint (4) DEFAULT NULL,
  `created_at` DATETIME,
  `updated_at` DATETIME,
  `txt` varchar(64) DEFAULT 'IMETEST',
  PRIMARY KEY (`sID`, `ID`),
  UNIQUE KEY `pcsID` (`pID`, `cID`, `sID`),
  KEY `pcStateIndex` (`pState`, `cState`)
  ) PLACEMENT POLICY = IME_R3;

  DROP TABLE IF EXISTS test.tbl_ime_R3;
  CREATE TABLE test.tbl_ime_R3 (
  `ID` bigint (20) NOT NULL AUTO_INCREMENT,
  `pID` bigint (20) NOT NULL,
  `cID` bigint (20) NOT NULL,
  `sID` bigint (20) NOT NULL,
  `pState` varchar (100) NOT NULL,
  `cState` tinyint (4) DEFAULT NULL,
  `created_at` DATETIME,
  `updated_at` DATETIME,
  `txt` varchar(64) DEFAULT 'IMETEST',
  PRIMARY KEY (`sID`, `ID`),
  UNIQUE KEY `pcsID` (`pID`, `cID`, `sID`),
  KEY `pcStateIndex` (`pState`, `cState`)
  ) PLACEMENT POLICY = IME_R3;

  EXIT;
  ```

  ```output
  mysql>   DROP TABLE IF EXISTS test.tbl_no_ime_R1;
  Query OK, 0 rows affected, 1 warning (0.00 sec)

  mysql>   CREATE TABLE test.tbl_no_ime_R1 (
      ->   `ID` bigint (20) NOT NULL AUTO_INCREMENT,
      ->   `pID` bigint (20) NOT NULL,
      ->   `cID` bigint (20) NOT NULL,
      ->   `sID` bigint (20) NOT NULL,
      ->   `pState` varchar (100) NOT NULL,
      ->   `cState` tinyint (4) DEFAULT NULL,
      ->   `created_at` DATETIME,
      ->   `updated_at` DATETIME,
      ->   `txt` varchar(64) DEFAULT 'IMETEST',
      ->   PRIMARY KEY (`sID`, `ID`),
      ->   UNIQUE KEY `pcsID` (`pID`, `cID`, `sID`),
      ->   KEY `pcStateIndex` (`pState`, `cState`)
      ->   ) PLACEMENT POLICY = IME_R1;
  Query OK, 0 rows affected, 5 warnings (0.10 sec)

  ...

  mysql> 
  mysql>   DROP TABLE IF EXISTS test.tbl_ime_R3;
  Query OK, 0 rows affected, 1 warning (0.00 sec)

  mysql>   CREATE TABLE test.tbl_ime_R3 (
      ->   `ID` bigint (20) NOT NULL AUTO_INCREMENT,
      ->   `pID` bigint (20) NOT NULL,
      ->   `cID` bigint (20) NOT NULL,
      ->   `sID` bigint (20) NOT NULL,
      ->   `pState` varchar (100) NOT NULL,
      ->   `cState` tinyint (4) DEFAULT NULL,
      ->   `created_at` DATETIME,
      ->   `updated_at` DATETIME,
      ->   `txt` varchar(64) DEFAULT 'IMETEST',
      ->   PRIMARY KEY (`sID`, `ID`),
      ->   UNIQUE KEY `pcsID` (`pID`, `cID`, `sID`),
      ->   KEY `pcStateIndex` (`pState`, `cState`)
      ->   ) PLACEMENT POLICY = IME_R3;
  Query OK, 0 rows affected, 5 warnings (0.07 sec)

  mysql> 
  mysql>   EXIT;
  Bye
  ```

+ テーブル作成の DDL ステートメントにおける PLACEMENT POLICY の定義により、以下のことがわかります：
  + テーブル `tbl_no_ime_R1` と `tbl_ime_R1` の PLACEMENT POLICY は `IME_R1` であり、これらの全ての LEADER 役割の Region は `region1` の TiKV ノードに格納され、これに対する読み書きはデフォルトで `region1` の TiKV ノードで行われます。
  + テーブル `tbl_no_ime_R2` と `tbl_ime_R2` の PLACEMENT POLICY は `IME_R2` であり、これらの全ての LEADER 役割の Region は `region2` の TiKV ノードに格納され、これに対する読み書きはデフォルトで `region2` の TiKV ノードで行われます。
  + テーブル `tbl_no_ime_R3` と `tbl_ime_R3` の PLACEMENT POLICY は `IME_R3` であり、これらの全ての LEADER 役割の Region は `region3` の TiKV ノードに格納され、これに対する読み書きはデフォルトで `region3` の TiKV ノードで行われます。
  + テーブル `tbl_no_ime_R1`、`tbl_ime_R1`、`tbl_no_ime_R2`、`tbl_ime_R2`、`tbl_no_ime_R3`、および `tbl_ime_R3` の TiKV クラスター内でのストレージは下の図のようになります：

  ![IME_PART2_TABLES_1.png 70%](https://lab-static.pingcap.com/images/2025/8/20/e8caf85c16d6ae4ba61ae26b8929dc1bceac86c4.png)

### 手順 3. データを準備します

+ [ターミナル 1](ssh://monitor1-ssh#1) で、`tiup bench` ツールを使用して、テーブル `tbl_no_ime_R1`、`tbl_no_ime_R2`、および `tbl_no_ime_R3` にそれぞれ 1,000 行のランダムデータを挿入します。`TiUP bench`については、こちらをご参照ください：<https://docs.pingcap.com/ja/tidb/stable/tiup-bench/>

  ```bash
  cat > tbl_no_ime_R1_R2_R3.sql <<EOF
  INSERT INTO test.tbl_no_ime_R1 (pID, cID, sID, pState, cState, created_at, updated_at) VALUES (1 + FLOOR(RAND() * 99999), 100001 + FLOOR(RAND() * 99999), 200001 + FLOOR(RAND() * 99999), ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), 1 + FLOOR(RAND() * 29), NOW(), NOW());
  INSERT INTO test.tbl_no_ime_R2 (pID, cID, sID, pState, cState, created_at, updated_at) VALUES (1 + FLOOR(RAND() * 99999), 100001 + FLOOR(RAND() * 99999), 200001 + FLOOR(RAND() * 99999), ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), 1 + FLOOR(RAND() * 29), NOW(), NOW());
  INSERT INTO test.tbl_no_ime_R3 (pID, cID, sID, pState, cState, created_at, updated_at) VALUES (1 + FLOOR(RAND() * 99999), 100001 + FLOOR(RAND() * 99999), 200001 + FLOOR(RAND() * 99999), ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), 1 + FLOOR(RAND() * 29), NOW(), NOW());
  EOF
  tiup bench rawsql run -H ${HOST_DB1_PRIVATE_IP} -P 4000 --count 1000 --threads 1 --query-files tbl_no_ime_R1_R2_R3.sql
  ```

  ```output
  A new version of bench is available:  -> v1.12.0

      To update this component:   tiup update bench
      To update all components:   tiup update --all

  The component `bench` version  is not installed; downloading from repository.
  Starting component bench: /home/ec2-user/.tiup/components/bench/v1.12.0/tiup-bench rawsql run -H 10.90.1.40 -P 4000 --count 1000 --threads 1 --query-files tbl_no_ime_R1_R2_R3.sql
  Finished
  [Summary] TBL_NO_IME_R1_R2_R3: 0.01s
  ```

+ [ターミナル 1](ssh://monitor1-ssh#1) で、TiDBサーバーインスタンスに接続します。

  ```bash
  mysql -h ${HOST_DB1_PRIVATE_IP} --port 4000 -u root
  ```

  ```output
  mysql> 
  ```

+ [ターミナル 1](ssh://monitor1-ssh#1) で、3 つのシーケンス（SEQUENCE）オブジェクト、`test.seq_ime_R1`、`test.seq_ime_R2`、および `test.seq_ime_R3` を作成し、次にテーブル `test.tbl_ime_R1`、`test.tbl_ime_R2`、および `test.tbl_ime_R3` にデータを挿入する際に使用します。

  ```sql
  DROP SEQUENCE IF EXISTS test.seq_ime_R1;
  CREATE SEQUENCE test.seq_ime_R1;
  DROP SEQUENCE IF EXISTS test.seq_ime_R2;
  CREATE SEQUENCE test.seq_ime_R2;
  DROP SEQUENCE IF EXISTS test.seq_ime_R3;
  CREATE SEQUENCE test.seq_ime_R3;
  EXIT
  ```

  ```output
  mysql> DROP SEQUENCE IF EXISTS test.seq_ime_R1;
  Query OK, 0 rows affected, 1 warning (0.00 sec)
  mysql> CREATE SEQUENCE test.seq_ime_R1;
  Query OK, 0 rows affected (0.06 sec)

  mysql> DROP SEQUENCE IF EXISTS test.seq_ime_R2;
  Query OK, 0 rows affected, 1 warning (0.00 sec)
  mysql> CREATE SEQUENCE test.seq_ime_R2;
  Query OK, 0 rows affected (0.06 sec)

  mysql> DROP SEQUENCE IF EXISTS test.seq_ime_R3;
  Query OK, 0 rows affected, 1 warning (0.00 sec)
  mysql> CREATE SEQUENCE test.seq_ime_R3;
  Query OK, 0 rows affected (0.06 sec)

  mysql> EXIT
  Bye
  ```

+ [ターミナル 1](ssh://monitor1-ssh#1) で、`tiup bench` ツールを使用して、テーブル `tbl_ime_R1` に 1,000 行のランダムデータを挿入します。テーブル `tbl_no_ime_R1` との違いは、各行のデータを挿入した後にその行データに対して 10 回の更新操作（UPDATE）を行い、10 個の MVCC スナップショットを生成する点です。これには約 1 分かかります。

  ```bash
  cat > tbl_ime_R1.sql <<EOF
  SELECT @sID := 200001 + FLOOR(RAND() * 99999);
  INSERT INTO test.tbl_ime_R1 (pID, cID, sID, pState, cState, created_at, updated_at) VALUES (1 + FLOOR(RAND() * 99999), 100001 + FLOOR(RAND() * 99999), @sID, ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), 1 + FLOOR(RAND() * 29), NOW(), NOW());
  SELECT @ID := NEXTVAL(test.seq_ime_R1);
  UPDATE test.tbl_ime_R1 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID;
  UPDATE test.tbl_ime_R1 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID;
  UPDATE test.tbl_ime_R1 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID;
  UPDATE test.tbl_ime_R1 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID;
  UPDATE test.tbl_ime_R1 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID;
  UPDATE test.tbl_ime_R1 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID;
  UPDATE test.tbl_ime_R1 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID;
  UPDATE test.tbl_ime_R1 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID;
  UPDATE test.tbl_ime_R1 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID;
  UPDATE test.tbl_ime_R1 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID;
  EOF
  tiup bench rawsql run -H ${HOST_DB1_PRIVATE_IP} -P 4000 --count 1000 --threads 1 --query-files tbl_ime_R1.sql
  ```

  ```output
  Starting component bench: /home/ec2-user/.tiup/components/bench/v1.12.0/tiup-bench rawsql run -H 10.90.1.40 -P 4000 --count 1000 --threads 1 --query-files tbl_ime_R1.sql
  [Current] TBL_IME_R1: 0.00s
  [Current] TBL_IME_R1: 0.00s
  [Current] TBL_IME_R1: 0.00s
  [Current] TBL_IME_R1: 0.00s
  [Current] TBL_IME_R1: 0.00s
  Finished
  [Summary] TBL_IME_R1: 0.00s
  ```

  + [ターミナル 1](ssh://monitor1-ssh#1) で、`tiup bench` ツールを使用して、テーブル `tbl_ime_R2` に 1,000 行のランダムデータを挿入します。テーブル `tbl_no_ime_R2` との違いは、各行のデータを挿入した後にその行データに対して 10 回の更新操作（UPDATE）を行い、10 個の MVCC スナップショットを生成する点です。これには約 1 分かかります。

  ```bash
  cat > tbl_ime_R2.sql <<EOF
  SELECT @sID := 200001 + FLOOR(RAND() * 99999);
  INSERT INTO test.tbl_ime_R2 (pID, cID, sID, pState, cState, created_at, updated_at) VALUES (1 + FLOOR(RAND() * 99999), 100001 + FLOOR(RAND() * 99999), @sID, ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), 1 + FLOOR(RAND() * 29), NOW(), NOW());
  SELECT @ID := NEXTVAL(test.seq_ime_R2);
  UPDATE test.tbl_ime_R2 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R2 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R2 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R2 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R2 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R2 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R2 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R2 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R2 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R2 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  EOF
  tiup bench rawsql run -H ${HOST_DB1_PRIVATE_IP} -P 4000 --count 1000 --threads 1 --query-files tbl_ime_R2.sql
  ```

  ```output
  Starting component bench: /home/ec2-user/.tiup/components/bench/v1.12.0/tiup-bench rawsql run -H 10.90.1.40 -P 4000 --count 1000 --threads 1 --query-files tbl_ime_R2.sql
  [Current] TBL_IME_R2: 0.00s
  [Current] TBL_IME_R2: 0.00s
  [Current] TBL_IME_R2: 0.00s
  [Current] TBL_IME_R2: 0.00s
  [Current] TBL_IME_R2: 0.00s
  [Current] TBL_IME_R2: 0.00s
  Finished
  [Summary] TBL_IME_R2: 0.00s
  ```

  + [ターミナル 1](ssh://monitor1-ssh#1) で、`tiup bench` ツールを使用して、テーブル `tbl_ime_R3` に 1,000 行のランダムデータを挿入します。テーブル `tbl_no_ime_R3` との違いは、各行のデータを挿入した後にその行データに対して 10 回の更新操作（UPDATE）を行い、10 個の MVCC スナップショットを生成する点です。これには約 1 分かかります。

  ```bash
  cat > tbl_ime_R3.sql <<EOF
  SELECT @sID := 200001 + FLOOR(RAND() * 99999);
  INSERT INTO test.tbl_ime_R3 (pID, cID, sID, pState, cState, created_at, updated_at) VALUES (1 + FLOOR(RAND() * 99999), 100001 + FLOOR(RAND() * 99999), @sID, ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), 1 + FLOOR(RAND() * 29), NOW(), NOW());
  SELECT @ID := NEXTVAL(test.seq_ime_R3);
  UPDATE test.tbl_ime_R3 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R3 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R3 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R3 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R3 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R3 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R3 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R3 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R3 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  UPDATE test.tbl_ime_R3 SET pState = ELT(1 + FLOOR(RAND() * 9), 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's0'), cState = 1 + FLOOR(RAND() * 29) WHERE sID = @sID AND ID = @ID; 
  EOF
  tiup bench rawsql run -H ${HOST_DB1_PRIVATE_IP} -P 4000 --count 1000 --threads 1 --query-files tbl_ime_R3.sql
  ```

  ```output
  Starting component bench: /home/ec2-user/.tiup/components/bench/v1.12.0/tiup-bench rawsql run -H 10.90.1.40 -P 4000 --count 1000 --threads 1 --query-files tbl_ime_R3.sql
  [Current] TBL_IME_R3: 0.00s
  [Current] TBL_IME_R3: 0.00s
  [Current] TBL_IME_R3: 0.00s
  [Current] TBL_IME_R3: 0.00s
  [Current] TBL_IME_R3: 0.00s
  Finished
  [Summary] TBL_IME_R3: 0.00s
  ```

### 手順 4. データの分布の確認

+ [ターミナル 1](ssh://monitor1-ssh#1) で、TiDBサーバーインスタンスに接続します。

  ```bash
  mysql -h ${HOST_DB1_PRIVATE_IP} --port 4000 -u root
  ```

  ```output
  mysql> 
  ```

+ [ターミナル 1](ssh://monitor1-ssh#1) で、以下の SQL コマンドを実行し、`test` 下のテーブル `tbl_no_ime_R1`、`tbl_ime_R1`、`tbl_no_ime_R2`、`tbl_ime_R2`、`tbl_no_ime_R3`、および `tbl_ime_R3` の TiKV クラスター上での分布状況を確認します。出力結果:
  + 列 `DB_NAME` はスキーマ名を示し。
  + 列 `TABLE_NAME` はテーブル名を示し。
  + 列 `ADDRESS` は所在の TiKV ノードのアドレスを示します。
  + 列 `IS_LEADER` は LEADER 役割の Region であるかどうかを示し、`1` ははい、`0` はいいえを表します。
  + 列 `IS_LEARNER` は LEARNER 役割の Region であるかどうかを示し、`1` ははい、`0` はいいえを表します。
  + 列 `REGION COUNT` は Region の数を示します。

  ```sql
  SELECT
    rs.`DB_NAME`,
    rs.`TABLE_NAME`,
    s.ADDRESS,
    r.`IS_LEADER`,
    r.`IS_LEARNER`,
    COUNT(r.REGION_ID) "REGION COUNT"
  FROM
    INFORMATION_SCHEMA.TIKV_REGION_PEERS r,
    INFORMATION_SCHEMA.TIKV_STORE_STATUS s,
    INFORMATION_SCHEMA.tikv_region_status rs
  WHERE r.STORE_ID = s.STORE_ID
    AND r.`REGION_ID` = rs.`REGION_ID`
    AND rs.`DB_NAME` = 'test'
    AND rs.`TABLE_NAME` IN ('tbl_no_ime_R1', 'tbl_no_ime_R2', 'tbl_no_ime_R3', 'tbl_ime_R1', 'tbl_ime_R2', 'tbl_ime_R3')
    AND r.`IS_LEARNER`=0
  GROUP BY rs.`DB_NAME`,
    rs.`TABLE_NAME`,
    s.`ADDRESS`,
    r.`IS_LEADER`,
    r.`IS_LEARNER`
    ORDER BY r.`IS_LEADER` DESC, rs.`DB_NAME`, s.ADDRESS, rs.`TABLE_NAME`;
  ```

  ```output
  +---------+---------------+-------------------+-----------+------------+--------------+
  | DB_NAME | TABLE_NAME    | ADDRESS           | IS_LEADER | IS_LEARNER | REGION COUNT |
  +---------+---------------+-------------------+-----------+------------+--------------+
  | test    | tbl_ime_R2    | 10.90.3.147:20160 |         1 |          0 |            4 |
  | test    | tbl_no_ime_R2 | 10.90.3.147:20160 |         1 |          0 |            4 |
  | test    | tbl_ime_R1    | 10.90.3.49:20160  |         1 |          0 |            4 |
  | test    | tbl_no_ime_R1 | 10.90.3.49:20160  |         1 |          0 |            4 |
  | test    | tbl_ime_R3    | 10.90.3.51:20160  |         1 |          0 |            4 |
  | test    | tbl_no_ime_R3 | 10.90.3.51:20160  |         1 |          0 |            4 |
  | test    | tbl_ime_R1    | 10.90.3.147:20160 |         0 |          0 |            4 |
  | test    | tbl_ime_R3    | 10.90.3.147:20160 |         0 |          0 |            4 |
  | test    | tbl_no_ime_R1 | 10.90.3.147:20160 |         0 |          0 |            4 |
  | test    | tbl_no_ime_R3 | 10.90.3.147:20160 |         0 |          0 |            4 |
  | test    | tbl_ime_R2    | 10.90.3.49:20160  |         0 |          0 |            4 |
  | test    | tbl_ime_R3    | 10.90.3.49:20160  |         0 |          0 |            4 |
  | test    | tbl_no_ime_R2 | 10.90.3.49:20160  |         0 |          0 |            4 |
  | test    | tbl_no_ime_R3 | 10.90.3.49:20160  |         0 |          0 |            4 |
  | test    | tbl_ime_R1    | 10.90.3.51:20160  |         0 |          0 |            4 |
  | test    | tbl_ime_R2    | 10.90.3.51:20160  |         0 |          0 |            4 |
  | test    | tbl_no_ime_R1 | 10.90.3.51:20160  |         0 |          0 |            4 |
  | test    | tbl_no_ime_R2 | 10.90.3.51:20160  |         0 |          0 |            4 |
  +---------+---------------+-------------------+-----------+------------+--------------+
  18 rows in set (0.02 sec)
  ```

+ 前の SQL コマンドの結果から以下の結論が得られます：
  + テーブル `tbl_no_ime_R1` と `tbl_ime_R1` の PLACEMENT POLICY は `IME_R1` であり、これらの全ての LEADER 役割の Region は `region1` の TiKV ノードに格納され、これに対する読み書きはデフォルトで `region1` の TiKV ノードで行われます。
  + テーブル `tbl_no_ime_R2` と `tbl_ime_R2` の PLACEMENT POLICY は `IME_R2` であり、これらの全ての LEADER 役割の Region は `region2` の TiKV ノードに格納され、これに対する読み書きはデフォルトで `region2` の TiKV ノードで行われます。
  + テーブル `tbl_no_ime_R3` と `tbl_ime_R3` の PLACEMENT POLICY は `IME_R3` であり、これらの全ての LEADER 役割の Region は `region3` の TiKV ノードに格納され、これに対する読み書きはデフォルトで `region3` の TiKV ノードで行われます。

+ `test` 下のテーブル `tbl_no_ime_R1`、`tbl_ime_R1`、`tbl_no_ime_R2`、`tbl_ime_R2`、`tbl_no_ime_R3`、および `tbl_ime_R3` の TiKV クラスター上での分布状況は下の図のようになります。ここで、`tbl_ime_R1`、`tbl_ime_R2`、および `tbl_ime_R3` のデータ量が `tbl_no_ime_R1`、`tbl_no_ime_R2`、および `tbl_no_ime_R3` より多い理由は、挿入時に更新（UPDATE）操作が行われたため、テーブルには大量の MVCC の履歴スナップショットデータが含まれています。

  ![IME_PART2_TABLES_2.png 70%](https://lab-static.pingcap.com/images/2025/8/20/9d9cf59417c092f62c7c584d41ca26a3fa8bc058.png)

+ [ターミナル 1](ssh://monitor1-ssh#1) で、次の 2 つの SQL コマンドを実行し、それぞれテーブル `test.tbl_no_ime_R1` と `test.tbl_ime_R1` に対してクエリを実行します。

  ```sql
  SELECT sID, ID, txt FROM test.tbl_no_ime_R1 USE INDEX (pcStateIndex) WHERE ((pState = 's1') OR (pState = 's2') OR (pState = 's3')) OR ((pState = 's3' AND cState = 10) OR (pState = 's3' AND cState = 20)) AND NOT (sID = 200001 AND ID = 1097) AND NOT (sID = 0 AND ID = 0) LIMIT 50;
  SELECT sID, ID, txt FROM test.tbl_ime_R1 USE INDEX (pcStateIndex) WHERE ((pState = 's1') OR (pState = 's2') OR (pState = 's3')) OR ((pState = 's3' AND cState = 10) OR (pState = 's3' AND cState = 20)) AND NOT (sID = 200001 AND ID = 1097) AND NOT (sID = 0 AND ID = 0) LIMIT 50;
  EXIT
  ```

  ```output
  +--------+-----+---------+
  | sID    | ID  | txt     |
  +--------+-----+---------+
  | 203063 | 275 | IMETEST |
  | 203099 | 901 | IMETEST |
  ...
  | 295013 | 475 | IMETEST |
  | 297637 | 920 | IMETEST |
  +--------+-----+---------+
  50 rows in set (0.03 sec)

  mysql> SELECT sID, ID, txt FROM test.tbl_ime_R1 USE INDEX (pcStateIndex) WHERE ((pState = 's1') OR (pState = 's2') OR (pState = 's3')) OR ((pState = 's3' AND cState = 10) OR (pState = 's3' AND cState = 20)) AND NOT (sID = 200001 AND ID = 1097) AND NOT (sID = 0 AND ID = 0) LIMIT 50;
  +--------+-----+---------+
  | sID    | ID  | txt     |
  +--------+-----+---------+
  | 203120 | 248 | IMETEST |
  | 205100 | 158 | IMETEST |
  ...
  | 296901 | 455 | IMETEST |
  | 297482 | 113 | IMETEST |
  +--------+-----+---------+
  50 rows in set (0.02 sec)

  mysql> EXIT
  Bye
  ```

+ [TiDB Dashboard](http://${LAB:HOST_PD1_PUBLIC_IP}:2379/dashboard)にアクセスし、ユーザー名`root`でログインします。現時点ではパスワードは不要です。`SQL Statements`パネルに移動し、表示時間を`Recent 5 min`に変更します。

  ![60%](https://lab-static.pingcap.com/quick-demo/ime-off-dashboard-time-1.png)

+ データベースを`test`に選択します。

  ![60%](https://lab-static.pingcap.com/quick-demo/ime-off-dashboard-db-2.png)

+ 表示される操作を `Select` に設定します。

  ![IME_PART2_DASHBOARD_1.png 70%](https://lab-static.pingcap.com/images/2025/8/19/f5b0606c31a88d5ed4ef29a11154046f4f92f7d9.png)

+ `SELECT 'sid', 'id', 'txt' FROM 'test'. 'tbl_no_ime_r1' WHERE ...` で始まる SQL コマンドを選択します。この SQL コマンドはテーブル `test.tbl_no_ime_r1` に対するクエリ操作です。クリックして詳細を確認します。

  ![IME_PART2_DASHBOARD_2.png 70%](https://lab-static.pingcap.com/images/2025/8/19/28355b3509e4076a27cde011953fd7ffdd042e86.png)

+ `Execution Detail` の `Execution Plan` 項目を確認し、演算子 `Limit_13(Build)` を見つけ、その `Execution Info` 情報を確認します。`total_process_keys` が `96`、`total_keys` が `97` であることがわかり、テーブルでスキャンしてフィルタリングする行数と実際に保存されている総行数が類似していることを示しています。

  ![IME_PART2_DASHBOARD_3.png 70%](https://lab-static.pingcap.com/images/2025/8/19/2fd7e5de180aa79f99ce50b3ac69ffd6327aa26a.png)

+ `Execution Detail` の `Coprocessor Read` 項目を確認したところ、`Mean Visible Versions Per Query` が `146` であり、`Mean Meet Versions Per Query` が `197` であることがわかりました。これらの二つの項目の値は類似しており、`Mean Meet Versions Per Query` の数値には MVCC 履歴スナップショットデータが含まれている可能性があるため、このクエリは過剰な MVCC 履歴スナップショットデータをスキャンしていないことを示しています。

  ![IME_PART2_DASHBOARD_4.png 70%](https://lab-static.pingcap.com/images/2025/8/19/69e9763ec43113a737fbd97458b25b3258f92871.png)

+ 前のページに戻り、`SELECT 'sid', 'id', 'txt' FROM 'test'. 'tbl_ime_r1' WHERE (...` で始まる SQL コマンドを選択します。この SQL コマンドはテーブル `test.tbl_ime_r1` に対するクエリ操作です。クリックして詳細を確認します。

  ![IME_PART2_DASHBOARD_5.png 70%](https://lab-static.pingcap.com/images/2025/8/19/2d51f054945395ca95606fddc14bb7354523501d.png)

+ `Execution Detail` の `Execution Plan` 項目を確認し、ステップ `Limit_13(Build)` を見つけ、その `Execution Info` 情報を確認したところ、`total_process_keys` が `96`、`total_keys` が `1865` であることがわかりました。これにより、テーブルでスキャンしてフィルタリングする必要のある行数が、実際に保存されている総行数よりもかなり少ないことが示されています。（出力結果は若干異なる場合があります）

  ![IME_PART2_DASHBOARD_6.png 70%](https://lab-static.pingcap.com/images/2025/8/19/94b738494b9f66c89fd9d13462c604820a0f082b.png)

+ `Execution Detail` の `Coprocessor Read` 項目を確認したところ、`Mean Visible Versions Per Query` が `146` であり、`Mean Meet Versions Per Query` が `2.3K` であることがわかりました。これらの二つの項目の値は大きく異なっており、`Mean Meet Versions Per Query` の数値には MVCC 履歴スナップショットデータが含まれている可能性があるため、このクエリは過剰な MVCC 履歴スナップショットデータをスキャンしていることを示しています。（出力結果は若干異なる場合があります）

  ![IME_PART2_DASHBOARD_7.png 70%](https://lab-static.pingcap.com/images/2025/8/19/6103fc9a975764597ec03bb44d2a3e54e83a7d35.png)

+ 注意：テーブル `test.tbl_ime_r1` に対するクエリ操作の場合、実行計画で特定の演算子の `Execution Info` 情報において `total_process_keys` と `total_keys` の差が大きい場合、そのクエリ操作は TiKV MVCC メモリエンジンの特性を利用して最適化するのが適切です。テーブル `tbl_no_ime_R2` と `tbl_ime_R2` のクエリ、およびテーブル `tbl_no_ime_R3` と `tbl_ime_R3` のクエリも同様の結果が得られるため、ここでは省略します。

### 手順 5. TiKV MVCCメモリエンジンの使用

+ TiKV MVCC メモリエンジンの使用状況を確認するために、[Grafana dashboard](http://${LAB:HOST_MONITOR1_PUBLIC_IP}:3000)にログインし、`Home`に入り、次に`tidb-demo`を選択し、続いて`tidb-demo-TiKV-Details`を選択します。`In Memory Engine`タブを開くと、`Region Cache Hit`、`Region Cache Hit Rate`、および `Region Cache Miss Reason` パネルが表示されます。（`Region Cache Hit` は TiKV MVCC メモリエンジンからデータを正常に取得した回数を示し、`Region Cache Hit Rate` は TiKV MVCC メモリエンジンのヒット率を示し、`Region Cache Miss Reason` パネルは TiKV MVCC メモリエンジンが有効な TiKV ノードで、TiKV MVCC メモリエンジンを使用したクエリの数を示します。）`tidb-demo-TiKV-Details` の `In Memory Engine` タブにある各パネルについては、以下を参照してください：<https://docs.pingcap.com/tidb/stable/grafana-tikv-dashboard/#in-memory-engine>。

  ![IME_PART2_TiKV_DETAIL_IME_1.png 70%](https://lab-static.pingcap.com/images/2025/8/20/90706bc00ff24f6ca060b5fad2bf527d8b3e165b.png)

+ [ターミナル 2](ssh://monitor1-ssh#2) で、`tiup bench` ツールを使用してテーブル `test.tbl_ime_R1` をスキャンします。スキャンは継続的に行われるため、スキャンが終了するのを待たずにすぐに次の操作を実行してください。

  ```bash
  cat > query_tbl_ime_R1.sql <<EOF
  SELECT sID, ID, txt FROM test.tbl_ime_R1 USE INDEX (pcStateIndex) WHERE ((pState = 's1') OR (pState = 's2') OR (pState = 's3')) OR ((pState = 's3' AND cState = 10) OR (pState = 's3' AND cState = 20)) AND NOT (sID = 200001 AND ID = 1097) AND NOT (sID = 0 AND ID = 0) LIMIT 50;
  EOF
  tiup bench rawsql run -H ${HOST_DB1_PRIVATE_IP} -P 4000 --count 300000 --threads 1 --query-files query_tbl_ime_R1.sql
  ```

  ```output
  Starting component bench: /home/ec2-user/.tiup/components/bench/v1.12.0/tiup-bench rawsql run -H 10.90.1.40 -P 4000 --count 300000 --threads 1 --query-files query_tbl_ime_R1.sql
  [Current] QUERY_TBL_IME_R1: 0.00s
  [Current] QUERY_TBL_IME_R1: 0.00s
  ...
  ```

+ [ターミナル 3](ssh://monitor1-ssh#3) で、`tiup bench` ツールを使用してテーブル `test.tbl_ime_R2` をスキャンします。スキャンは継続的に行われるため、スキャンが終了するのを待たずにすぐに次の操作を実行してください。

  ```bash
  cat > query_tbl_ime_R2.sql <<EOF
  SELECT sID, ID, txt FROM test.tbl_ime_R2 USE INDEX (pcStateIndex) WHERE ((pState = 's1') OR (pState = 's2') OR (pState = 's3')) OR ((pState = 's3' AND cState = 10) OR (pState = 's3' AND cState = 20)) AND NOT (sID = 200001 AND ID = 1097) AND NOT (sID = 0 AND ID = 0) LIMIT 50;
  EOF
  tiup bench rawsql run -H ${HOST_DB1_PRIVATE_IP} -P 4000 --count 300000 --threads 1 --query-files query_tbl_ime_R2.sql
  ```

  ```output
  Starting component bench: /home/ec2-user/.tiup/components/bench/v1.12.0/tiup-bench rawsql run -H 10.90.1.40 -P 4000 --count 300000 --threads 1 --query-files query_tbl_ime_R2.sql
  [Current] QUERY_TBL_IME_R2: 0.00s
  [Current] QUERY_TBL_IME_R2: 0.00s
  ...
  ```

+ [ターミナル 4](ssh://monitor1-ssh#4) で、`tiup bench` ツールを使用してテーブル `test.tbl_ime_R3` をスキャンします。スキャンは継続的に行われるため、スキャンが終了するのを待たずにすぐに次の操作を実行してください。

  ```bash
  cat > query_tbl_ime_R3.sql <<EOF
  SELECT sID, ID, txt FROM test.tbl_ime_R3 USE INDEX (pcStateIndex) WHERE ((pState = 's1') OR (pState = 's2') OR (pState = 's3')) OR ((pState = 's3' AND cState = 10) OR (pState = 's3' AND cState = 20)) AND NOT (sID = 200001 AND ID = 1097) AND NOT (sID = 0 AND ID = 0) LIMIT 50;
  EOF
  tiup bench rawsql run -H ${HOST_DB1_PRIVATE_IP} -P 4000 --count 300000 --threads 1 --query-files query_tbl_ime_R3.sql
  ```

  ```output
  Starting component bench: /home/ec2-user/.tiup/components/bench/v1.12.0/tiup-bench rawsql run -H 10.90.1.40 -P 4000 --count 300000 --threads 1 --query-files query_tbl_ime_R3.sql
  [Current] QUERY_TBL_IME_R3: 0.00s
  [Current] QUERY_TBL_IME_R3: 0.00s
  ...
  ```

+ 再度 [Grafana dashboard](http://${LAB:HOST_MONITOR1_PUBLIC_IP}:3000) に戻り、`tidb-demo-TiKV-Details` の `In Memory Engine` タブで、`Region Cache Hit`、`Region Cache Hit Rate`、および `Region Cache Miss Reason` パネルを通じて、現在 `region2` の TiKV ノードのクエリ操作のみが TiKV MVCC メモリエンジンを使用していることを理解します。その `Region Cache Hit` と `Region Cache Hit Rate` は上昇し始め、`Region Cache Miss Reason` は変化しないか、下降し始めます。`region1` の TiKV ノードは TiKV MVCC メモリエンジンが無効になっているため、表示されません。`region3` の TiKV ノードは TiKV MVCC メモリエンジンが有効になっていますが、その `Region Cache Miss Reason` は上昇し始め、`Region Cache Hit` と `Region Cache Hit Rate` は上昇しません。以下の図のようになります：

  ![IME_PART2_TiKV_DETAIL_IME_2.png 70%](https://lab-static.pingcap.com/images/2025/8/20/81c0ace60004a955c1fc8b6151228031d935ab67.png)

+ `region3` の TiKV ノードは TiKV MVCC メモリエンジンが有効になっていますが、使用されていない理由は、その `in-memory-engine.mvcc-amplification-threshold` が `100` に設定されており、実際の MVCC 読み取り増幅が `100` に達していないためです。以下の図のようになります：

  ![IME_PART2_TABLES_3.png 70%](https://lab-static.pingcap.com/images/2025/8/20/91006e2a198dd866153d54c31fd36715a3fe6fae.png)

### 手順 6. TiKV MVCC メモリエンジンの設定

+ [ターミナル 1](ssh://monitor1-ssh#1) で、TiDBサーバーインスタンスに接続します。

  ```bash
  mysql -h ${HOST_DB1_PRIVATE_IP} --port 4000 -u root
  ```

  ```output
  mysql> 
  ```

+ [ターミナル 1](ssh://monitor1-ssh#1) で、 すべての TiKV ノードに関する TiKV MVCC メモリエンジンの設定を確認します。

  ```sql
  show config where type='tikv' and name like 'in-memory-engine%';
  ```

  ```output
  +------+-------------------+-----------------------------------------------+------------+
  | Type | Instance          | Name                                          | Value      |
  +------+-------------------+-----------------------------------------------+------------+
  | tikv | 10.90.3.49:20160  | in-memory-engine.capacity                     | 1GiB       |
  | tikv | 10.90.3.49:20160  | in-memory-engine.cross-check-interval         | 0s         |
  | tikv | 10.90.3.49:20160  | in-memory-engine.enable                       | false      |
  | tikv | 10.90.3.49:20160  | in-memory-engine.evict-threshold              | null       |
  | tikv | 10.90.3.49:20160  | in-memory-engine.gc-run-interval              | 3m         |
  | tikv | 10.90.3.49:20160  | in-memory-engine.load-evict-interval          | 2m         |
  | tikv | 10.90.3.49:20160  | in-memory-engine.mvcc-amplification-threshold | 5          |
  | tikv | 10.90.3.49:20160  | in-memory-engine.stop-load-threshold          | null       |
  | tikv | 10.90.3.147:20160 | in-memory-engine.capacity                     | 1GiB       |
  | tikv | 10.90.3.147:20160 | in-memory-engine.cross-check-interval         | 0s         |
  | tikv | 10.90.3.147:20160 | in-memory-engine.enable                       | true       |
  | tikv | 10.90.3.147:20160 | in-memory-engine.evict-threshold              | 966367642B |
  | tikv | 10.90.3.147:20160 | in-memory-engine.gc-run-interval              | 3m         |
  | tikv | 10.90.3.147:20160 | in-memory-engine.load-evict-interval          | 2m         |
  | tikv | 10.90.3.147:20160 | in-memory-engine.mvcc-amplification-threshold | 5          |
  | tikv | 10.90.3.147:20160 | in-memory-engine.stop-load-threshold          | 805306369B |
  | tikv | 10.90.3.51:20160  | in-memory-engine.capacity                     | 1GiB       |
  | tikv | 10.90.3.51:20160  | in-memory-engine.cross-check-interval         | 0s         |
  | tikv | 10.90.3.51:20160  | in-memory-engine.enable                       | true       |
  | tikv | 10.90.3.51:20160  | in-memory-engine.evict-threshold              | 966367642B |
  | tikv | 10.90.3.51:20160  | in-memory-engine.gc-run-interval              | 3m         |
  | tikv | 10.90.3.51:20160  | in-memory-engine.load-evict-interval          | 2m         |
  | tikv | 10.90.3.51:20160  | in-memory-engine.mvcc-amplification-threshold | 100        |
  | tikv | 10.90.3.51:20160  | in-memory-engine.stop-load-threshold          | 805306369B |
  +------+-------------------+-----------------------------------------------+------------+
  24 rows in set (0.04 sec)
  ```

+ [ターミナル 1](ssh://monitor1-ssh#1) で、 `region3` の TiKV ノードの `in-memory-engine.mvcc-amplification-threshold` 値を `5` に変更します。ここでは、現在の TiKV ノードの IP アドレスに基づいて設定してください。

  ```sql
  set config "10.90.3.51:20160" `in-memory-engine.mvcc-amplification-threshold`=5;
  show config where instance='10.90.3.51:20160' and type='tikv' and name like 'in-memory-engine%';
  ```

  ```output
  mysql> set config "10.90.3.51:20160" `in-memory-engine.mvcc-amplification-threshold`=5;
  Query OK, 0 rows affected (0.02 sec)

  mysql> show config where instance='10.90.3.51:20160' and type='tikv' and name like 'in-memory-engine%';
  +------+------------------+-----------------------------------------------+------------+
  | Type | Instance         | Name                                          | Value      |
  +------+------------------+-----------------------------------------------+------------+
  | tikv | 10.90.3.51:20160 | in-memory-engine.capacity                     | 1GiB       |
  | tikv | 10.90.3.51:20160 | in-memory-engine.cross-check-interval         | 0s         |
  | tikv | 10.90.3.51:20160 | in-memory-engine.enable                       | true       |
  | tikv | 10.90.3.51:20160 | in-memory-engine.evict-threshold              | 966367642B |
  | tikv | 10.90.3.51:20160 | in-memory-engine.gc-run-interval              | 3m         |
  | tikv | 10.90.3.51:20160 | in-memory-engine.load-evict-interval          | 2m         |
  | tikv | 10.90.3.51:20160 | in-memory-engine.mvcc-amplification-threshold | 5          |
  | tikv | 10.90.3.51:20160 | in-memory-engine.stop-load-threshold          | 805306369B |
  +------+------------------+-----------------------------------------------+------------+
  8 rows in set (0.04 sec)
  ```

+ 再度 [Grafana dashboard](http://${LAB:HOST_MONITOR1_PUBLIC_IP}:3000) に戻り、`tidb-demo-TiKV-Details` の `In Memory Engine` タブを開き、前の操作から約 2 分後に、`region2` の TiKV ノードでのクエリ操作が TiKV MVCC メモリエンジンを使用していることが確認できます。その際、`Region Cache Hit` と `Region Cache Hit Rate` が上昇し始め、`Region Cache Miss Reason` が下降し始めます。`region1` の TiKV ノードは TiKV MVCC メモリエンジンが無効になっているため、依然として表示されません。以下の図のようになります：

  ![IME_PART2_TiKV_DETAIL_IME_3.png 70%](https://lab-static.pingcap.com/images/2025/8/20/bd29215aa8cd1d0ef3ec57080ea5df96c1c00f77.png)

+ [ターミナル 1](ssh://monitor1-ssh#1) で、 `region1` の TiKV ノードの `in-memory-engine.enable` 値を `true` に変更します。ここでも、現在の TiKV ノードの IP アドレスに基づいて設定してください。

  ```sql
  set config "10.90.3.49:20160" `in-memory-engine.in-memory-engine.enable`=true;
  show config where instance='10.90.3.49:20160' and type='tikv' and name like 'in-memory-engine%';
  ```

  ```output
  mysql> set config "10.90.3.49:20160" `in-memory-engine.in-memory-engine.enable`=true;
  Query OK, 0 rows affected, 1 warning (0.02 sec)

  mysql> show config where instance='10.90.3.49:20160' and type='tikv' and name like 'in-memory-engine%';
  +------+------------------+-----------------------------------------------+-------+
  | Type | Instance         | Name                                          | Value |
  +------+------------------+-----------------------------------------------+-------+
  | tikv | 10.90.3.49:20160 | in-memory-engine.capacity                     | 1GiB  |
  | tikv | 10.90.3.49:20160 | in-memory-engine.cross-check-interval         | 0s    |
  | tikv | 10.90.3.49:20160 | in-memory-engine.enable                       | false |
  | tikv | 10.90.3.49:20160 | in-memory-engine.evict-threshold              | null  |
  | tikv | 10.90.3.49:20160 | in-memory-engine.gc-run-interval              | 3m    |
  | tikv | 10.90.3.49:20160 | in-memory-engine.load-evict-interval          | 2m    |
  | tikv | 10.90.3.49:20160 | in-memory-engine.mvcc-amplification-threshold | 5     |
  | tikv | 10.90.3.49:20160 | in-memory-engine.stop-load-threshold          | null  |
  +------+------------------+-----------------------------------------------+-------+
  8 rows in set (0.04 sec)
  ```

+ [ターミナル 1](ssh://monitor1-ssh#1) で、クライアント接続を切断します。

  ```sql
  EXIT
  ```

  ```output
  mysql> EXIT
  Bye
  ```

+ `region1` の TiKV ノードの `in-memory-engine.enable` は依然として `false` です。これは、現在オンラインで TiKV ノードの TiKV MVCC メモリエンジンの特性を変更できないためです。再度 [Grafana dashboard](http://${LAB:HOST_MONITOR1_PUBLIC_IP}:3000) に戻り、`tidb-demo-TiKV-Details` の `In Memory Engine` タブを開くと、`region2` と `region3` の TiKV ノードでのクエリが TiKV ノードの TiKV MVCC メモリエンジンの特性を使用していることが確認できますが、`region1` の TiKV ノードは TiKV MVCC メモリエンジンの特性を使用していません。注意：あなたの結果は実験ガイドの結果と異なる場合があります。`Region Cache Hit Rate` パネル内の `region2` と `region3` の TiKV ノードでのクエリはすべて 100% に達しない可能性があります。

  ![IME_PART2_TiKV_DETAIL_IME_4.png 70%](https://lab-static.pingcap.com/images/2025/8/20/e5257af6fe90759a655b933107efe62755f595d4.png)

+ `region1`、`region2`、および `region3` の TiKV ノードの TiKV MVCC メモリエンジンの使用状況は以下の図のようになります：

  ![IME_PART2_TABLES_4.png 70%](https://lab-static.pingcap.com/images/2025/8/20/53cdfb65f295287f19db24284b4147b8327a5630.png)

+ [ターミナル 2](ssh://monitor1-ssh#2) で、**CTRL-C**を押して、`tiup bench` ツールによるテーブル `test.tbl_ime_R1` のスキャンを停止します。

  ```output
  ...
  [Current] QUERY_TBL_IME_R1: 0.00s
  [Current] QUERY_TBL_IME_R1: 0.00s
  ^C
  Got signal [interrupt] to exit.
  Got signal interrupt (Component: bench ; PID: 23009)
  Finished
  [Summary] QUERY_TBL_IME_R1: 0.00s
  [Summary] QUERY_TBL_IME_R1_ERR: 0.00s
  ...
  ```

+ [ターミナル 3](ssh://monitor1-ssh#3) で、**CTRL-C**を押して、`tiup bench` ツールによるテーブル `test.tbl_ime_R2` のスキャンを停止します。

  ```output
  [Current] QUERY_TBL_IME_R2: 0.00s
  [Current] QUERY_TBL_IME_R2: 0.00s
  ^C
  Got signal [interrupt] to exit.
  Got signal interrupt (Component: bench ; PID: 23314)
  Finished
  [Summary] QUERY_TBL_IME_R2: 0.00s
  [Summary] QUERY_TBL_IME_R2_ERR: 0.00s
  ```

+ [ターミナル 4](ssh://monitor1-ssh#4) で、**CTRL-C**を押して、`tiup bench` ツールによるテーブル `test.tbl_ime_R3` のスキャンを停止します。

  ```output
  [Current] QUERY_TBL_IME_R3: 0.00s
  [Current] QUERY_TBL_IME_R3: 0.00s
  ^C
  Got signal [interrupt] to exit.
  Got signal interrupt (Component: bench ; PID: 23495)
  [ec2-user@ip-10-90-4-217 ~]$ Finished
  [Summary] QUERY_TBL_IME_R3: 0.00s
  ```

+ [ターミナル 2](ssh://monitor1-ssh#2) で、`tiup bench` ツールを使用してテーブル `test.tbl_no_ime_R1` をスキャンします。スキャンは継続的に行われるため、スキャンが終了するのを待たずにすぐに次の操作を実行してください。

  ```bash
  cat > query_tbl_no_ime_R1.sql <<EOF
  SELECT sID, ID, txt FROM test.tbl_no_ime_R1 USE INDEX (pcStateIndex) WHERE ((pState = 's1') OR (pState = 's2') OR (pState = 's3')) OR ((pState = 's3' AND cState = 10) OR (pState = 's3' AND cState = 20)) AND NOT (sID = 200001 AND ID = 1097) AND NOT (sID = 0 AND ID = 0) LIMIT 50;
  EOF
  tiup bench rawsql run -H ${HOST_DB1_PRIVATE_IP} -P 4000 --count 300000 --threads 1 --query-files query_tbl_no_ime_R1.sql
  ```

  ```output
  Starting component bench: /home/ec2-user/.tiup/components/bench/v1.12.0/tiup-bench rawsql run -H 10.90.1.40 -P 4000 --count 300000 --threads 1 --query-files query_tbl_no_ime_R1.sql
  [Current] QUERY_TBL_NO_IME_R1: 0.00s
  [Current] QUERY_TBL_NO_IME_R1: 0.00s
  ...
  ```

+ [ターミナル 3](ssh://monitor1-ssh#3) で、`tiup bench` ツールを使用してテーブル `test.tbl_no_ime_R2` をスキャンします。スキャンは継続的に行われるため、スキャンが終了するのを待たずにすぐに次の操作を実行してください。

  ```bash
  cat > query_tbl_no_ime_R2.sql <<EOF
  SELECT sID, ID, txt FROM test.tbl_no_ime_R2 USE INDEX (pcStateIndex) WHERE ((pState = 's1') OR (pState = 's2') OR (pState = 's3')) OR ((pState = 's3' AND cState = 10) OR (pState = 's3' AND cState = 20)) AND NOT (sID = 200001 AND ID = 1097) AND NOT (sID = 0 AND ID = 0) LIMIT 50;
  EOF
  tiup bench rawsql run -H ${HOST_DB1_PRIVATE_IP} -P 4000 --count 300000 --threads 1 --query-files query_tbl_no_ime_R2.sql
  ```

  ```output
  Starting component bench: /home/ec2-user/.tiup/components/bench/v1.12.0/tiup-bench rawsql run -H 10.90.1.40 -P 4000 --count 300000 --threads 1 --query-files query_tbl_no_ime_R2.sql
  [Current] QUERY_TBL_NO_IME_R2: 0.00s
  [Current] QUERY_TBL_NO_IME_R2: 0.00s
  ...
  ```

+ [ターミナル 4](ssh://monitor1-ssh#4) で、`tiup bench` ツールを使用してテーブル `test.tbl_no_ime_R3` をスキャンします。スキャンは継続的に行われるため、スキャンが終了するのを待たずにすぐに次の操作を実行してください。

  ```bash
  cat > query_tbl_no_ime_R3.sql <<EOF
  SELECT sID, ID, txt FROM test.tbl_no_ime_R3 USE INDEX (pcStateIndex) WHERE ((pState = 's1') OR (pState = 's2') OR (pState = 's3')) OR ((pState = 's3' AND cState = 10) OR (pState = 's3' AND cState = 20)) AND NOT (sID = 200001 AND ID = 1097) AND NOT (sID = 0 AND ID = 0) LIMIT 50;
  EOF
  tiup bench rawsql run -H ${HOST_DB1_PRIVATE_IP} -P 4000 --count 300000 --threads 1 --query-files query_tbl_no_ime_R3.sql
  ```

  ```output
  Starting component bench: /home/ec2-user/.tiup/components/bench/v1.12.0/tiup-bench rawsql run -H 10.90.1.40 -P 4000 --count 300000 --threads 1 --query-files query_tbl_no_ime_R3.sql
  [Current] QUERY_TBL_NO_IME_R3: 0.00s
  [Current] QUERY_TBL_NO_IME_R3: 0.00s
  ...
  ```

+ 再度 [Grafana dashboard](http://${LAB:HOST_MONITOR1_PUBLIC_IP}:3000) に戻り、`tidb-demo-TiKV-Details` の `In Memory Engine` タブを開き、`Region Cache Hit`、`Region Cache Hit Rate`、および `Region Cache Miss Reason` パネルを通じて、現在 `region1` の TiKV ノードが TiKV MVCC メモリエンジンを有効にしていないため表示されないことを確認します。また、`region2` と `region3` の TiKV ノードのクエリ操作も TiKV MVCC メモリエンジンを使用していないため、`Region Cache Hit` と `Region Cache Hit Rate` は上昇せず、低い値のまま維持されています。さらに、`Region Cache Miss Reason` は上昇し、高い値を維持しています。その理由は、テーブル `test.tbl_no_ime_R2` と `test.tbl_no_ime_R3` の MVCC 読み取り増幅が、`region2` と `region3` の TiKV ノードに設定されている `in-memory-engine.mvcc-amplification-threshold` の値 `5` を超えていないためです。以下の図のようになります：

  ![IME_PART2_TiKV_DETAIL_IME_5.png 70%](https://lab-static.pingcap.com/images/2025/8/20/b1059224ed5b1a0294322bd29b75cac387251649.png)

+ [ターミナル 2](ssh://monitor1-ssh#2) で、**CTRL-C**を押して、`tiup bench` ツールによるテーブル `test.tbl_no_ime_R1` のスキャンを停止します。

  ```output
  ...
  [Current] QUERY_TBL_NO_IME_R1: 0.00s
  [Current] QUERY_TBL_NO_IME_R1: 0.00s
  ^C
  Got signal [interrupt] to exit.
  Got signal interrupt (Component: bench ; PID: 23800)
  Finished
  [Summary] QUERY_TBL_NO_IME_R1: 0.00s
  [Summary] QUERY_TBL_NO_IME_R1_ERR: 0.00s
  ...
  ```

+ [ターミナル 3](ssh://monitor1-ssh#3) で、**CTRL-C**を押して、`tiup bench` ツールによるテーブル `test.tbl_no_ime_R2` のスキャンを停止します。

  ```output
  [Current] QUERY_TBL_NO_IME_R2: 0.00s
  [Current] QUERY_TBL_NO_IME_R2: 0.00s
  ^C
  Got signal [interrupt] to exit.
  Got signal interrupt (Component: bench ; PID: 23768)
  Finished
  [Summary] QUERY_TBL_NO_IME_R2: 0.00s
  [Summary] QUERY_TBL_NO_IME_R2_ERR: 0.00s
  ```

+ [ターミナル 4](ssh://monitor1-ssh#4) で、**CTRL-C**を押して、`tiup bench` ツールによるテーブル `test.tbl_no_ime_R3` のスキャンを停止します。

  ```output
  [Current] QUERY_TBL_NO_IME_R3: 0.00s
  [Current] QUERY_TBL_NO_IME_R3: 0.00s
  ^C
  Got signal [interrupt] to exit.
  Got signal interrupt (Component: bench ; PID: 23809)
  [ec2-user@ip-10-90-4-217 ~]$ Finished
  [Summary] QUERY_TBL_NO_IME_R3: 0.00s
  ```

### 手順 7. データのクリーンアップ

+ [ターミナル 1](ssh://monitor1-ssh#1) で、TiDBサーバーインスタンスに接続します。

  ```bash
  mysql -h ${HOST_DB1_PRIVATE_IP} --port 4000 -u root
  ```

  ```output
  mysql> 
  ```

+ [ターミナル 1](ssh://monitor1-ssh#1) で、 本モジュールで使用されているすべてのデータをクリーンアップします。

  ```sql
  DROP TABLE IF EXISTS test.tbl_no_ime_R1;
  DROP TABLE IF EXISTS test.tbl_no_ime_R2;
  DROP TABLE IF EXISTS test.tbl_no_ime_R3;

  DROP TABLE IF EXISTS test.tbl_ime_R1;
  DROP TABLE IF EXISTS test.tbl_ime_R2;
  DROP TABLE IF EXISTS test.tbl_ime_R3;

  DROP SEQUENCE IF EXISTS test.seq_ime_R1;
  DROP SEQUENCE IF EXISTS test.seq_ime_R2;
  DROP SEQUENCE IF EXISTS test.seq_ime_R3;

  EXIT
  ```

  ```output
  mysql> DROP TABLE IF EXISTS test.tbl_no_ime_R1;
  Query OK, 0 rows affected (0.17 sec)

  mysql> DROP TABLE IF EXISTS test.tbl_no_ime_R2;
  Query OK, 0 rows affected (0.14 sec)

  mysql> DROP TABLE IF EXISTS test.tbl_no_ime_R3;
  Query OK, 0 rows affected (0.14 sec)

  mysql> 
  mysql> DROP TABLE IF EXISTS test.tbl_ime_R1;
  Query OK, 0 rows affected (0.14 sec)

  mysql> DROP TABLE IF EXISTS test.tbl_ime_R2;
  Query OK, 0 rows affected (0.13 sec)

  mysql> DROP TABLE IF EXISTS test.tbl_ime_R3;
  Query OK, 0 rows affected (0.13 sec)

  mysql> 
  mysql> DROP SEQUENCE IF EXISTS test.seq_ime_R1;
  Query OK, 0 rows affected (0.12 sec)

  mysql> DROP SEQUENCE IF EXISTS test.seq_ime_R2;
  Query OK, 0 rows affected (0.13 sec)

  mysql> DROP SEQUENCE IF EXISTS test.seq_ime_R3;
  Query OK, 0 rows affected (0.13 sec)

  mysql>   EXIT;
  Bye
  ```

+ 本モジュールはここで終了します。
