DBD-mysql icon indicating copy to clipboard operation
DBD-mysql copied to clipboard

DBD::MySQL does seem to be thread-safe [rt.cpan.org #104343]

Open mbeijen opened this issue 7 years ago • 2 comments

Migrated from rt.cpan.org#104343 (status was 'new')

Requestors:

From [email protected] on 2015-05-11 11:03:52:

Current DBD::MySQL documentation reads:

    The multithreading capabilities of DBD::mysql depend completely on the
    underlying C libraries. The modules are working with handle data only, no
    global variables are accessed or (to the best of my knowledge) thread
    unsafe functions are called. Thus DBD::mysql is believed to be completely
    thread safe, if the C libraries are thread safe and you don't share
    handles among threads.

However, MySQL documentation has stronger requirements <https://dev.mysql.com/doc/refman/5.1/en/c-api-threaded-clients.html>:

    When you call mysql_init(), MySQL creates a thread-specific variable for
    the thread that is used by the debug library (among other things). If
    you call a MySQL function before the thread has called mysql_init(), the
    thread does not have the necessary thread-specific variables in place
    and you are likely to end up with a core dump sooner or later. To avoid
    problems, you must do the following:

    (1) Call mysql_library_init() before any other MySQL functions. It is
    not thread-safe, so call it before threads are created, or protect the
    call with a mutex.

    (2) Arrange for mysql_thread_init() to be called early in the thread
    handler before calling any MySQL function. If you call mysql_init(), it
    will call mysql_thread_init() for you.

    (3) In the thread, call mysql_thread_end() before calling
    pthread_exit(). This frees the memory used by MySQL thread-specific
    variables. 

    The preceding notes regarding mysql_init() also apply to
    mysql_connect(), which calls mysql_init().

Current DBD::MySQL source does not call mysql_library_init() at all. Also it does not call mysql_thread_end() before exiting a thread. (Actually there is no Perl thread-specific code like START_MY_CXT.)

Finally, some MySQL distributions provide thread-safe MySQL client in standalone libmysqlclient_r.so library and DBD::MySQL still prefers the non-threaded libmysqlclient.so version (Makefile.PL should use mysql_config -libs_r).

It would be great to make the DBD::MySQL thread safe by following the MySQL requirements or drop the misleading text from the documentation.

mbeijen avatar Nov 14 '17 19:11 mbeijen

See #244 for details. Basically libmysqlclient is now always thread-safe (since 5.5)

dveeden avatar Sep 15 '18 14:09 dveeden

Looks we might need to call mysql_library_init(), even with MySQL 8.0: https://dev.mysql.com/doc/refman/8.0/en/mysql-library-init.html

dveeden avatar Sep 15 '18 14:09 dveeden