Sửa lỗi "mysqli_real_connect(): (HY000/2002): No such file or directory" trong WordPress

intermediate📝 WordPress2026-06-19| Ubuntu 20.04/22.04, Debian, CentOS — Apache hoặc Nginx + PHP 7.4/8.x + MySQL 8.x hoặc MariaDB 10.x, WordPress 5.x/6.x

Error Message

Warning: mysqli_real_connect(): (HY000/2002): No such file or directory in /var/www/html/wp-includes/class-wpdb.php
#mysql#cơ sở dữ liệu#socket#kết nối

TL;DR — Sửa Nhanh

Mở wp-config.php và thay localhost bằng 127.0.0.1 trong dòng DB_HOST:

// Trước
define( 'DB_HOST', 'localhost' );

// Sau
define( 'DB_HOST', '127.0.0.1' );

Thay đổi đơn giản này khiến PHP kết nối qua TCP thay vì đi tìm file Unix socket. Tải lại trang. Nếu hoạt động — xong. Nếu không, đọc tiếp.

Nguyên Nhân

MySQLi của PHP có một đường dẫn socket mặc định được biên dịch sẵn — thường là /tmp/mysql.sock. Nhưng cài đặt MySQL hoặc MariaDB của bạn gần như chắc chắn đặt socket ở chỗ khác, chẳng hạn /var/run/mysqld/mysqld.sock hoặc /var/lib/mysql/mysql.sock. Hai đường dẫn này không khớp nhau. PHP không tìm thấy file. WordPress bị lỗi.

Các trường hợp không khớp phổ biến nhất:

  • PHP được biên dịch với /tmp/mysql.sock, nhưng MySQL thực tế dùng /var/run/mysqld/mysqld.sock
  • Socket của MariaDB nằm ở /var/lib/mysql/mysql.sock trong khi PHP tìm ở chỗ khác
  • MySQL được cài lại hoặc nâng cấp khiến socket chuyển sang vị trí mới
  • MySQL chạy bên trong Docker hoặc VM — đường dẫn socket không tồn tại trên máy host

Lỗi này cụ thể hơn màn hình trắng chung chung "Error establishing a database connection" của WordPress. Nó xuất hiện thẳng trong output của PHP và chỉ rõ điểm thất bại:

Warning: mysqli_real_connect(): (HY000/2002): No such file or directory in /var/www/html/wp-includes/class-wpdb.php

Thông báo này thực ra rất hữu ích. Nó cho biết đây là vấn đề socket — không phải sai mật khẩu hay thiếu database.

Cách 1 — Chuyển Sang TCP (Nhanh Nhất)

Chỉnh sửa /var/www/html/wp-config.php (điều chỉnh đường dẫn nếu WordPress của bạn nằm ở chỗ khác):

define( 'DB_HOST', '127.0.0.1' );

TCP qua cổng 3306. Không cần file socket. Điều kiện duy nhất: MySQL phải đang lắng nghe trên giao diện loopback. Kiểm tra như sau:

ss -tlnp | grep 3306

Kết quả mong muốn trông như thế này:

LISTEN  0  151  127.0.0.1:3306  0.0.0.0:*  users:("mysqld",...)

Không thấy gì? MySQL chỉ dùng socket. Chuyển sang Cách 2 hoặc Cách 3.

Cách 2 — Tìm Socket Thực Và Trỏ PHP Vào Đó

Xác định vị trí MySQL thực sự đặt socket của nó:

# Hỏi thẳng MySQL
mysql -e "SHOW VARIABLES LIKE 'socket';"

# Tìm trong các file config
grep -r "socket" /etc/mysql/ /etc/my.cnf /etc/my.cnf.d/ 2>/dev/null

# Hoặc tìm trực tiếp trên ổ đĩa
find /var/run /tmp /var/lib/mysql -name "*.sock" 2>/dev/null

Khi đã có đường dẫn thực, truyền trực tiếp vào wp-config.php:

