## モジュール 2: ランナウェイクエリの特定と管理

+ このモジュールでは、ランナウェイクエリを特定し、それらを管理するためのアクションを学びます。
+ ランナウェイクエリは、`EXEC_ELAPSED`（実行時間）、`PROCESSED_KEYS`（処理キー数）、`RU`（リクエストユニット）などで特定できます。
+ ランナウェイクエリに対するアクションには、`DRYRUN`（何もしない）、`COOLDOWN`、`KILL`、`SWITCH GROUP`などがあります。

### 手順 1. TiDBに接続する

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

### 手順 2. データベース `sbtest` を使用し、データを取得する

+ 以下のクエリは、後で使用できる5つのクエリを生成します。

  ```sql
  USE sbtest;
  SELECT
    CONCAT(
      'SELECT * FROM sbtest1'
      ' WHERE c = ''',
      c,
      ''';'
    ) AS select_stmt
  FROM sbtest1
  WHERE id IN (1854967, 2546588, 4547856, 6374139, 8574239);
  ```

  ```output
  +------------------------------------------------------------------------------------------------------------------------------------------------------------+
  | select_stmt                                                                                                                                                |
  +------------------------------------------------------------------------------------------------------------------------------------------------------------+
  | SELECT * FROM sbtest1 WHERE c = '24897543010-03275216457-94900901372-55667311372-53395739269-97843435613-23430060855-92623057954-07277204320-98044593151'; |
  | SELECT * FROM sbtest1 WHERE c = '47331191657-14185857848-12598233640-45055926060-46507744483-13583166121-53370901880-15584534112-38498490607-22462784430'; |
  | SELECT * FROM sbtest1 WHERE c = '62445920995-81738237642-75309534239-00447205380-25802359858-30258723001-26103301616-59116803023-21063200722-98626229643'; |
  | SELECT * FROM sbtest1 WHERE c = '46607730431-76054520626-41005099754-96974085130-47547229605-86689999868-70104955183-39864721160-67802107023-56507121954'; |
  | SELECT * FROM sbtest1 WHERE c = '31507130228-72374452976-86320120947-15463984680-93359017252-69581927316-99176516606-73015610785-25943837292-41425794962'; |
  +------------------------------------------------------------------------------------------------------------------------------------------------------------+
  5 rows in set (0.00 sec)
  ```

### 手順 3. クエリを実行し、ベースラインを観察する

+ 手順2の出力の1行目にあるクエリを実行しましょう。**必ず手順2の出力からクエリをコピーしてください。**

  ```output
  +---------+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
  | id      | k       | c                                                                                                                       | pad                                                         |
  +---------+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
  | 1854967 | 4990337 | 51220495326-57294572228-74180497837-75653544056-24893586547-92403044009-87520022933-03279515577-21319387107-06005857619 | 16034900718-39255886096-26655700027-54928764285-07114323127 |
  +---------+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
  1 row in set (1.87 sec)
  ```

### 手順 4. ランナウェイクエリの定義を持つリソースグループを作成する

+ このリソースグループ（`rg1`）では、1秒以上実行されるクエリをランナウェイクエリと定義し、それらを強制終了（KILL）します。

  ```sql
  CREATE RESOURCE GROUP IF NOT EXISTS rg1 RU_PER_SEC = 500000 QUERY_LIMIT=(EXEC_ELAPSED='1s', ACTION=KILL);
  ```

  ```output
  Query OK, 0 rows affected (0.07 sec)
  ```

  ```sql
  SET RESOURCE GROUP `rg1`;
  SELECT CURRENT_RESOURCE_GROUP();
  ```

  ```output
  mysql> SET RESOURCE GROUP `rg1`;
  Query OK, 0 rows affected (0.00 sec)

  mysql> SELECT CURRENT_RESOURCE_GROUP();
  +--------------------------+
  | CURRENT_RESOURCE_GROUP() |
  +--------------------------+
  | rg1                      |
  +--------------------------+
  1 row in set (0.00 sec)
  ```

### 手順 5. SELECTおよびUPDATEクエリを実行する

+ 手順2の出力結果から**2番目のクエリ**を実行してみましょう。**手順2の出力からクエリをコピーして実行します。**

  ```output
  ERROR 1105 (HY000): context canceled
  ```

