Thread: Using connection after fork
I'm looking at a database-using program (PostgreSQL/libpq and MySQL) which does the following: A daemon process opens a database connection, forks children on request, and those children access the database using that inherited connection. After one request, the child dies. It seems to me that this connection sharing cannot work because the processes would get mixed up, but the author claims that he has tested this successfully. I've been trying to figure out the semantics from the libc documentation, but I can't find a definitive answer. Does anyone know what will happen in this situation, and why it actually appears to work?
On Aug 10, 2004, at 4:41 AM, Peter Eisentraut wrote: > does the following: A daemon process opens a database connection, > forks > children on request, and those children access the database using that > inherited connection. After one request, the child dies. It seems to > me I've been bit by this sort of thing before. When you fork() the child inherits all the file descriptors , including the one connected to PG. But when the child dies that FD will be closed, thus it will also be closed in the parent causing "odd behavior". (At least, that is what I've seen in my apps) > that this connection sharing cannot work because the processes would > get > mixed up, but the author claims that he has tested this successfully. > I've > been trying to figure out the semantics from the libc documentation, > but I > can't find a definitive answer. Does anyone know what will happen in > this > situation, and why it actually appears to work? > Does it work for sustained periods of time? Is the parent reconnecting to PG after each child dies? It *shouldn't* work. -- Jeff Trout <jeff@jefftrout.com> http://www.jefftrout.com/ http://www.stuarthamm.net/
Peter Eisentraut <peter_e@gmx.net> writes: > I'm looking at a database-using program (PostgreSQL/libpq and MySQL) which > does the following: A daemon process opens a database connection, forks > children on request, and those children access the database using that > inherited connection. After one request, the child dies. It seems to me > that this connection sharing cannot work because the processes would get > mixed up, I agree, unless there is some interlock that prevents a new child from being spawned before the last previous one died. It would seem to work under light load where that happened anyway. > but the author claims that he has tested this successfully. I've > been trying to figure out the semantics from the libc documentation, but I > can't find a definitive answer. Does anyone know what will happen in this > situation, and why it actually appears to work? I'll bet lunch that he simply has not stress-tested it hard enough to have multiple children actually using the connection at the same time. I can positively guarantee that it won't work if you do. It would also not work with SSL, since the encryption state would get out of sync. And some secondary features like tracking the current transaction state could get out of sync too. But the basic query-issuing cycle would probably appear to work as long as only one child actually had a query in progress at any instant. regards, tom lane
Jeff <threshar@torgo.978.org> writes: > I've been bit by this sort of thing before. When you fork() the child > inherits all the file descriptors , including the one connected to PG. > But when the child dies that FD will be closed, thus it will also be > closed in the parent causing "odd behavior". (At least, that is what > I've seen in my apps) That would only happen if the child explicitly does PQfinish() before exiting, so that the backend sees an 'X' (Terminate) command arrive and therefore cuts the connection from its end. If the child just exits the pipe or TCP connection will remain open. regards, tom lane