linux平台下使用unix socket连接mysql/MariaDB unix socket路径问题

本文探讨了Linux上Unix Socket连接MySQL/MariaDB时,为何文件名不总是/tmp/mysql.sock,以及如何查找MySQL Server的监听路径。用户可以通过设置环境变量、修改配置文件或使用ln -s重定向socket。客户端程序应考虑硬编码可能的Unix Socket路径,以优化性能并减少用户配置。
摘要由CSDN通过智能技术生成

原文:https://ocelot.ca/blog/blog/2015/07/19/connecting-to-mysql-or-mariadb-with-sockets-on-linux/

MySQL手册上面有这样一段话:

--socket=file_name, -S file_name ... On Unix, the name of the Unix socket file to use, for connections made using a named pipe to a local server.
The default Unix socket file name is /tmp/mysql.sock.

但是往往真正在使用unix socket连接的时候会报 "Can't connect to local MySQL server through socket '[something-other-than-/tmp/mysql.sock]'".

我接下来会解释一下为什么文件名总是不同的,如何知道mysql究竟在监听什么,对于用户和应用开发者来说固定不变的是什么.

为什么文件名不总是/tmp/mysql.sock

首先,Linux Foundation发布了一个"文件系统目录等级标准"的文档,在2.3版本中,对于/var/run路径的说法为:维护临时的unix socket文件必须存储在这里.但是在版本3中对于/var/run目录的说明做了一些修改:临时的unix socket文件必须放在该目录下,或者放到上述的一个合适的子目录下面(or an appropriate subdirectory as outlined above),3版本同时也说:总体来说,为了能够实现向后兼容,程序可以继续使用/var/run,所以./var/run依然是标准的存放unix socket文件的地方.

其次,Mysql的附录部分隐藏了一些有趣的东西:对于一些linux版本,unix socket的路径有可能是不同的,对于RPMs操作系统是/var/lib/mysql.这是一种模糊的说法,unix socket文件的路径在安装阶段(source-installation time)已经决定了.

在安装阶段,通过-DINSTALL_LAYOUT={STANDALONE|RPM|SVR4|DEB}决定:

SET(INSTALL_UNIX_ADDRDIR_STANDALONE     "/tmp/mysql.sock")
SET(INSTALL_UNIX_ADDRDIR_RPM            "/var/lib/mysql/mysql.sock")
SET(INSTALL_UNIX_ADDRDIR_DEB            "/var/run/mysqld/mysqld.sock")
SET(INSTALL_UNIX_ADDRDIR_SVR            "/tmp/mysql.sock")

 

所以说,不同的机器,mysql的unix socket默认路径是不同的,下面的配置是我在很久以前总结出来的,所以可能已经过时:

Non-Linux e.g. FreeBSD or Solaris: /tmp/mysql.sock
Debian-based e.g. Ubuntu, and archlinux: /var/run/mysqld/mysqld.sock
SUSE (after v11.2): /var/run/mysql/mysql.sock
Red Hat, and SUSE (before v11.2): /var/lib/mysql/mysql.sock
archlinux (very old versions): /tmp/mysqld.sock

有时,你可以通过 mysql_config --socket命令找出你机器上的mysql unix socket文件究竟在哪里.

找到MySQL Server究竟在监听什么

如果说你不是mysql的安装者,或者说或者说你已经忘记了mysql安装的细节,下面有一些方法可以找到mysql究竟打开了哪些socket.但是这些方法或多或少都有一些缺陷.

方法一:

netstat -lpn | grep mysqld

这种方式的缺陷是,如果你不是root用户,那么无法查看所有的进程,而且 |grep mysqld假设mysql server的名字就是mysqld.

方法二:

find /tmp /var/lib/mysql /var/run/mysqld -name "mysql*.sock"
find: 'var/lib/mysql': Permission denied
/var/run/mysqld/mysqld.sock

这种方法的缺陷是你必须实现猜测mysql unix socket文件存放在哪个目录下面.

方法三:

mysql -h 127.0.0.1 -e "select @@socket"
+-----------------------------+
| /var/run/mysqld/mysqld.sock |
+-----------------------------+

这种做法的缺点是假设mysql的端口就是默认端口3306,并且本地mysql可以访问,每个人都有访问mysql的权限.(我敲这个命令就提示无权限访问本地mysql)

用户可以做什么

当你发现了mysql server使用的unix socket,你可以为这个unix socket重定向一下:

ln -s /var/run/mysqld/mysqld.sock /tmp/mysql.sock

另外一个解决方案就是,告诉客户端程序unix socket是什么,对于遵循mysql guidelines的客户端程序来说,可以设定MYSQL_UNIX_PORT环境变量,或者命令行启动mysql的时候添加 --socket=X,或者更改配置文件(比如~/.my.cnf),在配置文件中增加一行 socket=X.注意mysql unix socket 文件路径也有可能存储在其他地方,比如/etc/mysql/debian.cnf 或php.ini.

mysql客户端程序可以做什么

开发客户端程序的人不应该把unix socket带来的一些问题带给用户,一个简单的解决方法是,把unix socket文件硬编码进程序中.

也有一些GUI的客户端程序默认就使用TCP进行连接,MYSQL有一个很麻烦的地方就是,当用户输入"host=localhost"的时候,我们不知道他们是要用TCP还是unix socket进行连接,Ocelet就默认的使用tcp连接.

所以说,ocelotgui通过把最有可能的unix socket路径硬编码进来让事情变得简单.也就是说,如果用户并没有指明unix socket,host是默认值或者localhost的时候,ocelotgui会尝试通过/tmp/mysql.sock连接如果失败的话尝试/var/lib/mysql/mysql.sock,如果再失败城市/var/run/mysqld/mysqld.sock.ocelotgui目前只是计划这样做,还没有真正的做.

我们之所以使用unix socket是因为性能问题,使用unix socket的数据传输率比tcp要快,而且再大数据量的情况下,花时间取配置unix socket是值得的.

TCP VS Unix Socket 是一个linux问题,所以说这不应该是mysql解决,而应该是linux开发者来解决(好像说的挺有道理)所以说google做了一个修补,如果连接的是本地mysql,将TCP连接直接转换成unix socket.有一篇2012年的文章是关于这一点的,在那之后mysql怎样,我并不清楚.(So there is a fix, or more precisely there is a Google patch, which turns a TCP/IP connection into a socket connection if the target is localhost. There was an article about it on lwn.net in 2012. What happened after that, I don't know.)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值