Lỗi này là gì
Bạn thử kết nối vào MySQL từ ứng dụng hoặc từ một máy chủ từ xa và nhận được thông báo lỗi này:
ERROR 1129 (HY000): Host '192.168.1.10' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
MySQL đã chặn máy chủ của bạn vì phát hiện quá nhiều lần kết nối thất bại liên tiếp. Khi một host vượt ngưỡng max_connect_errors, MySQL sẽ đưa IP đó vào danh sách đen. IP đó sẽ không thể kết nối lại cho đến khi bạn xóa lệnh chặn thủ công — hoặc khởi động lại máy chủ.
Nguyên nhân xảy ra lỗi
Mỗi khi một client kết nối nhưng thất bại trước khi xác thực hoàn tất — do mạng bị ngắt, handshake bị hủy ngang, hoặc client được cấu hình sai — MySQL sẽ tăng bộ đếm nội bộ cho host đó. Khi đạt đến giới hạn max_connect_errors (mặc định: 100), MySQL sẽ đóng cửa với host đó.
Các nguyên nhân phổ biến:
- Ứng dụng khởi động lại hoặc bị crash giữa chừng khi đang kết nối, để lại các socket TCP mở dở
- Mạng không ổn định giữa app server và database
- Connection pool được cấu hình kết nối lại quá tích cực khi gặp lỗi
- Firewall hoặc load balancer cắt kết nối trước khi MySQL hoàn tất handshake
- Thư viện MySQL client cũ có lỗi trong quá trình đàm phán SSL/TLS
Bước 1 — Mở chặn host ngay lập tức
Trước tiên, hãy khôi phục quyền truy cập bằng cách xóa host cache. Có ba cách để thực hiện:
Cách A: Dùng mysqladmin
mysqladmin -u root -p flush-hosts
Cách B: Từ bên trong phiên MySQL
-- Kết nối với quyền root từ localhost (không bị chặn)
mysql -u root -p
-- Sau đó chạy lệnh:
FLUSH HOSTS;
Cách C: Chỉ dành cho MySQL 8.0.26+ — truncate bảng performance_schema
TRUNCATE TABLE performance_schema.host_cache;
Cả ba cách đều đặt lại bộ đếm lỗi cho mọi host đang bị chặn. Chạy một trong số đó, sau đó thử kết nối lại — kết nối sẽ thành công ngay lập tức.
Bước 2 — Tìm hiểu tại sao kết nối bị thất bại
Xóa host cache chỉ giúp bạn có thêm thời gian. Nếu không khắc phục nguyên nhân gốc rễ, lệnh chặn sẽ quay lại — đôi khi chỉ trong vài phút trên app server có tải cao. Hãy bắt đầu từ MySQL error log:
# Vị trí mặc định trên Ubuntu/Debian
tail -100 /var/log/mysql/error.log
# Trên CentOS/RHEL
tail -100 /var/log/mysqld.log
# Không biết log của bạn ở đâu?
SHOW VARIABLES LIKE 'log_error';
Tìm các dòng chứa Aborted connection, Got an error reading communication packets, hoặc Got timeout reading communication packets. Những dòng này chỉ thẳng vào các kết nối đang bị lỗi.
Sau đó kiểm tra các bộ đếm kết nối bị hủy:
SHOW GLOBAL STATUS LIKE 'Aborted_connects';
SHOW GLOBAL STATUS LIKE 'Aborted_clients';
- Aborted_connects — thất bại trước khi xác thực. Đây chính xác là thứ kích hoạt ERROR 1129.
- Aborted_clients — kết nối thành công nhưng ngắt kết nối không đúng cách. Ít khẩn cấp hơn nhưng vẫn nên theo dõi.
Bước 3 — Tăng max_connect_errors (giải pháp tạm thời)
Bạn thường xuyên bị gián đoạn nhưng không nghiêm trọng — VPN không ổn định, Kubernetes liveness probe kiểm tra quá gắt, hoặc health check không thể xác thực? Bạn có thể tăng ngưỡng để MySQL không chặn quá nhanh.
Áp dụng ngay mà không cần khởi động lại:
SET GLOBAL max_connect_errors = 1000000;
Lưu vĩnh viễn vào my.cnf / my.ini:
[mysqld]
max_connect_errors = 1000000
Sau đó khởi động lại MySQL:
# Ubuntu/Debian
sudo systemctl restart mysql
# CentOS/RHEL
sudo systemctl restart mysqld
Đặt giá trị này rất cao — hoặc 0 trên MySQL 8.0.36+ để tắt hoàn toàn tính năng chặn — là ổn trên mạng nội bộ nơi bạn tin tưởng tất cả các host. Với bất kỳ thứ gì hướng ra internet công cộng, hãy giữ giá trị thấp hơn.
Bước 4 — Khắc phục vấn đề kết nối thực sự
Connection pool kết nối lại quá tích cực?
Nhiều framework tấn công MySQL khi khởi động bằng các lần kết nối lại liên tục. Hãy thêm kiểm tra pre-ping và khoảng thời gian recycle. Đây là ví dụ với Python SQLAlchemy:
engine = create_engine(
DATABASE_URL,
pool_pre_ping=True, # Kiểm tra kết nối trước khi sử dụng
pool_recycle=3600, # Hủy và thay thế kết nối sau 1 giờ
connect_args={"connect_timeout": 10}
)
Giảm kích thước pool trong quá trình kiểm tra ban đầu cũng giúp xác định liệu chính pool có phải là nguyên nhân hay không.
Nghi ngờ có vấn đề mạng hoặc firewall?
Kiểm tra kết nối TCP thuần từ host bị chặn trước khi chỉnh bất kỳ cấu hình MySQL nào:
telnet 192.168.1.100 3306
# hoặc
nc -zv 192.168.1.100 3306
Nếu kết nối bị ngắt hoặc treo, bạn đang gặp vấn đề về mạng. Thay đổi cấu hình MySQL sẽ không giúp được gì.
Đàm phán SSL/TLS gây ra lỗi?
# Thử kết nối với SSL bị tắt hoàn toàn
mysql -h 192.168.1.100 -u myuser -p --ssl-mode=DISABLED
Kết nối bình thường khi tắt SSL nhưng thất bại trong điều kiện thông thường? Hãy cập nhật thư viện client hoặc kiểm tra lại cấu hình certificate.
Xác nhận đã sửa xong
Sau khi xóa host cache và xử lý nguyên nhân gốc rễ, hãy xác nhận IP không còn bị chặn nữa:
-- Chỉ dành cho MySQL 8.0+
SELECT host, host_validated, sum_connect_errors, count_host_blocked_errors
FROM performance_schema.host_cache
WHERE host = '192.168.1.10';
sum_connect_errors phải bằng 0 hoặc gần 0. count_host_blocked_errors không được tiếp tục tăng.
Kiểm tra nhanh từ command line:
mysql -h 192.168.1.100 -u myuser -p -e "SELECT 1;"
Trả về 1? Vậy là xong.
Ngăn lỗi tái diễn
- Bật
pool_pre_pingtrong connection pool — nó kiểm tra kết nối trước khi đưa vào sử dụng, giúp MySQL không bao giờ thấy socket chết giữa chừng khi handshake - Tinh chỉnh
wait_timeoutvàinteractive_timeoutcho phù hợp với thời gian ứng dụng thực sự giữ kết nối mở - Theo dõi
Aborted_connectstrong hệ thống metrics — một đột biến ở đây là dấu hiệu cảnh báo sớm, thường xuất hiện vài phút trước khi ERROR 1129 xảy ra - Đặt ProxySQL hoặc HAProxy giữa ứng dụng và MySQL — proxy xử lý logic kết nối lại một cách khéo léo và không bắn loạt TCP retry thô vào MySQL khi khởi động lại
- Thêm
FLUSH HOSTSvào deployment script nếu app server thường xuyên khởi động lại trong quá trình release — ngăn việc tích lũy lệnh chặn trong quá trình rolling deploy

