Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MariaDB client version vs. package version error #1348

Open
chadmyers opened this issue Jan 31, 2024 · 12 comments
Open

MariaDB client version vs. package version error #1348

chadmyers opened this issue Jan 31, 2024 · 12 comments

Comments

@chadmyers
Copy link

chadmyers commented Jan 31, 2024

Ruby: 3.1.3.1
Platform: Windows, msys2, mingw64
MariaDB Connector/C version: 3.3.8
mysql2 gem version: 0.5.5

My MariaDB client lib install command:
ridk exec sh -c "pacman -S --needed --noconfirm mingw-w64-x86_64-libmariadbclient"

My Gem install command:

& C:\tools\ruby31\bin\gem.cmd install mysql2 --no-document --no-post-install-message -q -- --with-mysql-lib=C:\tools\msys64\mingw64\lib --with-mysql-include=C:\tools\msys64\mingw64\include

I've also tried with the same effect:

& C:\tools\ruby31\bin\gem.cmd install mysql2 --no-document --no-post-install-message -q -- --with-mysql-dir=C:\tools\msys64\mingw64

I can successfully gem install/compile the mysql2 gem but when I try to use it, I get the error:

Gem Load Error is: Incorrect MySQL client library version! This gem was compiled for 10.8.8 but the client library is 3.3.8.

I noticed in mysql2/ext/mysql2/client.c file it has (lines 52-58)

#if defined(MARIADB_CLIENT_VERSION_STR)
  #define MYSQL_LINK_VERSION MARIADB_CLIENT_VERSION_STR
#elif defined(LIBMYSQL_VERSION)
  #define MYSQL_LINK_VERSION LIBMYSQL_VERSION
#else
  #define MYSQL_LINK_VERSION MYSQL_SERVER_VERSION
#endif

Then (lines 1514 - 1526):

const char *lib = mysql_get_client_info();

