IBM Cloud: Cloud Service Endpoint(CSE)利用時のtimeout/KeepAlive構成について

# はじめに

IBM CloudにおけるVPCのPublic Gateway(PGW)やCloud Service Endpoint(CSE)みたいなNATを行うGatewayには、idle connection timeoutが設定されており、[この記事](https://www.ibm.com/cloud/blog/troubleshooting-outgoing-connection-issues-with-ibm-vpc-public-and-service-gateways)によるとTCPでは`4分`である。
この`4分`が長いか短いかというのはさておき、NATなどに利用できるポート番号は有限であり、通信が確立された後に、何もデータが流れていない状況でずーっとコネクションが張られていても、もしかしたらクライアントやサーバーによってすでにエラーが発生したり通信を終了させてしまっている可能性もあるのだから、そんな曖昧な状態を放置したままにせずに明示的に切断するべきだとクラウドベンダーとして考えるのはネットワーク管理の視点では至極自然な考えだと思われる。実際、そのコネクション上で何かしらのデータのやり取りがあれば切断されることはないのだし、[その記事](https://www.ibm.com/cloud/blog/troubleshooting-outgoing-connection-issues-with-ibm-vpc-public-and-service-gateways)でも紹介されていたように、もし接続を切りたくないのであれば、[TCP KeepAlive](https://milestone-of-se.nesuke.com/nw-basic/as-nw-engineer/keepalive-tcp-http/)をアプリケーションやミドルウェア側で明示的に実行しておけばよいはずである。
では、IBM Cloudの各種サービスはどうなっているのか？ 当然そんな明確な仕様はdocsにも載っていないので、各サービスごとの実装に依存するのだろうが、実際にCSE接続をした際のパケットキャプチャーをチェックしてみたのがこの記事である。

# 結論
最初に結論を書いておく。(2022年12月16日時点での）実験結果としては、以下の通り。IBM Cloud上のサービスによって、サーバー側からTCP KeepAliveパケットを投げるかどうかは構成が変わっているとは思っていたが、同じDb2サービスでも実装の違いがあったのは驚きだった（もちろん、この結果は将来変わる可能性があると思われます）。

- IBM Cloud Databases for PostgreSQL: psqlコマンドで接続後に、DBサーバー側から定期的にTCP KeepAliveが実行される(112秒 or 113秒）ので、接続後に4分以上放置しても再度SQLをそのまま実行できた。
- Db2 on Cloud: clpplusコマンド接続後に、DBサーバー側から定期的にTCP KeepAliveが実行される(20秒 or 21秒)ので、接続後に4分以上放置しても再度SQLをそのまま実行できた。
- Db2 warehouse on Cloud: **clpplusコマンド接続後に、DBサーバー側からTCP KeepAliveは実行されない！** よって、接続後に4分以上放置した上で、再度SQLを実行すると接続エラー(`ERRORCODE=-4499`)になる。つまり、接続完了後に、4分以上clpplusの実行を放置したり、もしくは4分以上結果が返ってこないQueryを実行する可能性があり、idle connectionの切断を回避する必要性があるのであれば、OSの`net.ipv4.tcp_keepalive_time`(TCP コネクション開始から KeepAlive の送信を開始するまでの時間。Linuxではデフォルトで2時間であり、こんなに待たないと初回のKeepaliveパケットを投げない）などを調整する必要がある。


|  | idle connection timeout | 検証記事 |
|:-|:-|:-|
|Cloud Service Endpoint(CSE)|発生する（4分）。利用するサービス、使い方によってはKeepAlive構成が必要。 |今回記事|
|Public Gateway  |発生する（4分） 。利用するサービス、使い方によってはKeepAlive構成が必要。| [次回記事](https://qiita.com/testnin2/items/c4c16446972a8a623e2b)|
|Floating IP | 発生しない（少なくとも20分放置しても切れなかった）  | [次回記事](https://qiita.com/testnin2/items/c4c16446972a8a623e2b)|


参考記事:[Troubleshooting Outgoing Connection Issues with IBM VPC Public and Service Gateways](https://www.ibm.com/cloud/blog/troubleshooting-outgoing-connection-issues-with-ibm-vpc-public-and-service-gateways)


:::note
なお、以下の記事によると、Db2クライアントでは`KeepAliveTimeout`がデフォルト15秒で構成されているようなので、これが有効になっていてidle connectionが切断されることはないと思っていたのですが、確かにtcpdumpを見てもクライアントからTCP KeepAliveパケットが投げられることはありませんでした。実際に設定値を色々変えて試してみたのですが、やはり動きませんでした。
このリンク内の記述をよく見ると`This keyword is only supported for TCP/IP protocol`とも書かれています。Db2への接続には、TCPとSSLの両方がサポートされていますが、Db2 on CloudやDb2 warehouse on Cloudは(Legacy Planを除き）現在はSSL接続のみがサポートされているようですが。よって、もしかしたらSSL利用時にはこのキーワードは効いていないんじゃないかと想像しています。もし詳しい方がいらっしゃって、「それは間違っているよ、本当はこうだよ」、というご指摘があれば、コメントいただけると大変助かります。
- https://www.ibm.com/docs/en/db2/11.5?topic=keywords-keepalivetimeout
- https://www.ibm.com/support/pages/was-db2%E6%8E%A5%E7%B6%9A%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B-tcp-keepalive%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%A2%E3%82%A6%E3%83%88%E8%A8%AD%E5%AE%9A%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6was-13-002
:::


:::note
今回は、

`VSI(Client) -> [CSE] -> DB Service(Server)`

という接続だったので、VSIのKeepAliveを構成しましたが、例えばDirect Linkなどを経由して、

`Client -> [Direct Link] -> VSI(Proxy) -> [CSE] -> DB Service(Server)`

というような構成も考えられます。この場合は、当然VSI(Proxy)がCSE経由で接続するのですから、VSI(Proxy)での適切な構成が必要となります。OSの`net.ipv4.tcp_keepalive_time`を変更すると、そのOS上の全てに影響を与えますが、利用するProxy Softwareによっては自身でKeepAlive構成を変更できるものもあるため、影響範囲を最小化するためにもProxy Software側で構成する方が望ましいでしょう。例えば、HAProxyでは、`option tcpka`, `srvtcpka-idle`, `srvtcpka-intvl`, `srvtcpka-cnt`のようなKeepAliveを構成するオプション・パラメーターが存在します。また、一定時間idleが発生するとconnectionを切断する`timeout client`や`timeout server`も存在します。

https://cbonte.github.io/haproxy-dconv/2.5/configuration.html
:::

# 環境情報

今回はIBM Cloud上のLinuxからCSE経由で各種サービスに接続している。

```
[root@new-syasuda-tok1-vpc1 ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

[root@new-syasuda-tok1-vpc1 ~]# sysctl -a 2>/dev/null | grep keepalive
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_time = 7200
```

```txt:psqlバージョン
[root@new-syasuda-tok1-vpc1 ~]# psql --version
psql (PostgreSQL) 12.11
```

clpplusは`v11.5.4_linuxx64_dsdriver.tar.gz`を利用した。

```
[root@new-syasuda-tok1-vpc1 dsdriver]# db2level
DB21085I  This instance or install (instance name, where applicable: "*") uses
"64" bits and DB2 code release "SQL11054" with level identifier "0605010F".
Informational tokens are "DB2 v11.5.4.0", "s2006161200", "DYN2006161200AMD64",
and Fix Pack "0".
Product is installed at "/root/dsdriver/.".

[root@new-syasuda-tok1-vpc1 dsdriver]# java com.ibm.db2.jcc.DB2Jcc -version
IBM Data Server Driver for JDBC and SQLJ 4.27.25
```


# 1. IBM Cloud Databases for PostgreSQL（クライアント側設定で明示的にKeepAliveを指定しなかった場合）

```
[root@new-syasuda-tok1-vpc1 ~]# export LANG=C
[root@new-syasuda-tok1-vpc1 ~]# USERNAME=admin
[root@new-syasuda-tok1-vpc1 ~]# PASSWORD=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[root@new-syasuda-tok1-vpc1 ~]# PGPASSWORD=$PASSWORD PGSSLROOTCERT=631b75c3-4296-4ce9-b0f2-426423c5b0e6 psql "host=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxx.private.databases.appdomain.cloud port=31269 dbname=ibmclouddb user=$USERNAME sslmode=verify-full"
```

ssコマンドにて、-oオプションを付けるとtimer情報(keepAliveの情報)が確認できる。OS設定値では、`net.ipv4.tcp_keepalive_time`=7200(120分）なので、クライアントがTCP コネクション開始から KeepAliveパケットの送信を開始するまで、120分もかかる。


```
[root@new-syasuda-tok1-vpc1 ~]# ss -no 'dport == :31269'
Netid State      Recv-Q Send-Q                                                                          Local Address:Port                                                                                         Peer Address:Port
tcp   ESTAB      0      0                                                                                    10.0.0.4:40538                                                                                         166.9.40.96:31269               timer:(keepalive,120min,0)
```

しかし、以下のように常にDBサーバー側から112秒 or 113秒置きに、TCP KeepAliveが届く。
これのおかげで、たとえpsqlを最初に接続してから10分後にSQL Queryを実行しても問題なく実行できる。

```
[root@new-syasuda-tok1-vpc1 ~]# tcpdump -i any port 31269 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
21:06:27.448611 IP 166.9.40.96.31269 > 10.0.0.4.40538: Flags [.], ack 2058053111, win 131, options [nop,nop,TS val 3247790107 ecr 3131042062], length 0
21:06:27.448649 IP 10.0.0.4.40538 > 166.9.40.96.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3131153445 ecr 3247678688], length 0
21:08:20.086837 IP 166.9.40.96.31269 > 10.0.0.4.40538: Flags [.], ack 1, win 131, options [nop,nop,TS val 3247902742 ecr 3131153445], length 0
21:08:20.086874 IP 10.0.0.4.40538 > 166.9.40.96.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3131266083 ecr 3247678688], length 0
21:10:12.725534 IP 166.9.40.96.31269 > 10.0.0.4.40538: Flags [.], ack 1, win 131, options [nop,nop,TS val 3248015376 ecr 3131266083], length 0
21:10:12.725576 IP 10.0.0.4.40538 > 166.9.40.96.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3131378722 ecr 3247678688], length 0
21:12:05.364127 IP 166.9.40.96.31269 > 10.0.0.4.40538: Flags [.], ack 1, win 131, options [nop,nop,TS val 3248128010 ecr 3131378722], length 0
21:12:05.364165 IP 10.0.0.4.40538 > 166.9.40.96.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3131491360 ecr 3247678688], length 0
21:13:58.002357 IP 166.9.40.96.31269 > 10.0.0.4.40538: Flags [.], ack 1, win 131, options [nop,nop,TS val 3248240645 ecr 3131491360], length 0
21:13:58.002374 IP 10.0.0.4.40538 > 166.9.40.96.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3131603999 ecr 3247678688], length 0
21:15:50.646456 IP 166.9.40.96.31269 > 10.0.0.4.40538: Flags [.], ack 1, win 131, options [nop,nop,TS val 3248353279 ecr 3131603999], length 0
21:15:50.646495 IP 10.0.0.4.40538 > 166.9.40.96.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3131716643 ecr 3247678688], length 0
```

# 2. IBM Cloud Databases for PostgreSQL（クライアント側設定で明示的にKeepAliveを指定した場合）

[psqlで指定できるTCP KeepAlive設定](https://www.postgresql.org/docs/current/libpq-connect.html)

今回は、実験的に

- keepalives_idle=10 
- keepalives_interval=10 
- keepalives_count=1

で接続してみた。以下のように、keepAliveのtimerが10秒で設定されていることが確認できる。

```
[root@new-syasuda-tok1-vpc1 ~]# PGPASSWORD=$PASSWORD PGSSLROOTCERT=631b75c3-4296-4ce9-b0f2-426423c5b0e6 psql "host=80e3ecbb-ae81-4dfc-bb1c-1fd74754c106.c8gao0tt0nr65snb1shg.private.databases.appdomain.cloud port=31269 dbname=ibmclouddb user=$USERNAME sslmode=verify-full keepalives_idle=10 keepalives_interval=10 keepalives_count=1"
[root@new-syasuda-tok1-vpc1 ~]# ss -no 'dport == :31269'
Netid State      Recv-Q Send-Q                                                                          Local Address:Port                                                                                         Peer Address:Port
tcp   ESTAB      0      0                                                                                    10.0.0.4:47538                                                                                         166.9.42.56:31269               timer:(keepalive,9.278ms,0)
```


tcpdumpを取得した際にも、10秒おきにクライアント側からKeepAliveパケットを送っている。ただし、`21:00:02.434313`や`21:01:55.068956`のようにサーバー側からも112秒 or 113秒置きにKeepAliveパケットが送られていることも確認できる。

```
[root@new-syasuda-tok1-vpc1 ~]# tcpdump -i any port 31269 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
20:58:21.203356 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 2353913326, win 293, options [nop,nop,TS val 3130667200 ecr 553656685], length 0
20:58:21.207279 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553666688 ecr 3130657240], length 0
20:58:31.219359 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130677216 ecr 553666688], length 0
20:58:31.223432 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553676703 ecr 3130657240], length 0
20:58:41.235435 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130687232 ecr 553676703], length 0
20:58:41.239443 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553686719 ecr 3130657240], length 0
20:58:51.251359 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130697248 ecr 553686719], length 0
20:58:51.255123 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553696735 ecr 3130657240], length 0
20:59:01.267363 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130707264 ecr 553696735], length 0
20:59:01.271301 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553706750 ecr 3130657240], length 0
20:59:11.283347 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130717280 ecr 553706750], length 0
20:59:11.287515 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553716766 ecr 3130657240], length 0
20:59:21.299358 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130727296 ecr 553716766], length 0
20:59:21.303777 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553726782 ecr 3130657240], length 0
20:59:31.315350 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130737312 ecr 553726782], length 0
20:59:31.319383 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553736797 ecr 3130657240], length 0
20:59:41.331357 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130747328 ecr 553736797], length 0
20:59:41.335753 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553746813 ecr 3130657240], length 0
20:59:51.347347 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130757344 ecr 553746813], length 0
20:59:51.352781 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553756830 ecr 3130657240], length 0
21:00:01.363508 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130767360 ecr 553756830], length 0
21:00:01.367447 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553766844 ecr 3130657240], length 0
21:00:02.434313 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553767911 ecr 3130657240], length 0
21:00:02.434352 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130768430 ecr 553766844], length 0
21:00:11.379435 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130777376 ecr 553766844], length 0
21:00:11.383464 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553776860 ecr 3130768430], length 0
21:00:21.395348 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130787392 ecr 553776860], length 0
21:00:21.399532 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553786876 ecr 3130768430], length 0
21:00:31.411352 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130797408 ecr 553786876], length 0
21:00:31.415358 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553796891 ecr 3130768430], length 0
21:00:41.427354 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130807424 ecr 553796891], length 0
21:00:41.432525 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553806907 ecr 3130768430], length 0
21:00:51.443448 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130817440 ecr 553806907], length 0
21:00:51.447763 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553816923 ecr 3130768430], length 0
21:01:01.459347 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130827456 ecr 553816923], length 0
21:01:01.463615 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553826938 ecr 3130768430], length 0
21:01:11.475355 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130837472 ecr 553826938], length 0
21:01:11.479674 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553836954 ecr 3130768430], length 0
21:01:21.491347 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130847488 ecr 553836954], length 0
21:01:21.495322 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553846969 ecr 3130768430], length 0
21:01:31.507352 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130857504 ecr 553846969], length 0
21:01:31.511212 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553856985 ecr 3130768430], length 0
21:01:41.523404 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130867520 ecr 553856985], length 0
21:01:41.527451 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553867001 ecr 3130768430], length 0
21:01:51.539442 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130877536 ecr 553867001], length 0
21:01:51.543759 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553877016 ecr 3130768430], length 0
21:01:55.068956 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553880542 ecr 3130768430], length 0
21:01:55.068996 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130881065 ecr 553877016], length 0
21:02:01.555452 IP 10.0.0.4.47538 > 166.9.42.56.31269: Flags [.], ack 1, win 293, options [nop,nop,TS val 3130887552 ecr 553877016], length 0
21:02:01.559526 IP 166.9.42.56.31269 > 10.0.0.4.47538: Flags [.], ack 1, win 131, options [nop,nop,TS val 553887032 ecr 3130881065], length 0
```

# 3. Db2 on Cloudの場合


```
[root@new-syasuda-tok1-vpc1 dsdriver]# export LANG=C
[root@new-syasuda-tok1-vpc1 dsdriver]# source db2profile
[root@new-syasuda-tok1-vpc1 dsdriver]# clpplus -nw xxxxxxxx/xxxxxxxxxxxxxxxx@dashdb
CLPPlus: Version 1.6
Copyright (c) 2009, 2011, IBM CORPORATION.  All rights reserved.


Database Connection Information :
---------------------------------
Hostname =
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxx.private.databases.appd
omain.cloud
Database server = DB2/LINUXX8664  SQL110570
SQL authorization ID = 3c08afc5
Local database alias = DASHDB
Port = 30009
SQL> SELECT T.SERVICE_LEVEL FROM TABLE(ENV_GET_INST_INFO()) AS T;

SERVICE_LEVEL
--------------------------------------------------
DB2 v11.5.7.0
```

ssコマンドにて、-oオプションを付けるとtimer情報(keepAliveの情報)が確認できる。OS設定値では、`net.ipv4.tcp_keepalive_time`=7200(120分）なので、クライアントがTCP コネクション開始から KeepAliveパケットの送信を開始するまで、120分もかかる。

```
[root@new-syasuda-tok1-vpc1 ~]# ss -no 'dport == :30009'
Netid State      Recv-Q Send-Q                                                                          Local Address:Port                                                                                         Peer Address:Port
tcp   ESTAB      0      0                                                                           [::ffff:10.0.0.4]:34072                                                                                [::ffff:166.9.40.41]:30009               timer:(keepalive,120min,0)
```

しかし、以下のように常にDBサーバー側から20秒 or 21秒置きに、TCP KeepAliveパケットが届く。
これのおかげで、たとえclpplusで最初に接続してから10分後にSQL Queryを実行しても問題なく実行できる。


```
[root@new-syasuda-tok1-vpc1 ~]# tcpdump -i any port 30009 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
22:10:12.957802 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 152900632, win 139, options [nop,nop,TS val 461259365 ecr 3134958731], length 0
22:10:12.957841 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3134978954 ecr 461197858], length 0
22:10:33.181591 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461279589 ecr 3134978954], length 0
22:10:33.181624 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3134999178 ecr 461197858], length 0
22:10:53.405399 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461299812 ecr 3134999178], length 0
22:10:53.405437 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135019402 ecr 461197858], length 0
22:11:13.629180 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461320036 ecr 3135019402], length 0
22:11:13.629217 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135039625 ecr 461197858], length 0
22:11:33.852905 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461340259 ecr 3135039625], length 0
22:11:33.852940 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135059849 ecr 461197858], length 0
22:11:54.076854 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461360483 ecr 3135059849], length 0
22:11:54.076886 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135080073 ecr 461197858], length 0
22:12:14.300311 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461380706 ecr 3135080073], length 0
22:12:14.300346 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135100296 ecr 461197858], length 0
22:12:34.529982 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461400934 ecr 3135100296], length 0
22:12:34.530019 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135120526 ecr 461197858], length 0
22:12:54.747669 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461421153 ecr 3135120526], length 0
22:12:54.747706 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135140744 ecr 461197858], length 0
22:13:14.971429 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461441377 ecr 3135140744], length 0
22:13:14.971481 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135160968 ecr 461197858], length 0
22:13:35.195144 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461461601 ecr 3135160968], length 0
22:13:35.195182 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135181191 ecr 461197858], length 0
22:13:55.419010 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461481824 ecr 3135181191], length 0
22:13:55.419049 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135201415 ecr 461197858], length 0
22:14:15.646598 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461502052 ecr 3135201415], length 0
22:14:15.646633 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135221643 ecr 461197858], length 0
22:14:35.866318 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461522271 ecr 3135221643], length 0
22:14:35.866368 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135241862 ecr 461197858], length 0
22:14:56.089997 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461542495 ecr 3135241862], length 0
22:14:56.090032 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135262086 ecr 461197858], length 0
22:15:16.313790 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461562718 ecr 3135262086], length 0
22:15:16.313832 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135282310 ecr 461197858], length 0
22:15:36.541580 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461582946 ecr 3135282310], length 0
22:15:36.541620 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135302538 ecr 461197858], length 0
22:15:56.761211 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461603165 ecr 3135302538], length 0
22:15:56.761250 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135322757 ecr 461197858], length 0
22:16:16.984942 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461623389 ecr 3135322757], length 0
22:16:16.984975 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135342981 ecr 461197858], length 0
22:16:37.208639 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461643612 ecr 3135342981], length 0
22:16:37.208673 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135363205 ecr 461197858], length 0
22:16:57.432474 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461663836 ecr 3135363205], length 0
22:16:57.432511 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135383429 ecr 461197858], length 0
22:17:17.656120 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461684059 ecr 3135383429], length 0
22:17:17.656160 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135403652 ecr 461197858], length 0
22:17:37.879738 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461704283 ecr 3135403652], length 0
22:17:37.879772 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135423876 ecr 461197858], length 0
22:17:58.103533 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461724506 ecr 3135423876], length 0
22:17:58.103570 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135444100 ecr 461197858], length 0
22:18:18.327369 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461744730 ecr 3135444100], length 0
22:18:18.327408 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135464324 ecr 461197858], length 0
22:18:38.551031 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461764953 ecr 3135464324], length 0
22:18:38.551069 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135484547 ecr 461197858], length 0
22:18:58.774658 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461785177 ecr 3135484547], length 0
22:18:58.774693 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135504771 ecr 461197858], length 0
22:19:18.998591 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461805401 ecr 3135504771], length 0
22:19:18.998629 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135524995 ecr 461197858], length 0
22:19:39.222074 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461825624 ecr 3135524995], length 0
22:19:39.222108 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135545218 ecr 461197858], length 0
22:19:59.445861 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461845848 ecr 3135545218], length 0
22:19:59.445891 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135565442 ecr 461197858], length 0
22:20:19.669569 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461866071 ecr 3135565442], length 0
22:20:19.669603 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135585666 ecr 461197858], length 0
22:20:39.893458 IP 166.9.40.41.30009 > 10.0.0.4.34072: Flags [.], ack 1, win 139, options [nop,nop,TS val 461886295 ecr 3135585666], length 0
22:20:39.893492 IP 10.0.0.4.34072 > 166.9.40.41.30009: Flags [.], ack 1, win 436, options [nop,nop,TS val 3135605890 ecr 461197858], length 0
```
```txt:10分間放置した後に実行したSQLは成功。
SQL> select count(*) from syscat.tables;

          1
-----------
        528
```


# 4. Db2 warehouse on Cloudの場合



```
[root@new-syasuda-tok1-vpc1 dsdriver]# export LANG=C
[root@new-syasuda-tok1-vpc1 dsdriver]# source db2profile
[root@new-syasuda-tok1-vpc1 dsdriver]# clpplus -nw bluadmin/xxxxxxxxxxxxxxxxxxxxxxxxxxxxx@dashdb2
CLPPlus: Version 1.6
Copyright (c) 2009, 2011, IBM CORPORATION.  All rights reserved.


Database Connection Information :
---------------------------------
Hostname = xxxx-xxxxxxx.private.ap-north.db2w.cloud.ibm.com
Database server = DB2/LINUXX8664  SQL110570
SQL authorization ID = bluadmin
Local database alias = DASHDB2
Port = 50001
SQL> SELECT T.SERVICE_LEVEL FROM TABLE(ENV_GET_INST_INFO()) AS T;

SERVICE_LEVEL
--------------------------------------------------
DB2 v11.5.7.0
```

ssコマンドにて、-oオプションを付けるとtimer情報(keepAliveの情報)が確認できる。OS設定値では、`net.ipv4.tcp_keepalive_time`=7200(120分）なので、クライアントがTCP コネクション開始から KeepAliveパケットの送信を開始するまで、120分もかかる。

```
[root@new-syasuda-tok1-vpc1 ~]# ss -no 'dport == :50001'
Netid State      Recv-Q Send-Q                                                                          Local Address:Port                                                                                         Peer Address:Port
tcp   ESTAB      0      0                                                                           [::ffff:10.0.0.4]:54416                                                                               [::ffff:166.9.42.115]:50001               timer:(keepalive,120min,0)
```

しかし、DBサーバー側からもKeepAliveパケットは届かない。

```txt:tcpdumpの結果。KeepAliveパケットはDBサーバーから来ない。
[root@new-syasuda-tok1-vpc1 ~]# tcpdump -i any port 50001 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
（なし）
```

その結果、初期接続の後に、5分間clpplus上で何もしないで放置した状態から、再度SQL Queryを実行すると、idle connectionが切断されており、接続エラーになってしまう。

```txt:5分ぐらい待って実行した結果
SQL> select count(*) from syscat.tables;
ERROR near line 1:
[jcc][t4][2030][11211][4.27.25] A communication error occurred during operations
on the connection's underlying socket, socket input stream,
or socket output stream.  Error location: Reply.fill() - socketInputStream.read
(-1).  Message: Connection reset. ERRORCODE=-4499, SQLSTATE=08001
SQL> select count(*) from syscat.tables;
DB250201E: No database connection exists, but a database connection is required.
```


# 5. Db2 warehouse on Cloudの場合(net.ipv4.tcp_keepalive_timeを小さくした)

暫定で以下のように小さくしてみた（OS設定として恒久的に変更したくなかったので、今回は/proc/sysを更新）

```
[root@new-syasuda-tok1-vpc1 dsdriver]# echo 75 > /proc/sys/net/ipv4/tcp_keepalive_time
[root@new-syasuda-tok1-vpc1 dsdriver]# sysctl -a 2>/dev/null | grep keepalive
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_time = 75
```

```
[root@new-syasuda-tok1-vpc1 dsdriver]# clpplus -nw bluadmin/xxxxxxxxxxxxxxxxxxxxxxxxxxxxx@dashdb2
CLPPlus: Version 1.6
Copyright (c) 2009, 2011, IBM CORPORATION.  All rights reserved.


Database Connection Information :
---------------------------------
Hostname = xxxx-xxxxxxx.private.ap-north.db2w.cloud.ibm.com
Database server = DB2/LINUXX8664  SQL110570
SQL authorization ID = bluadmin
Local database alias = DASHDB2
Port = 50001
```

ssコマンドにて、-oオプションを付けるとtimer情報(keepAliveの情報が確認できる）。OS設定値では、net.ipv4.tcp_keepalive_time=75及びnet.ipv4.tcp_keepalive_intvl=75なので、timerもそれに応じて短くなっている。


```
[root@new-syasuda-tok1-vpc1 dsdriver]# ss -no 'dport == :50001'
Netid State      Recv-Q Send-Q                                                                          Local Address:Port                                                                                         Peer Address:Port
tcp   ESTAB      0      0                                                                           [::ffff:10.0.0.4]:54454                                                                               [::ffff:166.9.42.115]:50001               timer:(keepalive,1min15sec,0)
```

```txt:75秒おきにKeepAliveパケットがクライアントから送信されている。
[root@new-syasuda-tok1-vpc1 ~]# tcpdump -i any port 50001 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
23:11:50.246429 IP 10.0.0.4.54454 > 166.9.42.115.50001: Flags [.], ack 2813185602, win 362, options [nop,nop,TS val 3138676243 ecr 3906680083], length 0
23:11:50.249242 IP 166.9.42.115.50001 > 10.0.0.4.54454: Flags [.], ack 1, win 139, options [nop,nop,TS val 3906755083 ecr 3138601282], length 0
23:13:05.491414 IP 10.0.0.4.54454 > 166.9.42.115.50001: Flags [.], ack 1, win 362, options [nop,nop,TS val 3138751488 ecr 3906755083], length 0
23:13:05.493835 IP 166.9.42.115.50001 > 10.0.0.4.54454: Flags [.], ack 1, win 139, options [nop,nop,TS val 3906830324 ecr 3138601282], length 0
23:14:20.755450 IP 10.0.0.4.54454 > 166.9.42.115.50001: Flags [.], ack 1, win 362, options [nop,nop,TS val 3138826752 ecr 3906830324], length 0
23:14:20.758136 IP 166.9.42.115.50001 > 10.0.0.4.54454: Flags [.], ack 1, win 139, options [nop,nop,TS val 3906905585 ecr 3138601282], length 0
23:15:36.019412 IP 10.0.0.4.54454 > 166.9.42.115.50001: Flags [.], ack 1, win 362, options [nop,nop,TS val 3138902016 ecr 3906905585], length 0
23:15:36.022013 IP 166.9.42.115.50001 > 10.0.0.4.54454: Flags [.], ack 1, win 139, options [nop,nop,TS val 3906980846 ecr 3138601282], length 0
23:16:51.283440 IP 10.0.0.4.54454 > 166.9.42.115.50001: Flags [.], ack 1, win 362, options [nop,nop,TS val 3138977280 ecr 3906980846], length 0
23:16:51.286213 IP 166.9.42.115.50001 > 10.0.0.4.54454: Flags [.], ack 1, win 139, options [nop,nop,TS val 3907056107 ecr 3138601282], length 0
23:18:06.547423 IP 10.0.0.4.54454 > 166.9.42.115.50001: Flags [.], ack 1, win 362, options [nop,nop,TS val 3139052544 ecr 3907056107], length 0
23:18:06.550153 IP 166.9.42.115.50001 > 10.0.0.4.54454: Flags [.], ack 1, win 139, options [nop,nop,TS val 3907131367 ecr 3138601282], length 0
23:19:21.811420 IP 10.0.0.4.54454 > 166.9.42.115.50001: Flags [.], ack 1, win 362, options [nop,nop,TS val 3139127808 ecr 3907131367], length 0
23:19:21.813722 IP 166.9.42.115.50001 > 10.0.0.4.54454: Flags [.], ack 1, win 139, options [nop,nop,TS val 3907206628 ecr 3138601282], length 0
23:20:37.076346 IP 10.0.0.4.54454 > 166.9.42.115.50001: Flags [.], ack 1, win 362, options [nop,nop,TS val 3139203073 ecr 3907206628], length 0
23:20:37.078785 IP 166.9.42.115.50001 > 10.0.0.4.54454: Flags [.], ack 1, win 139, options [nop,nop,TS val 3907281890 ecr 3138601282], length 0
```

10分後もSQL Queryは実行できた。

```txt:10分ぐらい待って実行した結果。
SQL> select count(*) from syscat.tables;

                                1
---------------------------------
                             1089
```