## モジュール 2: DC2 のネットワークアクセスを遮断してセカンダリ DC の故障をシミュレートする

この演習の目的は、データセンター2を完全に利用できない状態にシミュレートし、TiDBクラスタの状態を観察し、それを復元することです。

  ![60%](https://lab-static.pingcap.com/quick-demo/demo-303-5-en.png)

データセンター2の障害をシミュレートする方法は、データセンター1とデータセンター2間のネットワーク通信を切断することです。これにより、データセンター2のサーバーが外部からの要求を受信したり応答したりするのを防ぎ、データセンター1から見るとデータセンター2が完全に故障したかのように見えます。

### 手順 1. DC1 のモニターサーバーに接続します

+ [ターミナル1](ssh://az1monitor1-ssh#1) を開き、データセンター1のmonitor1に接続します。

### 手順 2. ワークロードを開始します

+ `sysbench`を開始してアプリケーションとして動作させます。開始後、次のステップに進みます。

  ```bash
  sysbench --config-file=sysbench_config oltp_read_write --tables=6 --mysql-ignore-errors=all run
  ```

  ```output
  sysbench 1.0.17 (using bundled LuaJIT 2.1.0-beta2)

  Running the test with following options:
  Number of threads: 1
  Report intermediate results every 1 second(s)
  Initializing random number generator from current time

  Initializing worker threads...

  Threads started!

  [ 1s ] thds: 1 tps: 61.90 qps: 1240.90 (r/w/o: 868.53/247.58/124.79) lat (ms,95%): 18.28 err/s: 0.00 reconn/s: 0.00
  [ 2s ] thds: 1 tps: 58.02 qps: 1176.46 (r/w/o: 824.32/236.09/116.04) lat (ms,95%): 18.28 err/s: 0.00 reconn/s: 0.00
  ...
  ```

### 手順 3. レプリケーション状態が同期していることを確認します

+ [ターミナル2](ssh://az1monitor1-ssh#2) を開き、DC1のmonitor1に接続して、データレプリケーションの状態が「sync」モードであることを確認します。

+ データレプリケーションの状態を確認します。

  ```bash
  curl ${HOST_AZ1PD1_PRIVATE_IP}:2379/pd/api/v1/replication_mode/status
  ```

  ```output
  {
   "mode": "dr-auto-sync",
   "dr-auto-sync": {
     "label_key": "dc",
     "state": "sync",
     "state_id": 1006,
     "acid_consistent": true
   }
  }
  ```

### 手順 4. DC2（アベイラビリティゾーン2）へのネットワークアクセスをブロックします

+ スクリプトを実行して、サブネット`demo-subnet-2`（AZ2内のサブネット10.90.2.0/24）をブロックすることによって完全なアベイラビリティゾーンの故障をシミュレートします。

  ```bash
  VPC_ID=`aws ec2 describe-vpcs --filters "Name=tag:Name,Values=${LAB:USER_UNIQUE_TAG}" --query "Vpcs[0].VpcId" --output text --region ${LAB:REGION_CODE}`
  SUBNET_ID=`aws ec2 describe-subnets --filters "Name=vpc-id,Values=${VPC_ID}" "Name=tag:Name,Values=demo-subnet-2" --query "Subnets[0].SubnetId" --output text --region ${LAB:REGION_CODE}`
  CAGE_NACL_ID=`aws ec2 describe-network-acls --filters "Name=vpc-id,Values=${VPC_ID}" "Name=default,Values=false" "Name=tag:Name,Values=cage" --query "NetworkAcls[0].NetworkAclId" --output text --region ${LAB:REGION_CODE}`
  ASSOC_ID=`aws ec2 describe-network-acls --filters "Name=vpc-id,Values=${VPC_ID}" "Name=default,Values=true" --query "NetworkAcls[0].Associations" --output text --region ${LAB:REGION_CODE} | grep ${SUBNET_ID} | awk -F" " '{print $1}'`
  aws ec2 replace-network-acl-association --association-id ${ASSOC_ID} --network-acl-id ${CAGE_NACL_ID} --region ${LAB:REGION_CODE}
  ```

  ```output
  {
  "NewAssociationId": "aclassoc-0402a6103febf799f"
  }
  ```

### 手順 5. アプリケーションと TiDB の状態を観察します

+ [ターミナル1](ssh://az1monitor1-ssh#1)に戻り、sysbenchがTiDBクラスタへのアクセスを約70秒間ブロックされることを確認します。これは、ブロッキングウィンドウ設定（デフォルト設定は60秒）よりも少し長い時間です。理由は、TiDBクラスタがネットワーク状態を収集し、TiDBクラスタの状態を処理し、各TiKVノードに状態を同期するための時間が必要だからです。

  ```output
  ...
  [ 493s ] thds: 6 tps: 278.00 qps: 5525.08 (r/w/o: 3866.05/1082.02/577.01) lat (ms,95%): 26.68 err/s: 0.00 reconn/s: 0.00
  [ 494s ] thds: 6 tps: 274.99 qps: 5505.84 (r/w/o: 3853.89/1079.97/571.98) lat (ms,95%): 27.17 err/s: 0.00 reconn/s: 0.00
  [ 495s ] thds: 6 tps: 271.99 qps: 5447.84 (r/w/o: 3814.89/1065.97/566.98) lat (ms,95%): 28.67 err/s: 0.00 reconn/s: 0.00
  [ 496s ] thds: 6 tps: 70.00 qps: 1406.04 (r/w/o: 985.03/278.01/143.00) lat (ms,95%): 28.16 err/s: 0.00 reconn/s: 0.00
  [ 497s ] thds: 6 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
  [ 498s ] thds: 6 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
  ...
  [ 544s ] thds: 6 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
  [ 545s ] thds: 6 tps: 0.00 qps: 29.00 (r/w/o: 26.00/0.00/3.00) lat (ms,95%): 0.00 err/s: 3.00 reconn/s: 0.00
  [ 546s ] thds: 6 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
  ...
  [ 566s ] thds: 6 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
  [ 567s ] thds: 6 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
  [ 568s ] thds: 6 tps: 98.00 qps: 1968.01 (r/w/o: 1376.00/388.00/204.00) lat (ms,95%): 25.74 err/s: 0.00 reconn/s: 0.00
  ...
  [ 569s ] thds: 6 tps: 244.00 qps: 4883.91 (r/w/o: 3418.93/950.98/513.99) lat (ms,95%): 24.38 err/s: 0.00 reconn/s: 0.00
  [ 570s ] thds: 6 tps: 237.00 qps: 4734.95 (r/w/o: 3313.96/924.99/495.99) lat (ms,95%): 26.68 err/s: 0.00 reconn/s: 0.00
  [ 571s ] thds: 6 tps: 264.02 qps: 5279.31 (r/w/o: 3693.21/1039.06/547.03) lat (ms,95%): 30.26 err/s: 0.00 reconn/s: 0.00
  ...
  ```

+ [ターミナル2](ssh://az1monitor1-ssh#2)に戻り、TiDBクラスタ内のノードの状態を観察します。DC2に配置されているノードはすべてダウンしています。

  ```bash
  tiup cluster display tidb-demo
  ```

  ```output
  Cluster type:       tidb
  Cluster name:       tidb-demo
  Cluster version:    v${LAB:TIDB_VERSION}
  Deploy user:        ec2-user
  SSH type:           builtin
  Dashboard URL:      http://18.236.254.103:2379/dashboard
  Grafana URL:        http://10.90.1.90:3000,http://10.90.2.17:3000
  ID                 Role        Host         Ports        OS/Arch       Status        Data Dir                    Deploy Dir
  --                 ----        ----         -----        -------       ------        --------                    ----------
  10.90.1.90:3000    grafana     10.90.1.90   3000         linux/x86_64  Up            -                           /tidb-deploy/grafana-3000
  10.90.2.17:3000    grafana     10.90.2.17   3000         linux/x86_64  Down          -                           /tidb-deploy/grafana-3000
  10.90.1.176:2379   pd          10.90.1.176  2379/2380    linux/x86_64  Up|L          /tidb-data/pd_data          /tidb-deploy/pd-2379
  10.90.1.73:2379    pd          10.90.1.73   2379/2380    linux/x86_64  Up            /tidb-data/pd_data          /tidb-deploy/pd-2379
  10.90.2.198:2379   pd          10.90.2.198  2379/2380    linux/x86_64  Down          /tidb-data/pd_data          /tidb-deploy/pd-2379
  10.90.1.90:10090   prometheus  10.90.1.90   10090/12020  linux/x86_64  Up            /tidb-data/prometheus_data  /tidb-deploy/prometheus-10090
  10.90.2.17:10090   prometheus  10.90.2.17   10090/12020  linux/x86_64  Down          /tidb-data/prometheus_data  /tidb-deploy/prometheus-10090
  10.90.1.106:4000   tidb        10.90.1.106  4000/10080   linux/x86_64  Up            -                           /tidb-deploy/tidb-4000
  10.90.2.61:4000    tidb        10.90.2.61   4000/10080   linux/x86_64  Down          -                           /tidb-deploy/tidb-4000
  10.90.1.245:20160  tikv        10.90.1.245  20160/20180  linux/x86_64  Up            /tidb-data/tikv_data        /tidb-deploy/tikv-20160
  10.90.1.45:20160   tikv        10.90.1.45   20160/20180  linux/x86_64  Up            /tidb-data/tikv_data        /tidb-deploy/tikv-20160
  10.90.2.125:20160  tikv        10.90.2.125  20160/20180  linux/x86_64  Disconnected  /tidb-data/tikv_data        /tidb-deploy/tikv-20160
  10.90.2.96:20160   tikv        10.90.2.96   20160/20180  linux/x86_64  Disconnected  /tidb-data/tikv_data        /tidb-deploy/tikv-20160
  Total nodes: 13
  ```

+ TiDBの同期モードが、`sync`から`async_wait`、そして`async`というように変化するのを観察します。`async_wait`の期間中、pdはすべてのtikvノードにモード切り替え指示を送信します。このプロセスが完了すると、同期モードは`async`に移行します。

  ```bash
  curl ${HOST_AZ1PD1_PRIVATE_IP}:2379/pd/api/v1/replication_mode/status
  ```

  ```output
  {
   "mode": "dr-auto-sync",
   "dr-auto-sync": {
     "label_key": "dc",
     "state": "sync",
     "state_id": 1006,
     "acid_consistent": true
   }
  }
  ```

  ```bash
  curl ${HOST_AZ1PD1_PRIVATE_IP}:2379/pd/api/v1/replication_mode/status
  ```

  ```output
  {
   "mode": "dr-auto-sync",
   "dr-auto-sync": {
     "label_key": "dc",
     "state": "async_wait",
     "state_id": 1001,
     "acid_consistent": true
   }
  }
  ```

  ```bash
  curl ${HOST_AZ1PD1_PRIVATE_IP}:2379/pd/api/v1/replication_mode/status
  ```

  ```output
  {
   "mode": "dr-auto-sync",
   "dr-auto-sync": {
     "label_key": "dc",
     "state": "async",
     "state_id": 483,
     "acid_consistent": true
   }
  }
  ```

### 手順 6. DC2 のネットワークアクセスを復旧します

+ ネットワークを復旧します。以前失われたノードは再びTiDBクラスタに参加します。

  ```bash
  VPC_ID=`aws ec2 describe-vpcs --filters "Name=tag:Name,Values=${LAB:USER_UNIQUE_TAG}" --query "Vpcs[0].VpcId" --output text --region ${LAB:REGION_CODE}`
  echo $VPC_ID

  SUBNET_ID=`aws ec2 describe-subnets --filters "Name=vpc-id,Values=${VPC_ID}" "Name=tag:Name,Values=demo-subnet-2" --query "Subnets[0].SubnetId" --output text --region ${LAB:REGION_CODE}`
  echo $SUBNET_ID

  DEFAULT_NACL_ID=`aws ec2 describe-network-acls --filters "Name=vpc-id,Values=${VPC_ID}" "Name=default,Values=true" --query "NetworkAcls[0].NetworkAclId" --output text --region ${LAB:REGION_CODE}`
  echo $DEFAULT_NACL_ID

  ASSOC_ID=`aws ec2 describe-network-acls --filters "Name=vpc-id,Values=${VPC_ID}" "Name=default,Values=false" --query "NetworkAcls[0].Associations" --output text --region ${LAB:REGION_CODE} | grep ${SUBNET_ID} | awk -F" " '{print $1}'`
  echo $ASSOC_ID

  aws ec2 replace-network-acl-association --association-id ${ASSOC_ID} --network-acl-id ${DEFAULT_NACL_ID} --region ${LAB:REGION_CODE}
  ```

  ```output
  {
  "NewAssociationId": "aclassoc-0df1e05cfc70356a8"
  }
  ```

+ [ターミナル1](ssh://az1monitor1-ssh#1)に切り替えて、アプリケーションとTiDBクラスタの状態を観察します。`sysbench`は安定して動作しています。

  ```output
  [ 1039s ] thds: 6 tps: 268.99 qps: 5409.79 (r/w/o: 3787.85/1067.96/553.98) lat (ms,95%): 27.17 err/s: 0.00 reconn/s: 0.00
  [ 1040s ] thds: 6 tps: 273.01 qps: 5455.15 (r/w/o: 3814.11/1083.03/558.02) lat (ms,95%): 28.16 err/s: 0.00 reconn/s: 0.00
  [ 1041s ] thds: 6 tps: 265.00 qps: 5282.95 (r/w/o: 3702.96/1043.99/535.99) lat (ms,95%): 30.26 err/s: 0.00 reconn/s: 0.00
  ...
  [ 1105s ] thds: 6 tps: 260.00 qps: 5244.02 (r/w/o: 3669.02/1043.00/532.00) lat (ms,95%): 29.72 err/s: 0.00 reconn/s: 0.00
  [ 1106s ] thds: 6 tps: 267.99 qps: 5339.86 (r/w/o: 3740.90/1052.97/545.99) lat (ms,95%): 27.17 err/s: 0.00 reconn/s: 0.00
  ```

+ TiDBクラスタの状態を確認します。DC2内のすべてのノードは再びオンラインになります。手順を迅速に進行すると、いくつかのTiKVノードの状態が`Disconnected`から`Up`に徐々に変わるのを観察するかもしれません。

  ```bash
  tiup cluster display tidb-demo
  ```

  ```output
  Cluster type:       tidb
  Cluster name:       tidb-demo
  Cluster version:    v${LAB:TIDB_VERSION}
  Deploy user:        ec2-user
  SSH type:           builtin
  Dashboard URL:      http://35.92.147.161:2379/dashboard
  Grafana URL:        http://10.90.1.212:3000,http://10.90.2.99:3000
  ID                 Role        Host         Ports        OS/Arch       Status        Data Dir                    Deploy Dir
  --                 ----        ----         -----        -------       ------        --------                    ----------
  10.90.1.212:3000   grafana     10.90.1.212  3000         linux/x86_64  Up            -                           /tidb-deploy/grafana-3000
  10.90.2.99:3000    grafana     10.90.2.99   3000         linux/x86_64  Up            -                           /tidb-deploy/grafana-3000
  10.90.1.156:2379   pd          10.90.1.156  2379/2380    linux/x86_64  Up            /tidb-data/pd_data          /tidb-deploy/pd-2379
  10.90.1.232:2379   pd          10.90.1.232  2379/2380    linux/x86_64  Up|L          /tidb-data/pd_data          /tidb-deploy/pd-2379
  10.90.2.104:2379   pd          10.90.2.104  2379/2380    linux/x86_64  Up            /tidb-data/pd_data          /tidb-deploy/pd-2379
  10.90.1.212:10090  prometheus  10.90.1.212  10090/12020  linux/x86_64  Up            /tidb-data/prometheus_data  /tidb-deploy/prometheus-10090
  10.90.2.99:10090   prometheus  10.90.2.99   10090/12020  linux/x86_64  Up            /tidb-data/prometheus_data  /tidb-deploy/prometheus-10090
  10.90.1.23:4000    tidb        10.90.1.23   4000/10080   linux/x86_64  Up            -                           /tidb-deploy/tidb-4000
  10.90.2.122:4000   tidb        10.90.2.122  4000/10080   linux/x86_64  Up            -                           /tidb-deploy/tidb-4000
  10.90.1.178:20160  tikv        10.90.1.178  20160/20180  linux/x86_64  Up            /tidb-data/tikv_data        /tidb-deploy/tikv-20160
  10.90.1.6:20160    tikv        10.90.1.6    20160/20180  linux/x86_64  Up            /tidb-data/tikv_data        /tidb-deploy/tikv-20160
  10.90.2.250:20160  tikv        10.90.2.250  20160/20180  linux/x86_64  Disconnected  /tidb-data/tikv_data        /tidb-deploy/tikv-20160
  10.90.2.90:20160   tikv        10.90.2.90   20160/20180  linux/x86_64  Up            /tidb-data/tikv_data        /tidb-deploy/tikv-20160
  Total nodes: 13
  ```

  ```output
  ...
  ID                 Role        Host         Ports        OS/Arch       Status  Data Dir                    Deploy Dir
  --                 ----        ----         -----        -------       ------  --------                    ----------
  10.90.2.250:20160  tikv        10.90.2.250  20160/20180  linux/x86_64  Up      /tidb-data/tikv_data        /tidb-deploy/tikv-20160
  ...
  ```

+ 現在のTiDBクラスタのレプリケーション状態を確認します。わずか数秒で状態が`sync_recover`から`sync`に切り替わります。

![60%](https://lab-static.pingcap.com/quick-demo/demo-303-6-en.png)

+ `sync_recover`モード。

  ```bash
  curl ${HOST_AZ1PD1_PRIVATE_IP}:2379/pd/api/v1/replication_mode/status
  ```

  ```output
  {
   "mode": "dr-auto-sync",
   "dr-auto-sync": {
     "label_key": "dc",
     "state": "sync_recover",
     "state_id": 1009,
     "acid_consistent": false,
     "total_regions": 78,
     "recover_progress": 0.08974359
   }
  }
  ```

+ `sync`モード。

  ```bash
  curl ${HOST_AZ1PD1_PRIVATE_IP}:2379/pd/api/v1/replication_mode/status
  ```

  ```output
  {
   "mode": "dr-auto-sync",
   "dr-auto-sync": {
     "label_key": "dc",
     "state": "sync",
     "state_id": 1010,
     "acid_consistent": true
   }
  }
  ```

![60%](https://lab-static.pingcap.com/quick-demo/demo-303-61-en.png)

+ この時点で、TiDBは2つのデータセンター間のデータ同期をSYNC状態に復元し、データセンター故障に対するRPO=0の高い耐障害性を達成します。

### 手順 7. `sysbench` ワークロードを停止します

+ [ターミナル1](ssh://az1monitor1-ssh#1) に移動し、sysbenchのスレッドを終了してターミナル1を閉じます。

+ ターミナル2も閉じます。

### モジュール 2のまとめ

+ 上記の手順を通じて、TiDBが完全なDC2の故障とその高可用性への復旧を処理する過程全体をシミュレーションしました。
  + DC2が利用不可になると、TiDBは故障を確認するためにブロッキングウィンドウに入ります。このブロッキングウィンドウ中、データベースへのアプリケーションの読み書き操作は影響を受けます。
  + ブロッキングウィンドウを超えると、TiDBはDC1内のノードのみを使用して動作し、`async`状態に移行します。この時点で、アプリケーションの読み書き操作は正常に戻ります。
  + DC2が障害から復旧すると、TiDBは`sync_recover`状態に入り、DC1内のノードからDC2内のノードにデータを同期します。このプロセスは、アプリケーションアクセスのためのデータベースの可用性には影響しません。
  + データ同期が完了すると、TiDBクラスタは`sync`モードに戻ります。
