DBD::mysql Module Cannot Locate MySQL Socket

Posted by bvalentine on 2017-08-08 10:10
Forums: PPM | OS: Red Hat / Fedora Core

I've used ActivePerl's PPM to install the DBD::mysql module. For some reason, when attempting a database connection in my script using localhost (unix socket), the module cannot locate the mysql.sock file. It is looking for it in /tmp/mysql.sock. That does not seem like a logical location. I know where the mysql.sock file is. I even sym-linked the socket file to the /tmp directory. No luck. Interestingly, using the loopback 127.0.0.1 (tcp/ip connection), the module finds the mysql socket with no issues.

Here is the exact error message from Perl over httpd: DBI connect(':localhost','root',...) failed: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) at /var/www/html/installation.cgi line 633., referer: http://192.168.1.253/installation.cgi

To add more confusion. This only pertains to the PPM DBD::mysql module. If I use the standard CPAN DBD::mysql module, I have no problem using localhost or 127.0.0.1. After comparing the files in the module, I found that the mysql.so (binary file) is different from PPM than CPAN (the ppm version is almost twice the size). Both versions of this module are the same. Very weird.

What am I missing?

This is on a Redhat 7.4 64-bit server. Running ActivePerl 5.24.

TIA

grahams
ActiveState Staff
Tue, 2017-08-08 15:45

PPM does two things. It provides prebuilt binaries for users with no compiler, and it provides binaries that are compiled with any needed compiler options should the user have the Perl Dev Kit and be creating wrapped binaries.

The reason the PPM binary is so much bigger is that it must use static linking in order to be wrappable.

It also cannot count on the existence of some files, so the binaries may be built to use /tmp as a working folder. On Redhat and Centos 7, running binaries from /tmp is known to fail due to the Security Best Practices implemented by RedHat, and is a contributing factor to the decision to stop selling PDK.

For the moment, since there are still many users of PDK, we can't really alter the way PPM works for everyone.

If you change the permissions on /tmp to allow execution, the PPM version should start working. If you can't change the permissions on /tmp, then building your own version directly from CPAN is the way to go.

bvalentine | Tue, 2017-08-08 17:54

Thank you for the information! The permissions of the /tmp directory are already 777. Still having the issue.

grahams
ActiveState Staff
Wed, 2017-08-09 07:16

bvalentine | Wed, 2017-08-09 08:07

Thank you again for the information, I appreciate it. Doesn't /tmp by default have execution? Is this a SELinux issue? Right now it is set to Permissive.

I ran "mount -o remount,exec /tmp"

The results when I run "mount" are:

tmpfs on /tmp type tmpfs (rw,relatime,seclabel)

I then ran " mount -o remount,noexec /tmp"

Now the results of "mount" are:

tmpfs on /tmp type tmpfs (rw,noexec,relatime,seclabel)

It doesn't matter with noexec, or exec, I still get a can't find socket error. What am I missing?

grahams
ActiveState Staff
Wed, 2017-08-09 13:14

With SELinux, I've had experiences where results from "permissive" did not match my interpretation of the language in the SELinux manuals. Maybe I read it wrong, but it's my experience that using "disabled" to shut SELinux off will determine if SELinux configuration is the issue.

bvalentine | Wed, 2017-08-09 13:31

I tried SELinux set to disabled earlier. Then rebooted. Still getting the socket error.

I also built a new virtual, installed Redhat and specified logical partition for /tmp. I gave it 1gb. This way I could verify if a virtual mount would not work.

Now my mount looks like this:

/dev/mapper/rhel-tmp on /tmp type xfs (rw,relatime,attr2,inode64,noquota)

Still getting the socket error.

Surely there are others using Redhat with ActivePerl and MySQL. I have no idea what I am doing wrong, or not doing that would cause this issue. I'm using a minimal install of redhat, development tools installed, mysql installed, and activeperl installed. That's it.

grahams
ActiveState Staff
Fri, 2017-08-11 14:00

