dbTalk Databases Forums  

Do I need thread-specific memory?

comp.databases.mysql comp.databases.mysql


Discuss Do I need thread-specific memory? in the comp.databases.mysql forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Gary Mills
 
Posts: n/a

Default Do I need thread-specific memory? - 11-06-2010 , 01:34 PM






I have a daemon that's both an RPC server and a Mysql client. The
daemon is linked with libmysqlclient_r.so.12. The Mysql server runs
mysql-4.0.18. The daemon maintains a cache of connections to the
Mysql server. It spawns a thread in response to each incoming RPC
request, using one of the existing connections to make an SQL query.

The thread that initiates the connection calls mysql_init() and
mysql_real_connect(). Internally, the Mysql library also calls
mysql_thread_init() to allocate a block of memory. This thread
eventually terminates, leaving that memory behind. Another thread
uses the connection to make an SQL query, but this one does not
allocate thread-specific memory. It terminates without a memory leak.
Yet another thread closes the connection with mysql_close() and
terminates. This one also has no thread-specific memory.

The Mysql documentation recommends calling mysql_thread_end() to free
the thread-specific memory, but that method doesn't seem to fit this
threading model. The easy fix is to call mysql_thread_end()
immediately after mysql_init() in the function that creates the
connection. That eliminates the memory leak. The daemon still works.
Now none of the threads have thread-specific memory. Is this a
dangerous thing to do? Is there a better way to handle this
situation?

--
-Gary Mills- -Unix Group- -Computer and Network Services-

Reply With Quote
  #2  
Old   
Axel Schwenke
 
Posts: n/a

Default Re: Do I need thread-specific memory? - 11-08-2010 , 02:09 AM






Gary Mills <mills (AT) cc (DOT) umanitoba.ca> wrote:
Quote:
I have a daemon that's both an RPC server and a Mysql client. The
daemon is linked with libmysqlclient_r.so.12. The Mysql server runs
mysql-4.0.18. The daemon maintains a cache of connections to the
Mysql server. It spawns a thread in response to each incoming RPC
request, using one of the existing connections to make an SQL query.
Connection pools are rarely necessary for MySQL and often do more harm
(allocating resources in the server) than benefits.

Quote:
The thread that initiates the connection calls mysql_init() and
mysql_real_connect(). Internally, the Mysql library also calls
mysql_thread_init() to allocate a block of memory.
In fact this is a safety measure. Normally you are expected to call
mysql_thread_init() in each thread that will later call mysql_init().

If you use a connection pool, then there is probably exactly one
thread that is doing all the calls to mysql_init(). Then all memory
will be allocated from this threads local memory.

Quote:
This thread
eventually terminates, leaving that memory behind. Another thread
uses the connection to make an SQL query, but this one does not
allocate thread-specific memory. It terminates without a memory leak.
Yet another thread closes the connection with mysql_close() and
terminates. This one also has no thread-specific memory.
The point here is "this thread eventually terminates". If you called
mysql_thread_end() before terminating this thread, then the allocated
memory will be freed. If you don't do that (it seems like so) then the
allocated memory will not be freed unless you end the complete server
process. Calling mysql_close() on any of those connections will
deallocate the memory. But since the thread which allocated it, no
longer exists, this memory is no longer accessible. In other words:
here is the memory leak.

Quote:
The Mysql documentation recommends calling mysql_thread_end() to free
the thread-specific memory, but that method doesn't seem to fit this
threading model.
Exactly. There are two clean approaches here:

1. allocate the memory in one thread - then this thread must not be
terminated through the lifetime of your demon. All memory will be
allocated from this threads local memory. mysql_close() will return
the memory to this thread, so it can be reused, i.e. for subsequent
calls to mysql_init().

-or-

2. have each worker thread run mysql_init() on its own and allocate
from its own local memory. Then mysql_thread_end() should be called
before terminating this thread. Memory will not leak.

Quote:
The easy fix is to call mysql_thread_end()
immediately after mysql_init() in the function that creates the
connection. That eliminates the memory leak. The daemon still works.
Pure luck. It depends on how exactly the thread library handles this.
But the freed memory could be re-used any time and then you will get
all kinds of problems from silently corrupted data to segfaults.

Quote:
Is this a dangerous thing to do?
Yes! You're relying on undefined behavior.

Quote:
Is there a better way to handle this situation?
Do it correctly. Don't use a connection pool.


XL

Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.