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文件
我們可以在配置文件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.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 文件解析的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- mysql sock文件存儲瞭什麼信息
- 詳解MySQL中的pid與socket
- 如何避免mysql啟動時錯誤及sock文件作用分析
- MySQL多實例的配置應用實例場景
- Redhat7.3安裝MySQL8.0.22的詳細教程(二進制安裝)