From: Andres Salomon Date: 2004-10-14T07:24:37+09:00 Subject: Re: ruby-mysql issues and persistence On Thu, 14 Oct 2004 06:47:09 +0900, Florian G. Pflug wrote: > Andres Salomon wrote: > >>I have some code that triggers a race somewhere in mysql. Basically, what >>happens is this (all in ruby code): >> >>1) using ruby-dbi w/ the mysql DBD, a connection is made to a database. >>2) fork() is called >>3) the child process redirects std{in,out,err} to /dev/null, and then runs >>a SQL query; SET AUTOCOMMIT=1 >>4) the child process runs another SQL query; this one is an INSERT. >>5) the parent process exits. This exit calls all finalizers on objects in >>the parent's memory, including free_mysql() (from mysql-ruby, free_mysql >>is set as a callback inside init() via Data_Make_Struct()). free_mysql() >>closes the mysql connection. >>6) if timed correctly, the INSERT from step 4 hangs indefinitely. >> >> > I don't think its a good idea to use the same database connection from > two different processes. > Either create a new connection for the child, or (if it absolutly _has_ > to be the same connection) connect to some > query-multiplexer from both processes. Right; the problem is, how does one handle that, post-fork? I don't think closing the Mysql connection before the fork, and then opening two connections to the Mysql server after the fork is the optimal solution. If the connection is left open before the fork, after the fork whichever one of the processes exits first will destroy the connection for the other process. > > I guess what happens is that when the first process shuts down, it > signals the mysql backend "end of connection". The backend thus believe > the connection to be lost, and never reports a status back to the second > process - thus it hangs forever, waiting for a sucess or failure message > concerning the insert. It's actually inside mysql that the connection hangs, though. Doing a 'show processlist;' on the database shows the active connection (0 seconds idle), so mysqld thinks it's doing *something*.