...

    if (lib[i] != MYSQL_LINK_VERSION[i]) {
      rb_raise(rb_eRuntimeError, "Incorrect MySQL client library version! This gem was compiled for %s but the client library is %s.", MYSQL_LINK_VERSION, lib);

My msys64\mingw64\include\mysql\mariadb_version.h file has:

#define MARIADB_CLIENT_VERSION_STR      "10.8.8"
...
#define MARIADB_PACKAGE_VERSION "3.3.8"

MariaDB client's mysql_get_client_info() function returns MARIADB_PACKAGE_VERSION, but mysql2 gem is comparing that against the MARIADB_CLIENT_VERSION_STR.

What I don't understand is that this stuff has been there for 3 years, but my mysql2 gem installation only just started breaking within the last 30 days or so. It worked in December when I rebuilt an AMI in AWS using the latest mysql2 gem (0.5.4) and MariaDB client (I think it was 3.3.7 or maybe 3.3.8).

Any thoughts on why this worked and why it's not working now? Thanks in advance!

@chadmyers
Copy link
Author

New information: I was able to get mysql2 0.5.5 gem to successfully install and work in a running application by using the old 3.1.13 ucrt64 version of the mariadb client. So I think the mariadb client folks changed how the versioning worked out from underneath the mysql2 gem, so you might need to add some extra logic to handle the difference

@cocco111
Copy link

I can confirm the issue.
Alternative solution to work with last gem version on windows:

  • download gem and rebuild without this line
  • gem install mysql2-0.5.6.gem -- --with-mysql-dir=c:/<Ruby-install-dir>/msys64/ucrt64

Specifing mysql-dir in which mariadbclient resides, is needed to avoid this error:

`block in find_library': undefined method `split' for nil:NilClass (NoMethodError)
 paths = paths.flat_map {|path| path.split(File::PATH_SEPARATOR)}

@Whaat
Copy link

Whaat commented Apr 11, 2024

Thanks @cocco111,
I'm trying to use your solution but struggling probably due to my inexperience working with gems.

  • download gem and rebuild without this line

I assuming this means, download the gem source code from github, comment out the 'line' in the source code you referenced and rebuild using:
gem build mysql2.gemspec
This creates a new file mysql2-0.5.6.gem in the working directory. Next I ran

  • gem install mysql2-0.5.6.gem -- --with-mysql-dir=c:/<Ruby-install-dir>/msys64/ucrt64

However, this failed for me with the error:

        ERROR: Failed to build gem native extension.

    No such file or directory @ dir_s_mkdir - C:/Ruby32-x64/lib/ruby/gems/3.2.0/gems/mysql2-0.5.6/ext/mysql2/.gem.20240411-17300-dt82ue

Any help is greatly appreciated. I am wondering if this is some sort of caching issue or maybe I need to update the version number of the gem for it to work...?

@cocco111
Copy link

Hello @Whaat ,
almost correct but I suggest to

  • download the packed file (.gem), for example with command gem fetch,
  • uncompress (it's a tar I think)
  • change file
  • gem build mysql2.gemspec
  • gem install mysql2.gem

This to avoid starting from source code, that for sure has additional building steps, deps, etc...
Hope it helps you!

@Whaat
Copy link

Whaat commented Apr 12, 2024

Thanks, but unfortunately that approach does not seem to work.
First problem is that the gemspec file did not exist inside the uncompressed .gem / tar. So I tried downloading it from github. But when running gem build I got
fatal: not a git repository (or any of the parent directories)

It's OK though I was able to build it now using my original approach. I re-cloned the repo and made sure to checkout the proper release tag (0.5.6). I also made sure to gem uninstall mysql2 before I installed my modified version. Perhaps I forgot that step last time, who knows.

@cocco111
Copy link

@Whaat try this way:
if you already have mysql2 installed, put .gemspec inside mysql2-0.5.6 installation dir (in gems folder), modify .c file and do a gem build
The result should be a .gem with these folders as data : ext, lib, support
Then, as you said, uninstall mysql2 and try to install your new gem

@jwalkerbg
Copy link

Same to me. What I did:

  1. Cloned https://github.com/brianmario/mysql2.git
  2. Switched to tag v0.5.6
  3. Edited mysql2/ext/mysql2/client.c (commented the if operator) at lines 1541-1543: if (lib[i] != MYSQL_LINK_VERSION[i]) { ... }
  4. Executed gem build mysql2.gemspec
  5. Uninstalled before installed mysql2 gems.
  6. Installed the gem built in point 4.

My command to install mysql2 is

gem install mysql2-0.5.6.gem --platform=ruby -- '--with-mysql-lib="C:\Program%20Files\MySQL\MySQL%20Server%205.7\lib" --with-mysql-include="C:\Program%20Files\MySQL\MySQL%20Server%205.7\include" --with-mysql-dir="C:\Program%20Files\MySQL\MySQL%20Server%205.7"'

MySQL is installed at C:\Program Files\MySQL\MySQL Server 5.7.

@zawhtutwin
Copy link

git clone https://github.com/brianmario/mysql2.git

cd mysql2

git checkout 0.5.6

cd ext

open client.c and comment the following line

   /* 
   if (lib[i] != MYSQL_LINK_VERSION[i]) {
      rb_raise(rb_eRuntimeError, "Incorrect MySQL client library version! This gem was compiled for %s but the client library is %s.", MYSQL_LINK_VERSION, lib);
    }*/

go to the project root dir and do

gem build mysql2.gemspec

copy mysql2-0.5.6.gem to your rails project folder and do

gem install mysql2-0.5.6.gem -- --with-mysql-dir="E:\Ruby32-x64" (assumed libmysql.dll is already in this folder)

@sampenguin
Copy link

Can confirm this issue still appears in mysql2 0.5.6 with Ruby 3.3.3 on Windows. Just like OP, mine was working fine with both 0.5.5 and 0.5.6 and then suddenly stopped, however I think in my case it was related to either upgrading Ruby from 3.2.x and/or upgrading RubyGems in my project.

@zawhtutwin 's workaround steps solved the problem in my case.

@chadmyers
Copy link
Author

@sampenguin I see the issue on both Ruby 3.1 and Ruby 3.3.3.1 on Windows and Linux. It's definitely an issue with the mysql2 gem and how it does version checking which has been messed up now that the libmariadb-client folks changed how their version constants work.

@sodabrew
Copy link
Collaborator

sodabrew commented Jul 3, 2024

Sounds to me that CI config using latest Ubuntu with MariaDB libs would help. For some of the CI configs, MySQL proper is fetched rather than using the distro package

The OP comment explains how Mariadb is using the constants in a manner that's confusing the check login. I'll see about improving this.

On the flip side, this error may be revealing that some folks are using different packages in your CI builds vs prod runtime environments. I urge double checking this as well. There is a high degree of compatibility of MySQL client libraries, but not perfect, which is what I recall (vaguely over the years now) this check was added for.

@LeonardoEckertMarques
Copy link

Thanks guys @zawhtutwin @chadmyers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants