# アップグレード時ダウンタイムなし

## 概要

この演習では、TiDB のシームレスなオンラインローリングアップグレード能力を示しています。従来のデータベースのアップグレードにおける一般的な問題を回避し、クライアントアプリケーションに障害が生じることがありません。TiDB のクラウドネイティブで疎結合されたアーキテクチャは、コンポーネントごとのインスタンスアップグレードを可能にします。TiProxy は、クライアントセッションをステートレスな TiDB サーバーから分離し、アップグレード中に TiDB サーバーが再起動する際、アクティブなインスタンスにセッションをシームレスに移行させ、アップグレード中もクライアント操作の中断を防ぎます。

![80%](https://lab-static.pingcap.com/quick-demo/demo_005_en.png)

### 所要時間

+ この演習は約 60 分程度かかります。

### タスク

+ TiDB クラスタのステータスとトポロジーを確認します。
+ TiDB クラスタをバージョン 7.5.4 から 8.1.1 へアップグレードします。
+ アップグレードの進行中に TiDB クラスタが機能を維持し、DML やクエリー操作を受け入れられるか観察し、確認します。

> [!TIP]
> 演習環境を起動するには、**開始**をクリックしてください。
> 環境の準備が整ったら、下部のツールバーで **次のモジュール** を選択して **モジュール 1** に進みます。
> そして、ステップバイステップの演習ガイドに従って、ハンズオン環境に接続し、タスクを開始してください。

## モジュール 1: TiProxy を使用して TiDB クラスタをデプロイする

### 手順 1. リモート Linux にログインします

+ ここをクリック - [ターミナル 1](ssh://monitor1-ssh#1) で、ハンズオン演習用に割り当てられた仮想マシンに接続された新しいターミナルを開きます。

+ ログイン後に表示されるバナー：

    ```output
     ,     #_
    ~\_  ####_        Amazon Linux 2
    ~~  \_#####\
    ~~     \###|      
    ~~       \#/ ___
    ~~       V~' '->
    ~~~         /    A newer version of Amazon Linux is available!
     ~~._.   _/
        _/ _/       Amazon Linux 2023, GA and supported until 2028-03-15.
      _/m/'           https://aws.amazon.com/linux/amazon-linux-2023/
    ```

### 手順 2. 準備されたクラスタトポロジー YAML ファイルを確認します

  ```bash
  cat eleven-nodes.yaml
  ```
  ```output
  global:
    user: "ec2-user"
    ssh_port: 22
    deploy_dir: "/tidb-deploy"
    data_dir: "/tidb-data"
    arch: "amd64"
  server_configs:
    pd:
      replication.max-replicas: 3
    tidb:
      security.auto-tls: true
      graceful-wait-before-shutdown: 10
  pd_servers:
    - host: 10.90.3.160
      client_port: 2379
      peer_port: 2380
      advertise_client_addr: "http://35.92.30.186:2379"
    - host: 10.90.1.162
      client_port: 2379
      peer_port: 2380
      advertise_client_addr: "http://52.34.128.150:2379"
    - host: 10.90.2.223
      client_port: 2379
      peer_port: 2380
      advertise_client_addr: "http://54.245.183.8:2379"
  tidb_servers:
    - host: 10.90.1.157
      port: 4000
      status_port: 10080
      deploy_dir: /tidb-deploy/tidb-4000
      log_dir: /tidb-deploy/tidb-4000/log
    - host: 10.90.2.6
      port: 4000
      status_port: 10080
      deploy_dir: /tidb-deploy/tidb-4000
      log_dir: /tidb-deploy/tidb-4000/log
  tikv_servers:
    - host: 10.90.3.132
      port: 20160
      status_port: 20180
    - host: 10.90.2.171
      port: 20160
      status_port: 20180
    - host: 10.90.1.222
      port: 20160
      status_port: 20180
  monitoring_servers:
    - host: 10.90.4.33
  grafana_servers:
    - host: 10.90.4.33
  alertmanager_servers:
    - host: 10.90.4.33
  tiproxy_servers:
    - host: 10.90.1.153
  ```

### 手順 3. TiDB クラスタをデプロイするためにシステム設定を修正します

  ```bash
  tiup mirror set tidb-community-server-7.5.4-linux-amd64
  tiup cluster check eleven-nodes.yaml \
    --user ec2-user \
    -i /home/ec2-user/.ssh/pe-class-key-oregon.pem \
    --apply
  ```
  ```output
  ...
  + Try to apply changes to fix failed checks
   - Applying changes on 10.90.1.162 ... ⠧ Sysctl: host=10.90.1.162 vm.swappiness = 0
   - Applying changes on 10.90.2.223 ... ⠧ Sysctl: host=10.90.2.223 vm.swappiness = 0
   - Applying changes on 10.90.3.132 ... ⠧ Sysctl: host=10.90.3.132 vm.swappiness = 0
  + Try to apply changes to fix failed checks
  + Try to apply changes to fix failed checks
   - Applying changes on 10.90.1.162 ... Done
   - Applying changes on 10.90.2.223 ... Done
  + Try to apply changes to fix failed checks
   - Applying changes on 10.90.1.162 ... Done
  + Try to apply changes to fix failed checks
  + Try to apply changes to fix failed checks
   - Applying changes on 10.90.1.162 ... Done
   - Applying changes on 10.90.2.223 ... Done
   - Applying changes on 10.90.3.132 ... Done
   - Applying changes on 10.90.2.171 ... Done
   - Applying changes on 10.90.1.222 ... Done
   - Applying changes on 10.90.4.33 ... Done
   - Applying changes on 10.90.3.160 ... Done
   - Applying changes on 10.90.1.153 ... Done
   - Applying changes on 10.90.2.210 ... Done
   - Applying changes on 10.90.1.157 ... Done
   - Applying changes on 10.90.2.6 ... Done
  ```

### 手順 4. TiDB クラスタをデプロイします

  ```bash
  tiup cluster deploy tidb-demo 7.5.4 ./eleven-nodes.yaml \
    --user ec2-user \
    -i /home/ec2-user/.ssh/pe-class-key-oregon.pem \
    --yes
  ```
  ```output
  ...
  Cluster `tidb-demo` deployed successfully, you can start it with command: `tiup cluster start tidb-demo --init`
  ```

### 手順 5. デプロイされた TiDB クラスタを開始します

  ```bash
  tiup cluster start tidb-demo
  ```
  ```output
  ...
  Started cluster `tidb-demo` successfully
  ```

## モジュール 2: TiDB クラスタに読み書き作業を適用する

### 手順 1. INSERT 作業のスクリプトを確認します

+ [ターミナル 2](ssh://monitor1-ssh#2) で、INSERT 作業のスクリプトを確認します。JDBC 例外が発生した場合にコンソールにメッセージを出力することができる Java プログラムが含まれています。最終的な出力には、`Work ? discards connection and try to get a new connection` といったメッセージが見られることがあります。デモの際にはこれらのメッセージに遭遇しないはずです。TiProxy はアップグレードプロセスが TiDB サーバーインスタンスをシャットダウンする前にデータベースクライアントセッションを移行でき、操作が中断されることがないからです。
   
  ```bash
  cat scripts/quick-demo-005-jdbc-endless-insert-dummy.sh
  ```
  ```output
  #!/bin/bash

  # Run ./quick-demo-005-jdbc-endless-insert-dummy.sh <LB_NAME>

  rm -f DemoJdbcEndlessInsertDummyCSPWithLBLongConn.class
  javac -cp .:misc/mysql-connector-java-5.1.36-bin.jar DemoJdbcEndlessInsertDummyCSPWithLBLongConn.java
  sleep 1
  java -cp .:misc/mysql-connector-java-5.1.36-bin.jar DemoJdbcEndlessInsertDummyCSPWithLBLongConn ${1}
  ```
  ```bash
  cat scripts/DemoJdbcEndlessInsertDummyCSPWithLBLongConn.java | grep -A10 catch | grep Work
  ```
  ```output
              System.out.println("Work 1 discards connection and try to get a new connection");
              System.out.println("Work 2 discards connection and try to get a new connection");
              System.out.println("Work 3 discards connection and try to get a new connection");
              System.out.println("Work 4 discards connection and try to get a new connection");
  ```

### 手順 2. INSERT 作業を適用するスクリプトを実行します

+ [ターミナル 2](ssh://monitor1-ssh#2) で、4つのワーカーでサンプル INSERT 作業を適用するスクリプトを実行します。作業を実行し続け、次のステップに進みます。

  ```bash
  mysql -h ${HOST_TIPROXY1_PRIVATE_IP} -P 6000 -uroot << EOF
  DROP TABLE IF EXISTS test.dummy; 
  CREATE TABLE test.dummy (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(80), event JSON, tidb_instance VARCHAR(30));
  EOF
  cd scripts
  ./quick-demo-005-jdbc-endless-insert-dummy.sh ${HOST_TIPROXY1_PRIVATE_IP}
  ```

  ```output
  Worker 3 -> TiDB:Thu May 16 09:38:55 UTC 2024 at 10.90.1.153
  Worker 4 -> TiDB:Thu May 16 09:38:56 UTC 2024 at 10.90.1.153
  Worker 2 -> TiDB:Thu May 16 09:38:56 UTC 2024 at 10.90.1.153
  Worker 1 -> TiDB:Thu May 16 09:38:56 UTC 2024 at 10.90.1.153
  Worker 3 -> TiDB:Thu May 16 09:38:56 UTC 2024 at 10.90.1.153
  Worker 4 -> TiDB:Thu May 16 09:38:57 UTC 2024 at 10.90.1.153
  Worker 2 -> TiDB:Thu May 16 09:38:57 UTC 2024 at 10.90.1.153
  Worker 1 -> TiDB:Thu May 16 09:38:57 UTC 2024 at 10.90.1.153
  Worker 3 -> TiDB:Thu May 16 09:38:57 UTC 2024 at 10.90.1.153
  Worker 4 -> TiDB:Thu May 16 09:38:58 UTC 2024 at 10.90.1.153
  Worker 2 -> TiDB:Thu May 16 09:38:58 UTC 2024 at 10.90.1.153
  ...
  ```

### 手順 3. クエリ作業を実行するスクリプトを実行します

+ [ターミナル 3](ssh://monitor1-ssh#3) で、クエリ作業を実行するスクリプトを確認します。各 TiDB サーバーインスタンスが処理したリクエスト数を確認するためにスクリプトを実行します。作業を実行し続け、次のステップに進みます。

  ```bash
  qdb(){
  mysql -h ${HOST_TIPROXY1_PRIVATE_IP} -P 6000 -uroot --connect-timeout 1 2>/dev/null << EOF
   SELECT tidb_instance, COUNT(event) FROM test.dummy GROUP BY tidb_instance ORDER BY tidb_instance;
  EOF
  }

  query(){
   echo;
   date;
   qdb
   sleep 2;
  }

  while true; do
   query;
  done;
  ```
  ```output
  Thu May 16 09:42:20 UTC 2024
  tidb_instance	COUNT(event)
  10.90.1.124:10080	466
  10.90.2.122:10080	466

  Thu May 16 09:42:22 UTC 2024
  tidb_instance	COUNT(event)
  10.90.1.124:10080	470
  10.90.2.122:10080	470

  Thu May 16 09:42:24 UTC 2024
  tidb_instance	COUNT(event)
  10.90.1.124:10080	474
  10.90.2.122:10080	474

  ...
  ```

## モジュール 3: ワークロードが実行中の状態で TiDB クラスタをアップグレードする

### 手順 1. TiUP ミラーの場所を設定します

+ [ターミナル 1](ssh://monitor1-ssh#1) に戻り、tiup コマンドを実行して TiUP のローカルミラーを v8.1.1 に変更します。

  ```bash
  tiup mirror set tidb-community-server-8.1.1-linux-amd64
  ```
  ```output
  Successfully set mirror to /home/ec2-user/tidb-community-server-8.1.1-linux-amd64
  ```

### 手順 2. TiDB クラスタをアップグレードします

+ `tiup` コマンドを実行して TiDB クラスタを v7.5.4 から v8.1.1 にアップグレードします。アップグレードが進行中の間、[ターミナル 2](ssh://monitor1-ssh#2) と [ターミナル 3](ssh://monitor1-ssh#3) に切り替えます。
    
  ```bash
  tiup cluster upgrade tidb-demo 8.1.1 --yes
  ```
  ```output
  Before the upgrade, it is recommended to read the upgrade guide at https://docs.tidb.io/tidb/stable/upgrade-tidb-using-tiup and finish the preparation steps.
  This operation will upgrade tidb v7.5.4 cluster tidb-demo to v8.1.1:
  will upgrade and restart component "                 pd" to "v8.1.1",
  will upgrade and restart component "               tikv" to "v8.1.1",
  will upgrade and restart component "               tidb" to "v8.1.1",
  ...
  + [ Serial ] - Download: component=grafana, version=v8.1.1, os=linux, arch=amd64
  + [ Serial ] - Download: component=tikv, version=v8.1.1, os=linux, arch=amd64
  + [ Serial ] - Download: component=tidb, version=v8.1.1, os=linux, arch=amd64
  + [ Serial ] - Download: component=prometheus, version=v8.1.1, os=linux, arch=amd64
  + [ Serial ] - Download: component=pd, version=v8.1.1, os=linux, arch=amd64
  ...
  Upgrading component pd
  	Restarting instance 10.90.1.135:2379
  	Restart instance 10.90.1.135:2379 success
  	Restarting instance 10.90.2.182:2379
  	Restart instance 10.90.2.182:2379 success
  	Restarting instance 10.90.3.231:2379
  	Restart instance 10.90.3.231:2379 success
  Upgrading component tikv
  	Evicting 11 leaders from store 10.90.1.55:20160...
  	  Still waiting for 11 store leaders to transfer...
  	  Still waiting for 11 store leaders to transfer...
  .
  .
  .
  Upgrading component tidb
  	Restarting instance 10.90.1.124:4000
  	Restart instance 10.90.1.124:4000 success
  	Restarting instance 10.90.2.122:4000
  	Restart instance 10.90.2.122:4000 success
  .
  .
  .
  ```

### 手順 3. INSERT および QUERY 作業が中断されていないことを確認します

+ [ターミナル 2](ssh://monitor1-ssh#2) と [ターミナル 3](ssh://monitor1-ssh#3) において、サンプルアプリケーション接続とトランザクションがアップグレード中に中断されていないことを確認します。

+ [ターミナル 1](ssh://monitor1-ssh#1) でのアップグレードコマンドが完了するまで待ってから、次のステップに進みます。

  ```output
  ...
  Upgraded cluster `tidb-demo` successfully
  ```

### 手順 4. アップグレード結果を確認します

+ クラスタのステータスを取得するコマンドを実行し、クラスタのバージョンが v8.1.1 であることを確認します。

  ```bash
  tiup cluster display tidb-demo
  ```
  ```output
  Cluster type:       tidb
  Cluster name:       tidb-demo
  Cluster version:    v8.1.1
  Deploy user:        ec2-user
  SSH type:           builtin
  Dashboard URL:      http://18.138.239.33:2379/dashboard
  Grafana URL:        http://10.90.4.8:3000
  ID                Role          Host         Ports        OS/Arch       Status  Data Dir                      Deploy Dir
  --                ----          ----         -----        -------       ------  --------                      ----------
  10.90.4.8:9093    alertmanager  10.90.4.8    9093/9094    linux/x86_64  Up      /tidb-data/alertmanager-9093  /tidb-deploy/alertmanager-9093
  10.90.4.8:3000    grafana       10.90.4.8    3000         linux/x86_64  Up      -                             /tidb-deploy/grafana-3000
  10.90.1.152:2379  pd            10.90.1.152  2379/2380    linux/x86_64  Up|L    /tidb-data/pd-2379            /tidb-deploy/pd-2379
  10.90.2.73:2379   pd            10.90.2.73   2379/2380    linux/x86_64  Up      /tidb-data/pd-2379            /tidb-deploy/pd-2379
  10.90.3.163:2379  pd            10.90.3.163  2379/2380    linux/x86_64  Up      /tidb-data/pd-2379            /tidb-deploy/pd-2379
  10.90.4.8:9090    prometheus    10.90.4.8    9090/12020   linux/x86_64  Up      /tidb-data/prometheus-9090    /tidb-deploy/prometheus-9090
  10.90.2.180:4000  tidb          10.90.2.180  4000/10080   linux/x86_64  Up      -                             /tidb-deploy/tidb-4000
  10.90.3.89:4000   tidb          10.90.3.89   4000/10080   linux/x86_64  Up      -                             /tidb-deploy/tidb-4000
  10.90.1.88:20160  tikv          10.90.1.88   20160/20180  linux/x86_64  Up      /tidb-data/tikv-20160         /tidb-deploy/tikv-20160
  10.90.2.20:20160  tikv          10.90.2.20   20160/20180  linux/x86_64  Up      /tidb-data/tikv-20160         /tidb-deploy/tikv-20160
  10.90.3.69:20160  tikv          10.90.3.69   20160/20180  linux/x86_64  Up      /tidb-data/tikv-20160         /tidb-deploy/tikv-20160
  10.90.1.60:6000   tiproxy       10.90.1.60   6000/3080    linux/x86_64  Up      -                             /tidb-deploy/tiproxy-6000
  Total nodes: 12
  ```

+ [ターミナル 2](ssh://monitor1-ssh#2) と [ターミナル 3](ssh://monitor1-ssh#3) で <kbd>Ctrl</kbd>+<kbd>C</kbd> を押して、両方のワークロードを停止します。

## 結論

TiDB サーバーは SQL レイヤーの接続を処理するため、オンラインアップグレードを行うことが TiKV や PD をアップグレードするよりも難しいです。この演習は、TiProxy の支援を受けて、そのような計画されたダウンタイムを回避できることを証明しています。TiDB サーバーをアップグレードする前に、それらは Placement Driver から情報を取得し、アップグレードされるサーバーを特定します。その前に、TiProxy は影響を受けるサーバーのすべてのセッションを他の TiDB サーバーに移行します。したがって、1 つずつ、すべての TiDB サーバーがアップグレードされるまで行われます。このようにして、クライアント セッションの中断を伴わない TiDB クラスタ全体のアップグレードが完了しました。データベースのダウンタイムとアプリケーションのダウンタイムは、ゼロでした。

TiDB Cloud を使用している場合、すべての機能は、TiProxy のセッション管理を含め、すぐに利用可能です。TiDB Cloud で、あなたの TiDB クラスタに対して TiProxy を有効または無効にするよう PingCAP にリクエストすることができます。

```hbsptform
{
  "ui": {
    "titleLevel": 3
  },
  "portalId": "4466002",
  "formId": "62bfb32a-a60a-4f9d-b2dc-1107a93db568",
  "region": "na1",
  "sfdcCampaignId": "701RC00000NdFlAYAV"
}
```