+ ここで、いくつかのUPDATEクエリを生成しましょう。

  ```sql
  SELECT
    CONCAT(
      'UPDATE sbtest1 SET k = ',
      k,
      ' WHERE c = ''',
      c,
      ''';'
    ) AS update_stmt
  FROM sbtest1
  WHERE id IN (1352967, 3646538, 5543556, 9528239);
  ```

  ```output
  +---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  | update_stmt                                                                                                                                                         |
  +---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  | UPDATE sbtest1 SET k = 5572807 WHERE c = '66769965526-22288246937-08772982046-39736592708-85565542463-16253515139-87788040417-16516967986-79761698887-90363782788'; |
  | UPDATE sbtest1 SET k = 4890272 WHERE c = '77751511479-77301323689-60724124182-56634052966-85022579170-95485486629-85511175487-24497764529-19028317287-55284140309'; |
  | UPDATE sbtest1 SET k = 5044683 WHERE c = '07884020628-55189473747-23156287117-55412424061-23981532176-33586725174-57709714730-45907782845-11012331015-05750365369'; |
  | UPDATE sbtest1 SET k = 5029615 WHERE c = '58693437664-70153861813-92566944634-27074701047-38913304646-44201618079-59665704931-59737601649-85799104421-65986769359'; |
  +---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  4 rows in set (0.00 sec)
  ```

+ 上記の出力の**最初の行**にあるクエリを実行してください。**出力からクエリをコピーして実行します。**

  ```output
  ERROR 1105 (HY000): context canceled
  ```

+ 手順 3から、クエリの実行時間は約2秒であることが分かっています。手順 4で、1秒を超えるクエリを「ランナウェイクエリ」と定義し、強制終了するように設定しました。この手順 の2つのクエリは、期待通り強制終了されます。なお、ランナウェイクエリが強制終了された場合、`ERROR 8253 (HY000): Query execution was interrupted, identified as runaway query` というエラーが表示されることもあります。

### 手順 6. ランナウェイクエリの定義を再設定する

+ 今回は `PROCESSED_KEYS` に基づいてランナウェイクエリを定義します。`PROCESSED_KEYS=100` は非常に小さい値であり、実際の運用環境ではもっと大きな値を設定します。

  ```sql
  ALTER RESOURCE GROUP rg1 QUERY_LIMIT=(PROCESSED_KEYS=100, ACTION=KILL);
  ```

  ```sql
  SET RESOURCE GROUP `rg1`;
  SELECT CURRENT_RESOURCE_GROUP();
  ```

  ```output
  tidb:db1> SET RESOURCE GROUP `rg1`;
  Query OK, 0 rows affected (0.00 sec)

  tidb:db1> SELECT CURRENT_RESOURCE_GROUP();
  +--------------------------+
  | CURRENT_RESOURCE_GROUP() |
  +--------------------------+
  | rg1                      |
  +--------------------------+
  1 row in set (0.00 sec)
  ```

### 手順 7. データベースから値を取得する

+ もう一度、UPDATEクエリを生成してみましょう。

  ```sql
  SELECT
    CONCAT(
      'UPDATE sbtest1 SET k = ',
      k,
      ' WHERE c = ''',
      c,
      ''';'
    ) AS update_stmt
  FROM sbtest1
  WHERE id IN (1352127, 3645438, 5548556, 9526339);
  ```

  ```output
  +---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  | update_stmt                                                                                                                                                         |
  +---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  | UPDATE sbtest1 SET k = 4910244 WHERE c = '69548467213-73791607785-10957730918-78445356961-91004694742-80323790863-13593873623-29524209298-71843592568-28064133015'; |
  | UPDATE sbtest1 SET k = 5182108 WHERE c = '87619334087-12889838231-05423612926-91915277761-80000970680-01099535465-40190779332-69927181259-86609575474-36554130556'; |
  | UPDATE sbtest1 SET k = 5043778 WHERE c = '46457191195-10255489756-60509274356-37025881706-07298342317-91405313638-74801992298-20461048824-96377089638-25184990994'; |
  | UPDATE sbtest1 SET k = 5039888 WHERE c = '96519115164-73671707684-33674179113-65994753810-08206447227-36642846222-72994512859-35744412659-41458322631-88308679056'; |
  +---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  4 rows in set (0.01 sec)
  ```

### 手順 8. 100キー以上を処理するクエリを実行する

+ 手順7の出力結果から**最初のクエリ**を実行してみましょう。

  ```output
  ERROR 8253 (HY000): Query execution was interrupted, identified as runaway query [ProcessedKeys = 1095654(100)]
  ```

+ この出力メッセージは、このクエリが `1095654` 個のキーを処理したことを示しています。しかし、手順 6で100個を超えるキーを処理するクエリをランナウェイクエリと定義し、強制終了するように設定したため、期待通りの動作となっています。
