Bug #60061 libmysqlclient.so.16 in 5.5.8 is not ABI compatible with previous versions
Submitted: 9 Feb 2011 20:24 Modified: 8 Mar 2011 20:18
Reporter: Clint Byrum Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Packaging Severity:S2 (Serious)
Version:5.5.8, 5.5.9 OS:Linux
Assigned to: CPU Architecture:Any
Tags: abi, libmysqlclient, regression, soname

[9 Feb 2011 20:24] Clint Byrum
Description:
This is basically a consolidation of these two bugs:

http://bugs.mysql.com/bug.php?id=59106

and

http://bugs.mysql.com/bug.php?id=59078

The soname of libmysqlclient.so.16 used in libmysqlclient for 5.5.8 is incompatible with prior versions of the library with the same soname. The reason for versioning a shared library is to prevent this exact problem from happening. Anything that requires a re-link and/or re-compile of linking programs, must also be paired with a change to the soname.

Likewise, linking a versioned library to an unversioned linking object will mean that programs needing the old version of the library will not function if the older development version of the library must be installed for some reason. The linker needs /usr/lib/libmysqlclient.so so it can *resolve* the soname to link things to, and if users want to compile something against the old library, they will need to install the old development version.

libmysqlclient_r.so.16.0.0, therefore, must not be a symlink to libmysqlclient.so. In fact, the library should just be dropped in 5.5.8. Builds can be fixed to no longer link against _r, and old programs can continue to use the libmysqlclient_r.so.16 copy of the library from 5.1 until they've been rebuilt.

How to repeat:
This is oriented around a Debian and/or Ubuntu system, but it will have the same problem on any distribution that has shipped libmysqlclient.so.16 from a previous version of MySQL:

1. Check out this revision of this packaging branch of mysql 5.5.8

bzr export -r 28 lp:~clint-fewbar/ubuntu/natty/mysql-5.1/mysql-5.5-packaging

2. If on Debian, you can build it with  cd mysql-5.5-packaging && DEB_BUILD_OPTIONS=nocheck debuild. Otherwise, the cmake and make commands are contained in debian/rules to repeat the build in a similar fashion.

3. Install the new libmysqlclient16 packages that were produced:

sudo dpkg -i ../libmysqlclient16_5.5.8-0ubuntu3_*.deb

4. Install something from your distribution depends on libmysqlclient16:

sudo apt-get install sysbench

5. Run sysbench

$ sysbench --test=oltp --db-driver=mysql run
sysbench: /usr/lib/libmysqlclient_r.so.16: no version information available (required by sysbench)

The program does run in spite of the complaint, but there's potential for breakage in a very unpredictable way as types, arguments, or variables may have disappeared and will become unresolvable, causing system crashes.

Suggested fix:
=== modified file 'cmake/mysql_version.cmake'
--- cmake/mysql_version.cmake	2010-12-21 07:55:42 +0000
+++ cmake/mysql_version.cmake	2011-02-09 20:18:43 +0000
@@ -17,7 +17,7 @@
 # Global constants, only to be changed between major releases.
 #
 
-SET(SHARED_LIB_MAJOR_VERSION "16")
+SET(SHARED_LIB_MAJOR_VERSION "17")
 SET(PROTOCOL_VERSION "10")
 SET(DOT_FRM_VERSION "6")

=== modified file 'libmysql/CMakeLists.txt'
--- libmysql/CMakeLists.txt	2010-12-21 07:55:42 +0000
+++ libmysql/CMakeLists.txt	2011-02-09 20:21:21 +0000
@@ -172,7 +172,6 @@
       SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
     ENDIF() 
   ENDMACRO()
-  INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
 ENDIF()
 
 IF(NOT DISABLE_SHARED)
@@ -203,23 +202,5 @@
     #(mysqlclient in this case)
     SET_TARGET_PROPERTIES(mysqlclient PROPERTIES CLEAN_DIRECT_OUTPUT 1)
     SET_TARGET_PROPERTIES(libmysql PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-
-    # Install links to libmysqlclient.so (client_r)
-    GET_VERSIONED_LIBNAME(
-      "${CMAKE_SHARED_LIBRARY_PREFIX}mysqlclient_r"
-      "${CMAKE_SHARED_LIBRARY_SUFFIX}"
-      ""
-      linkname)
-    INSTALL_SYMLINK(${linkname} libmysql ${INSTALL_LIBDIR} SharedLibraries)
-    SET(OS_SHARED_LIB_SYMLINKS "${SHARED_LIB_MAJOR_VERSION}" "${OS_SHARED_LIB_VERSION}")
-    LIST(REMOVE_DUPLICATES OS_SHARED_LIB_SYMLINKS)
-    FOREACH(ver ${OS_SHARED_LIB_SYMLINKS})
-      GET_VERSIONED_LIBNAME(
-        "${CMAKE_SHARED_LIBRARY_PREFIX}mysqlclient_r"
-        "${CMAKE_SHARED_LIBRARY_SUFFIX}"
-        "${ver}"
-        linkname)
-      INSTALL_SYMLINK(${linkname} libmysql ${INSTALL_LIBDIR} SharedLibraries)
-    ENDFOREACH()
   ENDIF()
 ENDIF()
[10 Feb 2011 0:42] Clint Byrum
Just wanted to add another test case..

the actual mysql client from 5.1, compiled against 5.1 libmysqlclient.so.16, will not work with the 5.5.8 library:

$ mysql -uroot -p
mysql: /usr/lib/libmysqlclient.so.16: no version information available (required by mysql)
mysql: relocation error: mysql: symbol disabled_my_option, version libmysqlclient_16 not defined in file libmysqlclient.so.16 with link time reference
[25 Feb 2011 23:43] Sveta Smirnova
Thank you for the report.

Verified as described.
[9 Mar 2011 2:53] Paul DuBois
Noted in 5.5.10 changelog.

The shared library version of the client library was increased to 18
to reflect ABI changes, and avoid compatibility problems with the
client library in MySQL 5.1. Note that this is an incompatible change
between 5.5.10 and earlier 5.5 versions, so client programs that use 
the 5.5 client library should be recompiled against the 5.5.10 client
library.