摘要:连接连接的操作实际上是启动一个连接进程和数据库实例进行通信,本质上属于进程间通信,而进程通信的方式有管道命名管道命名字套接字套接字。同时代表该文件内容为空。
在观察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文件我们可以在配置文件my.cnf中指定套接字文件的路径:
[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.sockERROR 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
mysql.sock文件详解:https://blog.csdn.net/kerwin6...
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/29293.html
阅读 1708·2021-11-18 13:20
阅读 1109·2021-10-11 10:59
阅读 2938·2021-08-24 10:01
阅读 3483·2019-08-29 14:21
阅读 3321·2019-08-29 14:15
阅读 3497·2019-08-26 12:23
阅读 3320·2019-08-26 11:46
阅读 3324·2019-08-26 11:35