错误码(13) Permission denied表明是Unix socket权限问题而非路径错误,需检查mysqld进程用户与客户端用户在socket目录及文件上的属组和权限匹配性,推荐通过加组、设setgid目录权限或改用TCP连接解决。

直接说结论:报 Can't connect to local MySQL server through socket 且错误码是 (13)(Permission denied),不是路径错了,而是目录或 socket 文件的权限/属组不匹配——mysqld 进程用户(通常是 mysql)和你的客户端用户(比如 ubuntu 或 www-data)之间无法完成 Unix domain socket 的文件系统级握手。
怎么确认是权限拒绝而不是路径错误?
错误信息里明确含 Permission denied(不是 No such file or directory),或者用 strace mysql -u root -S /path/to/mysql.sock 2>&1 | grep connect 看到 connect(3, {sa_family=AF_UNIX, sun_path="/path/to/mysql.sock"}, 110) = -1 EACCES (Permission denied),就是典型的权限问题。
常见触发场景:
- 你用
sudo mysql -u root能连,但普通用户或 PHP 进程(如www-data)连不上 -
ls -l /var/run/mysqld/显示目录权限是drwxr-x---,属组是mysql,但当前用户不在mysql组里 - socket 文件本身权限是
srw-rw----,但属组不包含客户端用户
修复 socket 目录和文件权限的实操步骤
别改 chmod 777,那会破坏安全模型。按最小权限原则操作:
- 把当前用户加进
mysql组:sudo usermod -aG mysql $USER,然后完全退出终端重登(groups命令要能看到mysql) - 确保 socket 所在目录可进入且可写:
sudo chgrp mysql /var/run/mysqld(如果属组不对),再sudo chmod 2775 /var/run/mysqld(2是 setgid,保证新建文件继承组) - 检查 socket 文件权限:
ls -l /var/run/mysqld/mysqld.sock,应为srw-rw---- 1 mysql mysql;如果不是,重启mysqld(不要手动touch或chmod它) - 如果用的是 Docker,宿主机映射的目录(如
/var/run/mysqld)必须对容器内mysql用户 UID/GID 可写,且 SELinux 上下文正确(chcon -Rt container_file_t /host/path)
PHP/Python 连接时绕过 socket 权限问题的稳妥方式
它们不读 my.cnf 的 [client] 段,也不自动加入 mysql 组,硬碰权限容易翻车。更可靠的做法是切换通信协议:
- PHP 中,把
'hostname' => 'localhost'改成'hostname' => '127.0.0.1',强制走 TCP,避开 socket 权限校验(前提是mysqld开了bind-address = 127.0.0.1且没设skip-networking) - Python 的
pymysql或mysql-connector-python,显式传参:pymysql.connect(host='127.0.0.1', port=3306, user='root', ...),不要依赖host='localhost' - 宝塔面板里 PHP 连接 MySQL 失败,优先改网站根目录下的
.env或数据库配置,把DB_HOST=localhost换成DB_HOST=127.0.0.1
真正难搞的不是找不到 mysql.sock,而是它明明存在、路径也对、服务也跑着,就卡在 connect() 系统调用返回 EACCES ——这时得一层层查目录属组、用户组成员关系、SELinux 上下文,缺一不可。


















