The client library — libmysqlclient — is part of the same source code repository as the server. It comes both as a dynamic link library (.so), also called a shared library, and as a static link library (.a). During the 5.7 development cycle, we’ve made several improvements to the library, which has resulted in a bump from ABI version 18 to version 20. This is the first in a series of blog posts focusing on the client library.
The libmysqlclient API exposes more than 100 functions that application developers can use to issue queries, retrieve results, etc. The API functions are easily recognized by their prefix, “mysql_” (with my_init() as the only exception).
These functions are those application developers can expect the library to support. If you can’t do what you want to do using those functions, you’re probably not meant to do it at all.
In an ideal world, all client applications would use just the documented API. But for many years, libmysqlclient has exported all internal symbols, so developers have started using functions that were never intended to be used by the public. Worst of all, since these functions are not intended to be used outside the library, we haven’t made sure the behavior is consistent between versions.
This all changes with MySQL 5.7 and libmysqlclient 20. The biggest change we’ve made to the client library in 5.7 is that we’ve started restricting the list of exported symbols to those in the documented API. You can no longer access internal functions that were never intended for public use. And, more importantly, you will no longer have problems linking your application with other libraries just because they happen to export symbols with the same names as some of the internal symbols in libmysqlclient.
I know many users have been waiting for this change for a long time. One of the reasons it has taken so long is that we know people are using undocumented symbols. We needed a way to handle those cases before we could start breaking applications. We now have a way to solve this. However, it requires people to report build failures to us.
So we expect there will be applications that depend on symbols that we haven’t exported. If you’re the developer of such an application, my first advice is to see if you can achieve what you’re trying to do using functions that are part of the API. If you still can’t find a way and you really need us to add a symbol, please file a bug telling us what you need it for and why.
Our preferred way of adding new symbols is not to just add an internal symbol to the export list. In order to keep the API neat and clean, we may add a new function with the “mysql_” prefix, or we may choose to give you access to the same functionality using an existing function. We believe it’s better to provide a well designed interface instead of adding random functions.
There are no rules without exceptions. We started out with only the documented API in the 5.7.5 DMR almost a year ago. Since then, we’ve added a few non-API symbols to the export list:
That does not give you a free pass to use those functions! As you can see from the names of those functions, they lack the “mysql_” prefix, which means they’re not part of the API you’re meant to use.
We’ve added them because we know people are using them, and we don’t want to break those applications right now. But, please, if you do use these symbols, file a bug report telling us what you’re using them for and why you have to. We plan to remove them in a future version, and if you don’t tell us that you need them, they may not be replaced by proper API functions.
Static vs. dynamic
All the restrictions above apply to the dynamic link library, i.e., libmysqlclient.so. When using the static library, i.e., libmysqlclient.a, these rules aren’t enforced. This has to do with how static libraries are made and used by the linker, and it’s not MySQL specific.
So the good news is that if you use the static library, you’re not affected. However, I still strongly recommend doing a build that links with the shared library in order to check if you’re using functions you’re not supposed to. While it is possible to do so with the static library, it’s not wise. These functions are internal to the library and may change without notice. By using such functions, you run the risk of breaking your application when the library is upgraded.
Since we’re restricting the export list after a period with no restrictions, we do expect some applications to fail to build because of missing symbols. But we can add those as we go. The ABI version is currently 20.0.9, and every time we add new symbols, we’ll bump the minor version number (i.e., the one in the middle).
In the next post in this series, we’ll go into more details about how the ABI version number is made.
Until then, if you have questions or comments, please use the comment field below.