15 Jan 2012 13:11
John Deal <bassdeal@...>
2012-01-15 12:11:48 GMT
2012-01-15 12:11:48 GMT
I have continued to work on the MySQL multi-threaded issue but still no resolution. It works fine single-threaded (meaning setting the number of server threads to 1 in mira.conf).
I am convinced it has nothing to do with using prepared statements. This leaves either MySQL is not being initialized properly for multi-threaded operation or there are improperly shared variables between threads. The MySQL initialization is fairly simple and since we link the thread-safe library, no different than than single-threaded operation except for the added check that MySQL is thread-safe (which it comes back positive).
Each sever thread has its own instance of the DbMySqlDirectory (which is derived from DbDirectory) and each DbMySqlDirectory creates its own connection to the MySQL server so each thread has its own DB connection. The only shared variable is a first-time initialization flag which is controlled by an exclusive lock (in fact, the lock is not needed since this DbDirectory constructor is only currently called by main()). All other code uses local or instance-level variables.
I have added extensive debug code to my local version of mira_server. It displays the beginning and ending of DbMySqlDirectory methods indicating thread ID and instance address. This gives me a view into what threads are active and what DbMySqlDirectory instance they are using.
The scenario which constantly causes the server to crash is as follows:
3 users with 2 workplaces where each workplace has 2 members.
Login of one user (sometimes it takes two logins).
The server segfaults when DbMySqlDirectory.find_workplace(ID) is active with one thread and multiple DbMySqlDirectory.find_user(ID) are taking place. This is when the client has received information on one workplace the user belongs, issues commends to find out user details of all members of the workplace, and issues a command to get information on the second workplace the user belongs to. This results in one thread doing the find_workplace() and other threads doing find_user(). The crash happens on a mysql_stmt_execute() command which performs the actual query on the server. The stack is trashed so I don't get a stack trace. I suspect the bind variables used in the query are trashed either on the mira_server side or the MySQL server side (these bind variables contain pointer to where to put the resulting queried data). All queries involved are read-only (select).
I am not sure what to do at this point. I am out of ideas on resolving this issue. I could convert DbMySqlDirectory to use non-prepared queries or to use the C++ MySQL connector and see if that makes a difference. Both would require a substantial amount of rework and testing. I would prefer trying the C++ connector. I am not convinced that either would solve the problem but I am willing to do it.
I don't want to hold up the project any longer because of this issue. I propose that I fix some issues I found during my investigation and submit those to the dbBackend branch and we document that a MySQL-configured server must run with one client thread until I fix the problem.
If anyone would like to help me on this issue that would be great.
------------------------------------------------------------------------------ RSA(R) Conference 2012 Mar 27 - Feb 2 Save $400 by Jan. 27 Register now! http://p.sf.net/sfu/rsa-sfdev2dev2
_______________________________________________ Mira-development mailing list Mira-development@... https://lists.sourceforge.net/lists/listinfo/mira-development