// Định dạng host:socket — WordPress truyền thẳng cho MySQLi
define( 'DB_HOST', 'localhost:/var/run/mysqld/mysqld.sock' );

MySQLi hỗ trợ định dạng host:socket_path một cách tự nhiên. Không cần thủ thuật gì thêm.

Cách 3 — Đặt Socket Mặc Định Trong php.ini

Muốn cách sửa áp dụng cho mọi ứng dụng PHP trên server, không chỉ riêng WordPress? Cấu hình trong php.ini.

# Tìm php.ini đang được dùng
php --ini | grep "Loaded Configuration"

# Chỉnh sửa (điều chỉnh số phiên bản cho khớp)
sudo nano /etc/php/8.1/cli/php.ini

Tìm dòng mysqli.default_socket và trỏ vào đường dẫn socket thực của bạn:

mysqli.default_socket = /var/run/mysqld/mysqld.sock

Có dùng PDO ở đâu không? Cập nhật luôn dòng đó:

pdo_mysql.default_socket = /var/run/mysqld/mysqld.sock

Khởi động lại PHP để áp dụng thay đổi:

# PHP-FPM
sudo systemctl restart php8.1-fpm

# Apache mod_php
sudo systemctl restart apache2

Cách 4 — MySQL Không Chạy

Trước khi đi tìm đường dẫn socket, hãy loại trừ nguyên nhân hiển nhiên nhất: MySQL bị crash.

sudo systemctl status mysql
# hoặc
sudo systemctl status mysqld

# Đang dừng? Khởi động lại:
sudo systemctl start mysql

# Xem nguyên nhân khiến nó dừng:
sudo journalctl -u mysql -n 50 --no-pager

Nếu MySQL liên tục crash khi khởi động, hãy kiểm tra /var/log/mysql/error.log. Nguyên nhân thực sự hầu như luôn nằm ở đó — ổ đĩa đầy, InnoDB bị hỏng, vượt giới hạn bộ nhớ.

Cách 5 — Docker Hoặc Cấu Hình Server Tùy Chỉnh

Đang chạy WordPress trong Docker? localhost bên trong container trỏ đến chính container đó — không phải máy host hay container anh em. Hãy dùng tên service thực hoặc địa chỉ IP thay thế:

# Tên service định nghĩa trong docker-compose.yml
define( 'DB_HOST', 'db' );

# MySQL trên host — Mac/Windows Docker Desktop
define( 'DB_HOST', 'host.docker.internal' );

# MySQL trên host — Linux Docker default bridge
define( 'DB_HOST', '172.17.0.1' );

Xác Nhận Đã Sửa Xong

Trước khi tải lại trang, hãy kiểm tra kết nối từ dòng lệnh. Lấy DB_USER, DB_PASSWORDDB_NAME từ wp-config.php, rồi chạy:

# Qua TCP
mysql -h 127.0.0.1 -u your_wp_user -p your_wp_database

# Qua socket
mysql -S /var/run/mysqld/mysqld.sock -u your_wp_user -p

Kết nối không có lỗi? WordPress sẽ hoạt động bình thường. Tải trang lên, rồi theo dõi error log để xác nhận không còn vấn đề gì:

sudo tail -f /var/log/nginx/error.log
# hoặc
sudo tail -f /var/log/apache2/error.log

Nên Dùng Cách Nào

  • Shared hosting / server được quản lý — Cách 1 (TCP). Hoạt động được hầu hết mọi lúc. Chỉ cần truy cập vào wp-config.php, không cần quyền quản trị server.
  • VPS với toàn quyền kiểm soát — Thử Cách 1 trước. Thêm Cách 3 nếu muốn đặt đường dẫn socket mặc định cho toàn bộ ứng dụng trên máy.
  • Cấu hình Docker — Cách 5. Đừng cố chia sẻ socket giữa các container — TCP đơn giản hơn và dễ di chuyển hơn.
  • MySQL không chạy — Cách 4 trước tiên. Không có gì khác quan trọng khi service chưa thực sự khởi động.

Related Error Notes