首頁 > 軟體

mysql sock 檔案解析及作用講解

2022-07-15 10:00:42

引言

在觀察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代表該檔案內容為空。

當我們使用localhostmysql命令 -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:

https://www.jb51.net/books/598536.html

mysql.sock檔案詳解:https://www.jb51.net/article/93285.htm

以上就是mysql sock 檔案解析及作用的詳細內容,更多關於mysql sock 檔案解析的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com