[pgcluster: 795] pgreplicateがSIGTERMで落とせません(PGCluster-1.1.1a)
Masanobu Yasui
yasui-m @ klab.org
2005年 8月 7日 (日) 03:01:52 JST
お世話になります。
安井と申します。
PGCluster-1.1.1a で pgreplicate の動作検証をしているのですが、以下のような問題がありましたの
でご相談させて頂けないでしょうか。
【動作環境】
Debian : 3.1 Sarge
LinuxKernel: 2.6.12.3
【現象】
pgreplicate起動後、一度でもReplication_Port(8001)で接続を受け付けると、その後SIGTERMで終了
できなくなります。(正確な挙動は若干違いますが、、、要約ということでなんとか)
【詳細】
replicate_main() では PGR_Create_Socket_Bind() でリスナを生成し、 select で接続待機をして
いますが、このリスナでAcceptしたsocketがリモートから切断された場合、なぜか リスナのselect
が rmask をセットして返ってきてしまうようです。
その結果、待機中の接続がないにもかかわらず replicate_loop() が呼ばれてしまい、BUSY_MODEの
まま PGR_Create_Acception で接続待ちをしているようです。この状態では SIGTERM が無視されて
しまうため、SIGQUIT等で終了するしかなくなってしまいます。
(psqlでクラスタDBに接続したままSIGTERMという手もありますが・・・・)
「処理の流れ」
--------------------------------------------------
replicate_main()
↓
select()
↓
(接続を受け付けてsockを生成)
↓
replicate_loop()
↓
PGR_Create_Acception()
↓
fork() & return
↓
select()
↓
(sockがリモートから切断される)
↓
replicate_loop()
↓
PGR_Create_Acception()
↓
(待機中の接続がないのでBUSY_MODEのままだんまり)
--------------------------------------------------
とりあえず、以下のようなパッチで リスナソケットを非ブロッキングモードにし、待機中の接続が
ない場合は replicate_main() に戻ってくるようにしてみましたが、この対応で問題がないかどうか
は微妙なのかなあと感じています(全体の挙動に影響するし、移植性の問題とかもありますし・・・)
既知の問題でしたらすいません。
次期バージョンでの対応予定等がございましたら、なにかしらの情報を頂けると幸いです。
よろしくお願い致します。
diff -ur pgcluster-1.1.1a/src/backend/libpq/pgcluster.c pgcluster-1.1.1a-patch/src/backend/libpq/pgcluster.c
--- pgcluster-1.1.1a/src/backend/libpq/pgcluster.c 2005-08-06 20:19:44.000000000 +0900
+++ pgcluster-1.1.1a-patch/src/backend/libpq/pgcluster.c 2005-08-07 01:48:35.000000000 +0900
@@ -206,6 +206,7 @@
size_t len = 0;
struct sockaddr_in addr;
int one = 1;
+ int fl = 0;
if ((*fdP = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
@@ -247,6 +248,18 @@
PGR_Close_Sock(fdP);
return STATUS_ERROR;
}
+ fl = fcntl(*fdP, F_GETFL);
+ if( fl == -1 )
+ {
+ PGR_Close_Sock(fdP);
+ return STATUS_ERROR;
+ }
+ if( fcntl(*fdP, F_SETFL, fl | O_NONBLOCK) == -1 )
+ {
+ PGR_Close_Sock(fdP);
+ return STATUS_ERROR;
+ }
+
return STATUS_OK;
}
@@ -257,10 +270,15 @@
struct sockaddr addr;
size_t len = 0;
int one = 1;
+ int fl = 0;
len = sizeof(struct sockaddr);
while ((sock = accept(fd,&addr,&len)) < 0)
{
+ if( (errno == EAGAIN) || (errno == EWOULDBLOCK) )
+ {
+ return STATUS_ERROR;
+ }
PGR_Close_Sock(&fd);
PGR_Create_Socket_Bind(&fd, hostName , portNumber);
}
@@ -273,6 +291,15 @@
{
return STATUS_ERROR;
}
+ fl = fcntl(sock, F_GETFL);
+ if( fl == -1 )
+ {
+ return STATUS_ERROR;
+ }
+ if( fcntl(sock, F_SETFL, fl & ~O_NONBLOCK) == -1 )
+ {
+ return STATUS_ERROR;
+ }
*sockP = sock;
return STATUS_OK;
diff -ur pgcluster-1.1.1a/src/pgcluster/pgrp/main.c pgcluster-1.1.1a-patch/src/pgcluster/pgrp/main.c
--- pgcluster-1.1.1a/src/pgcluster/pgrp/main.c 2005-03-02 10:24:28.000000000 +0900
+++ pgcluster-1.1.1a-patch/src/pgcluster/pgrp/main.c 2005-08-07 02:04:53.000000000 +0900
@@ -169,7 +169,11 @@
int rtn = 0;
bool exist_sys_log = false;
- PGR_Create_Acception(fd,&sock,"",Port_Number);
+ if( STATUS_OK != PGR_Create_Acception(fd,&sock,"",Port_Number) )
+ {
+ return(0);
+ }
+
pgid = getpgid(0);
pid = fork();
if (pid <0)
**************************************************************
KLab 株式会社(クラブかぶしきがいしゃ) http://www.klab.org/
Kラボラトリー: 安井真伸
**************************************************************
pgcluster メーリングリストの案内