在觀察MySQL
本地鏈接的時候,發現對mysql.sock
是個啥我不明白,因而我提出了一個問題:mysql.sock到底存了什麼信息?php
根據多方查資料和自我思考,我有了本身的一些認識和結論,但結論並不必定正確,歡迎你們指教。node
MySQL
鏈接MySQL
的操做其實是啓動一個鏈接進程和MySQL
數據庫實例進行通訊,本質上屬於進程間通訊,而進程通訊的方式有管道、命名管道、命名字、TCP/IP
套接字、UNIX
套接字。MySQL
數據庫提供的方式有3種:mysql
TCP/IP
套接字方式Windows
平臺獨有)UNIX
套接字(UNIX
平臺獨有)TCP/IP
套接字方式是MySQL
數據庫在任何平臺都提供的鏈接方式,通常用於客戶端和服務端不在同一臺服務器上,基於網絡的遠程鏈接請求。linux
筆者使用的是UNIX
服務器,因此不瞭解Windows
相關的內容,在使用UNIX
域套接字時,通常用於客戶端和服務端在同一臺服務器上的狀況,而該套接字並非一個網絡協議,只是用於同機器鏈接通信的載體。sql
mysql.sock
文件咱們能夠在配置文件my.cnf
中指定套接字文件的路徑:shell
[mysqld] socket = /tmp/mysql.sock
也能夠在啓動時指定socket
文件的路徑:數據庫
# 如下兩種都可 ./mysqld_safe --socket=/tmp/mysql.sock ./mysqld_safe -S /tmp/mysql.sock
在啓動MySQL
以後咱們能夠查詢socket
文件的路徑:segmentfault
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)
錯誤本質上同樣,解決方案也同樣