通信切断時のセッション挙動

(8.0.22)

サーバ: CentOS7
クライアント:CentOS7
リモートクライアントバージョン=5.6.47

セッション1: クライアントからリモート接続。更新後、コミットなし
セッション2: サーバからローカル接続。更新後、セッション1のコミット待ち
※インタフェースをOFFするセッションはコンソール接続

この状態でサーバかクライアントのインターフェイスOFF

set session innodb_lock_wait_timeout = 1073741824;
select @@session.innodb_lock_wait_timeout;


drop table tab1;
create table tab1(col1 int primary key,col2 int);
insert into tab1 values(1,1);

start transaction;

update tab1 set col1 = 2 where col1 = 1;
update tab1 set col1 = 3 where col1 = 1;

-- サーバとクライアントでパケット監視
tcpdump -A -i ens192 -nn src host 192.168.137.50 and dst host 192.168.137.66 and dst port 3306

確認結果:
①サーバ側インタフェースOFFの場合

2時間11分後セッション2でロック取得
この時間はTCP KeepAlive(デフォルト2時間)に由来する模様。

②クライアント側インタフェースOFFの場合
DBサーバのTCP KeepAliveを5分にして実行
echo 300 > /proc/sys/net/ipv4/tcp_keepalive_time
sysctl -n net.ipv4.tcp_keepalive_time

16分後セッション2でロック取得


結論:
mysqlクライアントのレイヤでKeepAliveはない。
通信不可クライアントからのロックはTCP KeepAlive(デフォルト2時間)経過後、解放される。

 

 

(19c)

サーバ: CentOS7
クライアント:CentOS7
リモートクライアントバージョン=12.1.0.2.0

セッション1: クライアントからリモート接続。更新後、コミットなし
セッション2: サーバからローカル接続。更新後、セッション1のコミット待ち
※インタフェースをOFFするセッションはコンソール接続

この状態でサーバかクライアントのインターフェイスOFF


set time on
set timing on

drop table tab1 purge;
create table tab1(col1 int primary key,col2 int);
insert into tab1 values(1,1);
commit;

update tab1 set col1 = 2 where col1 = 1;
update tab1 set col1 = 3 where col1 = 1;

 

-- サーバとクライアントでパケット監視
tcpdump -A -i ens160 -nn src host 192.168.137.50 and dst host 192.168.137.65 and dst port 1521

確認結果:
①サーバ側インタフェースOFFの場合


2時間11分後セッション2でロック取得
この時間はTCP KeepAlive(デフォルト2時間)に由来する模様。


②クライアント側インタフェースOFFの場合
DBサーバのTCP KeepAliveを5分にして実行
echo 300 > /proc/sys/net/ipv4/tcp_keepalive_time
sysctl -n net.ipv4.tcp_keepalive_time

16分後セッション2でロック取得


結論:
sqlplusクライアントのレイヤでKeepAliveはない。
通信不可クライアントからのロックはTCP KeepAlive(デフォルト2時間)経過後、解放される。

 

(13)

サーバ: CentOS8
クライアント:CentOS7
リモートクライアントバージョン=9.4.26

セッション1: クライアントからリモート接続。更新後、コミットなし
セッション2: サーバからローカル接続。更新後、セッション1のコミット待ち
※インタフェースをOFFするセッションはコンソール接続

この状態でサーバかクライアントのインターフェイスOFF

set lock_timeout = 0;
show lock_timeout;

\timing 1

drop table tab1;
create table tab1(col1 int primary key,col2 int);
insert into tab1 values(1,1);

start transaction;

update tab1 set col1 = 2 where col1 = 1;
update tab1 set col1 = 3 where col1 = 1;

-- サーバとクライアントでパケット監視
tcpdump -A -i ens192 -nn src host 192.168.137.50 and dst host 192.168.137.67 and dst port 5432

確認結果:
①サーバ側インタフェースOFFの場合


2時間14分後セッション2でロック取得
この時間はTCP KeepAlive(デフォルト2時間)に由来する模様。


②クライアント側インタフェースOFFの場合
DBサーバのTCP KeepAliveを5分にして実行
echo 300 > /proc/sys/net/ipv4/tcp_keepalive_time
sysctl -n net.ipv4.tcp_keepalive_time

16分後セッション2でロック取得

結論:
psqlクライアントのレイヤでKeepAliveはない。
通信不可クライアントからのロックはTCP KeepAlive(デフォルト2時間)経過後、解放される。

 

(2019)

サーバ: Windows Server 2019
クライアント:CentOS7
リモートクライアントバージョン=17.7.0001.1

セッション1: クライアントからリモート接続。更新後、コミットなし
セッション2: サーバからローカル接続。更新後、セッション1のコミット待ち
※インタフェースをOFFするセッションはコンソール接続

この状態でサーバかクライアントのインターフェイスOFF

set lock_timeout -1
select @@lock_timeout;

set statistics time on

drop table tab1;
create table tab1(col1 int primary key,col2 int);
insert into tab1 values(1,1);

begin transaction;

update tab1 set col1 = 2 where col1 = 1;
update tab1 set col1 = 3 where col1 = 1;

 

-- サーバとクライアントでパケット監視
tcpdump -A -i ens160 -nn src host 192.168.137.50 and dst host 192.168.137.61 and dst port 1433

-- Wiresharkフィルタ
ip.src == 192.168.137.50 and ip.dst == 192.168.137.61 and tcp.dstport == 1433


確認結果:
①サーバ側インタフェースOFFの場合

インタフェースがOFFとなった直後、セッション2がロックを取得する

②クライアント側インタフェースOFFの場合
sqlcmdクライアントのKeepAliveのタイミングでセッション2がロックを取得する(最大30秒)


結論:
sqlcmdクライアントのレイヤでKeepAliveがある(30秒)

サーバインタフェースのエラーの場合、通信不可クライアントのロックは即時で解放される。

クライアントインタフェースのエラーの場合、通信不可クライアントのロックはsqlcmd KeepAlive(30秒)以内に、解放される。