mysql的socket⽂件_mysql.sock⽂件解析
在观察MySQL本地连接的时候,发现对mysql.sock是个啥我不明⽩,于是我提出了⼀个问题:mysql.sock到底存了什么信息?
根据多⽅查资料和⾃我思考,我有了⾃⼰的⼀些认识和结论,但结论并不⼀定正确,欢迎⼤家指教。
连接MySQL
连接MySQL的操作实际上是启动⼀个连接进程和MySQL数据库实例进⾏通信,本质上属于进程间通信,⽽进程通信的⽅式有管道、命名管道、命名字、TCP/IP套接字、UNIX套接字。MySQL数据库提供的⽅式有3种:
TCP/IP套接字⽅式
命名管道和共享内存(Windows平台独有)
UNIX套接字(UNIX平台独有)
TCP/IP套接字⽅式是MySQL数据库在任何平台都提供的连接⽅式,⼀般⽤于客户端和服务端不在同⼀台服务器上,基于⽹络的远程连接请求。
笔者使⽤的是UNIX服务器,所以不了解Windows相关的内容,在使⽤UNIX域套接字时,⼀般⽤于客户端和服务端在同⼀台服务器上的情况,⽽该套接字并不是⼀个⽹络协议,只是⽤于同机器连接通讯的载体。
mysql.sock⽂件
php远程连接mysql数据库
我们可以在配置⽂件myf中指定套接字⽂件的路径:
[mysqld]
socket = /tmp/mysql.sock
也可以在启动时指定socket⽂件的路径:
# 以下两种均可
./mysqld_safe --socket=/tmp/mysql.sock
./mysqld_safe -S /tmp/mysql.sock
在启动MySQL之后我们可以查询socket⽂件的路径:
mysql> show variables like 'socket';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| socket | /tmp/mysql.sock |
+---------------+-----------------+
1 row in set (0.00 sec)
mysql.sock⽂件的作⽤
这个套接字⽂件在我们启动MySQL后会⾃动在我们指定的路径被创建:
[work@ work]$ ll /tmp | grep mysql.sock
srwxrwxrwx 1 mysql mysql 0 Aug 21 20:49 mysql.sock
可以看到该⽂件被刚刚创建,并且⽂件类型's'代表socket套接字类型。同时0代表该⽂件内容为空。
当我们使⽤localhost(mysql命令 -h参数的缺省值)连接本地数据库时,因为⽆法使⽤TCP/IP协议监听端⼝的请求和数据,我们需要使⽤该socket⽂件来进⾏你启动的连接进程和MySQL实例进程的进程间通信,即通讯协议的载体。如果我们删除了该⽂件,当你再次连接本地数据库时会报错:
[root@ work]# mysql -uroot -p
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
此时,我们新建⼀个socket⽂件,并且修改权限和拥有者,同时再次发起数据库连接是依然会报错,不过是不⼀样的错误:
# 新建的为mysql.sock,原有的改名为mysql.sock.bak
mv mysql.sock mysql.sock.bak
# 创建新的mysql socket⽂件
mksock mysql.sock
chown mysql:mysql mysql.sock
chmod 777 mysql.sock
# 展⽰对⽐两个mysql.sock
[root@ tmp]# ll -i | grep mysql
85 srwxrwxrwx 1 mysql mysql 0 Apr 18 15:03 mysql.sock.bak
37 srwxrwxrwx 1 mysql mysql 0 Aug 20 20:35 mysql.sock
# 再次发起连接
[root@ tmp]# mysql -uroot -p
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (111)
可以看出除了inode不同之外其他的信息全部⼀样,⽽且内容都是空的,为什么就不能使⽤呢?
以下原因为个⼈推测,实际的原因需要看linux对socket⽂件的实现,每个socket肯定有属性的不同。
原因是由于mysql.sock是每⼀次MySQL启动之后⽣成的,该socket⽂件会监听创建它的进程,此处即本机的mysqld进程,⽤于其与MySQL实例进程通信,如果你关闭了mysqld进程,该⽂件会被⾃动删除。⽽你新建的socket⽂件只是虚有其表,并没有监听任何的IP和端⼝以及进程PID,所以⾃然不能与MySQL实例通信了。所以如果你删掉了这个⽂件,只能杀死mysqld进程并重启,因为此时你给MySQL实例发送关闭信号的通道也没有了(当然此时你可以⾛TCP/IP通信的⽅法)。
为了证明我的猜测,做了⼀些测试:
保留mysql.sock,杀死进程并重启MySQL,复⽤该socket,依然⽆法通信,证明⾮仅仅简单监听本地端⼝。
tail -f mysql.sock,由于socket只能通过进程间通信使⽤,所以不能通过open()⽅法打开,报错⽆法打开该⽂件,因此⽆法观察到是怎么通过该socket进⾏进程间通信的。
数据库运维:mysql.sock错误修复
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
问题根源:mysql.sock⽂件不到了
问题场景:⼀般为该⽂件被误删,或者PHP等后端指定的该socket⽂件地址路径不对
解决⽅案:
1 . 重启
ps -auxf | grep mysql
kill -SIGKILL pid(到指定的mysql进程pid)
./mysqld_safe
2 . 使⽤locate mysql.sock定位,同时重启:./mysqld_safe -S /path/to/mysql.sock
3 . 在php等配置⽂件(如php.ini)中修改指定该socket的配置地址
pdo_mysql.default_socket = /path/to/mysql.sock
mysql.default_socket = /path/to/mysql.sock
mysqli.default_socket = /path/to/mysql.sock
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (111)问题根源:mysql.sock⽂件⽆法通信
问题场景:⼀般为该mysql.sock⽂件内容不符合通信的需要
解决⽅案:跟上⾯的(2)错误本质上⼀样,解决⽅案也⼀样
参考资料
MySQL技术内幕 InnoDB存储引擎第2版 1.5节 连接MySQL

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。