通过执行 show variables like 'socket'; 可确认 mysql 正在使用的 unix socket 路径,如 /var/run/mysqld/mysqld.sock,该路径需存在、可访问且权限正确,否则本地 socket 连接将失败。

怎么确认 MySQL 正在用 Unix Socket?
先别急着改配置,得先看服务端到底有没有启用、路径在哪。MySQL 启动后会把 socket 路径写进系统变量,直接查最准:
mysql -u root -p -e "SHOW VARIABLES LIKE 'socket';"- 或连进去后执行:
SHOW VARIABLES LIKE 'socket';
返回的 Value 就是真实路径,比如 /var/run/mysqld/mysqld.sock。这个路径必须存在且可访问——如果文件被删了,mysqld 不会自动重建(除非重启服务),此时所有本地 socket 连接都会失败,报错类似 Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)。
服务端配置:改 my.cnf 的 [mysqld] 段
修改前先停服务,否则改了也不生效。路径通常在 /etc/my.cnf 或 /etc/mysql/my.cnf,重点只动这一块:
[mysqld] socket = /var/run/mysqld/mysqld.sock
注意几点:
- 路径目录(如
/var/run/mysqld/)必须存在,且属主为mysql用户,权限建议drwxr-xr-x - 不要和
datadir混用同一路径,避免权限冲突 - 改完必须重启
mysqld:sudo systemctl restart mysql(或mariadb) - 重启后检查进程是否真用了新路径:
ss -l | grep mysqld或lsof -U | grep mysqld
客户端连接:三种指定 socket 的方式,优先级有区别
客户端不配也能连,默认找 /tmp/mysql.sock 或编译时定义的路径,但靠猜容易翻车。推荐显式指定:
- 命令行加
-S参数(最高优先级):mysql -u root -p -S /var/run/mysqld/mysqld.sock - 设环境变量
MYSQL_UNIX_ADDR(中等优先级):export MYSQL_UNIX_ADDR=/var/run/mysqld/mysqld.sock,之后所有mysql命令都走这个 - 写进客户端配置文件(最低优先级,但最省事):
~/.my.cnf中加:
[client] socket = /var/run/mysqld/mysqld.sock
⚠️ 注意:-h localhost 会强制走 socket(哪怕你同时写了 -P 3306),而 -h 127.0.0.1 一定走 TCP。这点常被当成“连不上”的原因——你以为在连本地,其实 MySQL 认为你想走网络。
Python / Go 等代码里怎么用 socket 连?关键字段别写错
不同驱动对 socket 字段的命名不统一,写错就 fallback 到 TCP,甚至报错:
-
pymysql:用unix_socket参数,不是socket:unix_socket='/var/run/mysqld/mysqld.sock' -
mysql-connector-python:用unix_socket,同上 -
go-sql-driver/mysql:不支持原生 socket;必须用unix(/path/to/socket)/dbname格式写host字段,例如:user:pass@unix(/var/run/mysqld/mysqld.sock)/db - Java 的
mysql-connector-j:原生不支持,得靠junixsocket补丁,且要额外加 JAR 包到 classpath
最容易忽略的是:socket 文件的权限。如果程序以非 mysql 用户运行(比如 www-data、普通开发者账号),而 socket 文件权限是 srw-rw---- 且属组不是该用户所在组,就会报 Permission denied —— 这时候不是配置错了,是系统级权限没对齐。











