TiDB 検証ライフ(6-ディスク障害の検証1)

# ディスク障害時にTiDBがリカバリをやってくれるか確かめてみます

障害には、さまざまなケースや影響範囲が考えられますので、まずは検証シナリオを決めようと思います。
どのデータを、どのタイミングで、どのような方法で、壊すのか。
また、どのような障害対策を期待できるか、などなど。

##　そもそもTiDBは物理データをどこに保存しているか

SST(Sorted String Table)ファイルにデータ保存するとマニュアルにありました。
メモリのデータがある程度溜まったら、RocksDBがSSTにフラッシュしてくれるようです。
SSTファイルはレベル分けされるようで、あるレベルのSSTファイルのサイズが大きくなったら、複数SSTをマージし、レベルアップするようです。

###　おさらいとして、TiKVのアーキテクチャ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61975/c739373a-ed4e-f406-4604-04d8982c447d.png)

※　引用:　https://docs.pingcap.com/tidb/stable/rocksdb-overview

##　とりあえず、INSERT文実行しSSTファイルに書き込まれるか確認してみます

###　端末Aから、tikv-serverのwriteシステムコールを追ってみます

#### Dockerコンテナにログイン

```
(base) appurunoMacBook-Air:~ apple$ docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED        STATUS          PORTS                       NAMES
364aef630ecd   kindest/node:v1.21.1   "/usr/local/bin/entr…"   12 hours ago   Up 29 minutes   127.0.0.1:50709->6443/tcp   kind-control-plane
(base) appurunoMacBook-Air:~ apple$ docker exec -it 364aef630ecd /bin/bash
root@kind-control-plane:/# 
```

#### straceコマンドなど存在しなかったらインストール

```
root@kind-control-plane:/# apt-get update
root@kind-control-plane:/# apt-get install strace
root@kind-control-plane:/# apt-get install lsof
root@kind-control-plane:/# apt-get install vim
```

#### tikv-serverプロセスのプロセスIDを確認

```
root@kind-control-plane:/# ps -ef | grep tikv-server | grep -v grep
root        1892    1197  3 Dec10 ?        00:01:28 /tikv-server --pd=http://basic-pd:2379 --advertise-addr=basic-tikv-0.basic-tikv-peer.tidb-cluster.svc:20160 --addr=0.0.0.0:20160 --status-addr=0.0.0.0:20180 --advertise-status-addr=basic-tikv-0.basic-tikv-peer.tidb-cluster.svc:20180 --data-dir=/var/lib/tikv --capacity=0 --config=/etc/tikv/tikv.toml
```

####　tikv-serverプロセスのwriteシステムコールを追跡

straceコマンドの引数に上述のプロセスIDを指定し実行します。

```
root@kind-control-plane:/# strace -Tfe trace=write -p 1892
```

### 別端末Bから、TiDBへ接続しINSERTを実行します

####　tidb-cluster名前空間のサービスリストを確認

```
(base) appurunoMacBook-Air:~ apple$ kubectl get svc -n tidb-cluster
NAME                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)               AGE
basic-discovery          ClusterIP   10.96.96.27     <none>        10261/TCP,10262/TCP   9h
basic-grafana            ClusterIP   10.96.182.77    <none>        3000/TCP              9h
basic-monitor-reloader   ClusterIP   10.96.215.171   <none>        9089/TCP              9h
basic-pd                 ClusterIP   10.96.188.54    <none>        2379/TCP              9h
basic-pd-peer            ClusterIP   None            <none>        2380/TCP              9h
basic-prometheus         ClusterIP   10.96.146.74    <none>        9090/TCP              9h
basic-tidb               ClusterIP   10.96.12.186    <none>        4000/TCP,10080/TCP    9h
basic-tidb-peer          ClusterIP   None            <none>        10080/TCP             9h
basic-tikv-peer          ClusterIP   None            <none>        20160/TCP             9h
```

basic-tidbサービスはポート番号4000で待ち受けているようです。

####　ポート4000をフォーワード

```
(base) appurunoMacBook-Air:~ apple$ kubectl port-forward -n tidb-cluster svc/basic-tidb 4000 > pf4000.out &
[1] 969
```

####　mysqlコマンドでTiDBサーバに接続し、INSERTを実行します。

```
(base) appurunoMacBook-Air:~ apple$ mysql -h 127.0.0.1 -P 4000 -u root
mysql> use test;
mysql> create table test(id int);
mysql> insert into test values(1);

```

### 端末Aから、straceの出力を確認し、書き込み先ファイルを特定

####　strace出力で、writeシステムコールの抜粋
```
... ...
[pid  3059] write(28, "\tj\232w\242\0\0013\r\0\0\0\0\0\0\2\0\0\0\1\23\1\2\0\0\0\0\0\0\3\352\1"..., 169) = 169 <0.000892>
[pid  3061] write(40, "-\243\315.e\0\1\216\33\0\0\0\0\0\0\2\0\0\0\5\2$zt\200\0\0\0\0\0\0\377"..., 108) = 108 <0.011160>
... ...
```

どうやら、プロセスID3059,3061から、ファイルディスクリプター28、40に対し書き込みが行われたようです。

####　write先ファイルを特定

lsofコマンで、tikv-serverプロセスが開いている、ファイルディスクリプター28、40が何者か確認します。

```
root@kind-control-plane:/# lsof -p 1892 | grep -w 28w
tikv-serv 1892 root   28w      REG  254,1    241309 3018866 /var/lib/tikv/raft/000006.log
root@kind-control-plane:/# lsof -p 1892 | grep -w 40w
tikv-serv 1892 root   40w      REG  254,1    159865 3018951 /var/lib/tikv/db/000017.log
```

/var/lib/tikv/raft/000006.logはRaftログで、
/var/lib/tikv/db/000017.logはRocksDBログかなー。

###　単純にINSERT一発実行しただけでは、データがSSTに書き込まれないようです

処理されるデータ量が少ないため、メモリ上である程度データ溜まってから、SSTファイルにフラッシュされると推測されます。

##　SSTファイルにすぐデータを書き込みたいが、何か方法はないか

PingCAP社の資料からは見当たらないため、手っ取り早くSlackのask-tugチャンネルで聞いています。

##　終わりに
結局、ディスク障害検証は次回に持ち越しとなりそうです。
やはり、ストレージのメカニズムをきちんと理解してから、着手した方がよいかもです。。。