Might be a compatibility issue with the Client version used by PPM....
Looks like it was built with
# mysql_clientinfo is: 5.1.72
and it's test suite ran vs
# mysql_serverinfo is: 5.5.24-0ubuntu0.12.04.1

Or... Have you tried this in your code? Just to ensure that the code has no confusion about where mysql.sock is found:
mysql_socket
It is possible to choose the Unix socket that is used for connecting to the server. This is done, for example, with

mysql_socket=/dev/mysql
Usually there's no need for this option, unless you are using another location for the socket than that built into the client.

bvalentine | Fri, 2017-08-11 14:26

That seems kind of old. I'm running the latest, 5.7.19.

bvalentine | Mon, 2017-08-14 04:39

I can go alter all my db connections as a test. This same code works on ActivePerl on Windows. It also works just fine with CPAN modules. I have also changed the default location of the socket in the mysql cnf. So now the socket lives in /tmp. Still doesn't work.

grahams
ActiveState Staff
Tue, 2017-08-15 10:30

I went through the release notes and bug lists from DBD-MySQL and from MySQL. There's a lot of changes that might affect a binary built against an older client, but nothing seems obvious.

Does the MySQL server have any related logs when the connection attempt is made?

bvalentine | Tue, 2017-08-15 12:09

There is a log, but the error occurs in Perl before it even gets to MySQL. The error prints in the httpd error log. The mysql.log is just start and stop entries.

It has to be something more. Now that the socket lives in /tmp, DBD::mysql should be happy, but it isn't. That goes back to what you were explaining about exec on the /tmp dir. But I feel like I have ruled that out too.

Thanks again for the follow-up I appreciate it.

bvalentine | Tue, 2017-08-15 12:14

The mysql.sock file has zero size (I don't know much about socket files, this could be normal?). It shows as 0 kb. There is also a mysql.socket lock file.

grahams
ActiveState Staff
Wed, 2017-08-16 09:47

Your example looks like you have disabled pam_systemd.

On my RHEL 7 testbed, /tmp is mapped elsewhere; to
tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,seclabel,... )

Is there a chance it's not fully disabled, and that the mysql.sock file doesn't exist in the folder that gets mapped as /tmp for the userID used when you run ActivePerl?

bvalentine | Wed, 2017-08-16 10:44

We are getting into concepts I am not really familiar with. Be patient with me.

I ran "systemctl status systemd-logind.service". This showed me that it is running, not disabled or anything.

I'm not sure what this has to do with the /tmp directory:

tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,seclabel,... )

That is a mount for /run/user/1000.

When I ran "mount" again on my system. Here are the lines:

/dev/mapper/rhel-tmp on /tmp type xfs (rw,nosuid,relatime,attr2,inode64,noquota)
tmpfs on /run/user/0 type tmpfs (rw,nosuid,nodev,relatime,size=101648k,mode=700)

The only item missing is seclabel. I attempted to add that to the /tmp mount. However, when I do that, it removes nosuid and does not add seclabel. i.e. /dev/mapper/rhel-tmp on /tmp type xfs (rw,relatime,attr2,inode64,noquota)

On your test bed system, did you have to alter anything before installing ActivePerl? Am I missing some other "first steps" to get this thing prepped?

Thanks again.

grahams
ActiveState Staff
Thu, 2017-08-17 13:45

I reviewed the docs, and systemd would only be managing per-user tmp files; not a system-wide file such as mysql.sock.

Another finding: The string "Can't connect to local MySQL server through socket '$PATH/mysql.sock' comes from the MySQL client and is simply handed along by Perl. Since the connection only fails when the PPM version is used, it must be the client used by the PPM version that has an issue, and since the client used by the nonPPM version works, there's some difference between the clients. Since we know the PPM version has static linked components which make it different (bigger) from the CPAN version, that seems to be where the problem is.

We've more or less eliminated all the other likely explanations. We're left with some kind of incompatibility between the old client and the new MySQL. Maybe a C debugger on the socket connection attempt would show more, but that might be overkill.

Is there any reason why you can't use the latest CPAN DBD-MySQL to go with the latest version of MySQL (installed)?