摘要:連接連接的操作實際上是啟動一個連接進(jìn)程和數(shù)據(jù)庫實例進(jìn)行通信,本質(zhì)上屬于進(jìn)程間通信,而進(jìn)程通信的方式有管道命名管道命名字套接字套接字。同時代表該文件內(nèi)容為空。
在觀察MySQL本地連接的時候,發(fā)現(xiàn)對mysql.sock是個啥我不明白,于是我提出了一個問題:mysql.sock到底存了什么信息?
根據(jù)多方查資料和自我思考,我有了自己的一些認(rèn)識和結(jié)論,但結(jié)論并不一定正確,歡迎大家指教。
連接MySQL連接MySQL的操作實際上是啟動一個連接進(jìn)程和MySQL數(shù)據(jù)庫實例進(jìn)行通信,本質(zhì)上屬于進(jìn)程間通信,而進(jìn)程通信的方式有管道、命名管道、命名字、TCP/IP套接字、UNIX套接字。MySQL數(shù)據(jù)庫提供的方式有3種:
TCP/IP套接字方式
命名管道和共享內(nèi)存(Windows平臺獨有)
UNIX套接字(UNIX平臺獨有)
TCP/IP套接字方式是MySQL數(shù)據(jù)庫在任何平臺都提供的連接方式,一般用于客戶端和服務(wù)端不在同一臺服務(wù)器上,基于網(wǎng)絡(luò)的遠(yuǎn)程連接請求。
筆者使用的是UNIX服務(wù)器,所以不了解Windows相關(guān)的內(nèi)容,在使用UNIX域套接字時,一般用于客戶端和服務(wù)端在同一臺服務(wù)器上的情況,而該套接字并不是一個網(wǎng)絡(luò)協(xié)議,只是用于同機器連接通訊的載體。
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后會自動在我們指定的路徑被創(chuàng)建:
[work@ work]$ ll /tmp | grep mysql.sock srwxrwxrwx 1 mysql mysql 0 Aug 21 20:49 mysql.sock
可以看到該文件被剛剛創(chuàng)建,并且文件類型"s"代表socket套接字類型。同時0代表該文件內(nèi)容為空。
當(dāng)我們使用localhost(mysql命令 -h參數(shù)的缺省值)連接本地數(shù)據(jù)庫時,因為無法使用TCP/IP協(xié)議監(jiān)聽端口的請求和數(shù)據(jù),我們需要使用該socket文件來進(jìn)行你啟動的連接進(jìn)程和MySQL實例進(jìn)程的進(jìn)程間通信,即通訊協(xié)議的載體。如果我們刪除了該文件,當(dāng)你再次連接本地數(shù)據(jù)庫時會報錯:
[root@ work]# mysql -uroot -p ERROR 2002 (HY000): Can"t connect to local MySQL server through socket "/tmp/mysql.sock" (2)
此時,我們新建一個socket文件,并且修改權(quán)限和擁有者,同時再次發(fā)起數(shù)據(jù)庫連接是依然會報錯,不過是不一樣的錯誤:
# 新建的為mysql.sock,原有的改名為mysql.sock.bak mv mysql.sock mysql.sock.bak # 創(chuàng)建新的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 # 再次發(fā)起連接 [root@ tmp]# mysql -uroot -p ERROR 2002 (HY000): Can"t connect to local MySQL server through socket "/tmp/mysql.sock" (111)
可以看出除了inode不同之外其他的信息全部一樣,而且內(nèi)容都是空的,為什么就不能使用呢?
以下原因為個人推測,實際的原因需要看linux對socket文件的實現(xiàn),每個socket肯定有屬性的不同。
原因是由于mysql.sock是每一次MySQL啟動之后生成的,該socket文件會監(jiān)聽創(chuàng)建它的進(jìn)程,此處即本機的mysqld進(jìn)程,用于其與MySQL實例進(jìn)程通信,如果你關(guān)閉了mysqld進(jìn)程,該文件會被自動刪除。而你新建的socket文件只是虛有其表,并沒有監(jiān)聽任何的IP和端口以及進(jìn)程PID,所以自然不能與MySQL實例通信了。所以如果你刪掉了這個文件,只能殺死mysqld進(jìn)程并重啟,因為此時你給MySQL實例發(fā)送關(guān)閉信號的通道也沒有了(當(dāng)然此時你可以走TCP/IP通信的方法)。
為了證明我的猜測,做了一些測試:
保留mysql.sock,殺死進(jìn)程并重啟MySQL,復(fù)用該socket,依然無法通信,證明非僅僅簡單監(jiān)聽本地端口。
tail -f mysql.sock,由于socket只能通過進(jìn)程間通信使用,所以不能通過open()方法打開,報錯無法打開該文件,因此無法觀察到是怎么通過該socket進(jìn)行進(jìn)程間通信的。
數(shù)據(jù)庫運維:mysql.sock錯誤修復(fù) 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進(jìn)程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文件內(nèi)容不符合通信的需要
解決方案:跟上面的(2)錯誤本質(zhì)上一樣,解決方案也一樣
MySQL技術(shù)內(nèi)幕 InnoDB存儲引擎第2版 1.5節(jié) 連接MySQL
mysql.sock文件詳解:https://blog.csdn.net/kerwin6...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/29293.html
閱讀 1878·2021-11-18 13:20
閱讀 1233·2021-10-11 10:59
閱讀 3055·2021-08-24 10:01
閱讀 3589·2019-08-29 14:21
閱讀 3456·2019-08-29 14:15
閱讀 3600·2019-08-26 12:23
閱讀 3416·2019-08-26 11:46
閱讀 3433·2019-08-26 11:35