MySQL 5.5 on Mac OS X
If you’re (re)building a development workstation on Mac OS X, you may have decided to use the latest MySQL 5.5 packages from mysql.com. Unfortunately, that means you probably have seen (or will soon see) two problems. The first is this:
dlopen(/Library/Ruby/Gems/1.8/gems/mysql2-0.2.6/lib/mysql2/mysql2.bundle, 9): Library not loaded: libmysqlclient.16.dylib Referenced from: /Library/Ruby/Gems/1.8/gems/mysql2-0.2.6/lib/mysql2/mysql2.bundle Reason: image not found - /Library/Ruby/Gems/1.8/gems/mysql2-0.2.6/lib/mysql2/mysql2.bundle |
That example is from the mysql2 gem, but the same problem exists with the older mysql gem. The problem is that the libmysqlclient shared library in the MySQL 5.5 package does not specify a full path to the library. When something links with it, such as the MySQL gem, it won’t be able to find the library at runtime.
There are two ways to fix this.
-
The easy way (but see the July 2012 update below): modify DYLD_LIBRARY_PATH in your .bash_profile (or equivalent if you use another shell). The advantage to this method is that it fixes it once for anything that links with the MySQL client libraries going forward. Add:
DYLD_LIBRARY_PATH="/usr/local/mysql/lib:$DYLD_LIBRARY_PATH"
-
The hard, do-it-again-someday way: modify the .bundle files within the gem to use an absolute path to the MySQL client library. The fix is lost when reinstalling the gem or updating to a new version and must be reapplied. Change to your gem’s root, somewhere like /Library/Ruby/Gems/1.8/gems/mysql-2.8.1 or .../mysql2-0.2.6, or even both. There are two .bundle files within the gem (under lib and ext) that you must run the following command on.
$ sudo install_name_tool -change libmysqlclient.16.dylib /usr/local/mysql/lib/libmysqlclient.16.dylib mysql_api.bundle
The second problem with the MySQL 5.5 packages is in the MySQLStartupItem and preference pane. Neither work to start or stop the server.
-
The ownership of the StartupItem files is wrong. OS X complains with
“/Library/StartupItems/MySQLCOM†has not been started because it does not have the proper security settings.
To fix that, run:
$ sudo chown -R root:wheel /Library/StartupItems/MySQLCOM
-
basedir and datadir are not set in /usr/local/mysql/support-files/mysql.server, which breaks the preference pane. Edit that file with superuser privileges (sudo mate or vi, joe, …) and set them:
basedir=/usr/local/mysql datadir=/usr/local/mysql/data
Update July 2012: A change in OS X 10.8 makes the easy method above less elegant. If you set that variable, every time you run a setuid or setgid program, you get this warning on stderr:
dyld: DYLD_ environment variables being ignored because main executable (...) is setuid or setgid |
Ruby developers using Phusion Passenger Standalone will see this message displayed in their console every five seconds. It gets really irritating, very fast.
I have filed a bug with Apple. It’s also at OpenRadar.
In the meantime, there is also a third way to fix the client library path problem that doesn’t require setting DYLD_LIBRARY_PATH (working around this 10.8 issue) or hacking .bundle files with install_name_tool:
- $ brew install mysql
exactly my problem. thanks for the fix!!
Awesome! Just installed MySQL 5.5 on OSX and hit this problem immediately. Thanks a lot for taking the time to post the solution.
I burned a ton of time on this trying nearly every solution out there until I found this. Thanks for posting this!
Thanks a lot.. Works like a charm…
I done the easy way above (1) and i get the following error? any idea?(Thanks)
dyld: lazy symbol binding failed: Symbol not found: _mysql_get_client_info
Referenced from: /Library/Ruby/Gems/1.8/gems/mysql2-0.3.2/lib/mysql2/mysql2.bundle
Expected in: flat namespace
dyld: Symbol not found: _mysql_get_client_info
Referenced from: /Library/Ruby/Gems/1.8/gems/mysql2-0.3.2/lib/mysql2/mysql2.bundle
Expected in: flat namespace
Trace/BPT trap
I wasn’t familiar with “lazy symbol binding failed,” so I Googled it and one of the top hits suggests that you may have a mismatch between your 64-bit Ruby (this comes with Mac OS X) and a 32-bit MySQL server. Did you install the 32- or 64-bit MySQL package?
Thanks for the reply Steve, I installed the 64 bit Mysql package.
How else can i install Mysql so i don’t get this problem?
I haven’t run into this specific problem myself, so I can’t give you any definite answers. Googling around points to an architecture mismatch between Ruby and MySQL. They must be the same, either 32- or 64-bit. I suggest you double check your Ruby from Activity Monitor (be sure to turn on the Kind column; “Intel” is 32-bit and “Intel (64-bit)” is obviously 64-bit). Running irb should be enough for that. Check the MySQL server process, too.
After that, verify that there aren’t any old versions of the mysql2 gem or a MySQL server on your system. If there are, remove them and re-install the gem. If you have an old MySQL server, the gem might be linking against it at build time, then trying to dynamically load the newer library (because of DYLD_LIBRARY_PATH) at runtime.
If you find a solution to your problem, let me know here and I’ll update the post with the fix.
I was having the same problem, even with the correct version (64-bit) of MySQL. Turns out the problem was using Bundler to install the mysql2 gem.
I uninstalled mysql (gem uninstall mysql2) then re-installed it manually:
sudo env ARCHFLAGS=”-arch x86_64″ gem install mysql — –with-mysql-config=/usr/local/mysql/bin/mysql_config
Things worked after that!
The install path solution fixed the problem immediately.
Thanks!
Has anyone figured out a way to make method 1 work under passenger?
Method 1 works for me with a WEBrick, but not for my osx 10.6.7, mysql 5.5.13, Passenger 3.0.7, and rvm setup. I had to use method 2 to make it work under passenger.
I tried to make method 2 work by setting the DYLD_LIBRARY_PATH in the apache virtual host configuration, and also under /usr/sbin/envvars, but no luck.
I found a solution for passenger after more tinkering.
I added the following nodes to the root element of the /System/Library/LaunchDaemons/org.apache.httpd.plist.
EnvironmentVariables
DYLD_LIBRARY_PATH
/usr/local/mysql/lib
Here’s that snippet again, with entities escaped:
<key>EnvironmentVariables</key>
<dict>
<key>DYLD_LIBRARY_PATH</key>
<string>/usr/local/mysql/lib</string>
</dict>
Does that go after the last ?
I currently have the following in my org.apache.httpd.plist:
Disabled
Label
org.apache.httpd
ProgramArguments
/usr/sbin/httpd
-D
FOREGROUND
OnDemand
SHAuthorizationRight
system.preferences
Sorry. Did not escape entities. Not sure how to!
Ok. Got it sorted. Your code goes before the last dict and i’ve now got my app working under passenger. Thanks a million!
You could also point your PassengerRuby to a shell script that sets up the environment then execs the real ruby binary.
Steve: thank you for the original post, helped me greatly in repairing my local Rails and Passenger setup under Lion. Upgrading to Lion bit me on some other database connection problems, which is why I upgraded to MySQL 5.5 in the first place, running into the .dylib reference problem mentioned here.
Weston T: tried your .plist solution first, but unfortunately didn’t get it to work, not immediately and not after a restart. Had to go for the install_name_tool, which has its drawbacks when upgrading, but works great for now.
OMG I was working my** off to understand this, but the simple compand in the beginning fixed everything! THANKS!!!
Hello – I am still having some problems with this. I am new to rails development so it might be that I am missing something easily overlooked. Anyways, I get the error noted above and I have added the following to my .bash_profile:
export DYLD_LIBRARY_PATH=â€/usr/local/mysql/lib:$DYLD_LIBRARY_PATHâ€
I then tried to run this command:
sudo chown -R root:wheel /Library/StartupItems/MySQLCOM
and i would get the command not found, which I’m assuming is because i do not have a startpitems folder?
please let me know if you have any suggestions.
thank you
/Library/StartupItems/MySQLCOM won’t exist unless you have installed the MySQL Startup Item. It’s always been in the same DMG as the MySQL server itself.
I too am new to RUBY and am trying to do this on Lion 10.7 final. I am also getting the.
dyld: lazy symbol binding failed: Symbol not found: _mysql_get_client_info
Referenced from: /Library/Ruby/Gems/1.8/gems/mysql2-0.3.6/lib/mysql2/mysql2.bundle
Expected in: flat namespace
dyld: Symbol not found: _mysql_get_client_info
Referenced from: /Library/Ruby/Gems/1.8/gems/mysql2-0.3.6/lib/mysql2/mysql2.bundle
Expected in: flat namespace
Trace/BPT trap: 5
Even after setting
export DYLD_LIBRARY_PATH=â€/usr/local/mysql/lib:$DYLD_LIBRARY_PATHâ€
Has anyone solved this yet.
Thanks a ton for the install_name_tool command!
FWIW, while both ways of getting around this have their merits, in my experience the DYLD_LIBRARY_PATH command is more likely to not cover all your cases. For instance, if you’re going to try and run things under the Apache2 that the system runs, you’re better off to just fix the software once rather than have to modify an environment you don’t control directly.
However, as you said either way the best fix would be for the MySQL library to use an absolute path in the first place…
If you have installed OS X 10.7 (Lion), this is also a fix for the error:
uninitialized constant MysqlCompat::MysqlRes
which, as I learned after much searching and hair-pulling, is ultimately caused by the same library path issue.
Thanks for this tip! I looked all over the place only to find lots of advice about ARCHFLAGS, but very little about anything else.