首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL show processlist 出現 "unauthenticated user" 根因分析與解決方案

     編輯:MySQL 綜合教學

現場還原

某計費系統服務器突然負載飆升,CPU 被 mysqld 進程佔滿,僅 50 並發呼叫卻出現大量僵屍進程,AGI 程序響應極慢。重啟服務器無效。登入 MySQL 執行 SHOW PROCESSLIST 發現異常進程:

+----+-----------------------+-----------+------+---------+------+-----------------------+------------------+
| Id | User                  | Host      | db   | Command | Time | State                 | Info             |
+----+-----------------------+-----------+------+---------+------+-----------------------+------------------+
| 123| unauthenticated user  | localhost | NULL | Connect |  15  | reading from net      | NULL             |
+----+-----------------------+-----------+------+---------+------+-----------------------+------------------+

關鍵特徵:User="unauthenticated user"、Command="Connect"、State="reading from net"、Host="localhost"。

根因深度剖析

連接建立流程與阻塞點

  1. 客戶端發起 TCP 連接 → MySQL 接受連接,分配線程
  2. 關鍵步驟:MySQL 執行反向 DNS 解析(將客戶端 IP 解析為主機名)
  3. 解析完成前,線程處於 reading from net 狀態,用戶顯示為 unauthenticated user
  4. 解析超時或失敗 → 線程阻塞累積 → 連接數耗盡 → 新連接被拒/極慢

為什麼是 localhost 卻需 DNS 解析?

MySQL 判斷客戶端主機名的邏輯:

  • TCP 連接來源 IP → 反向查詢 PTR 記錄 → 獲取主機名
  • 再正向查詢 A/AAAA 記錄驗證一致性
  • 最終用解析出的主機名匹配 mysql.user 表的 Host 列

即使是 127.0.0.1,若 /etc/hosts 無 localhost 記錄或 DNS 服務異常,同樣會觸發解析超時。

解決方案

方案一:禁用 DNS 解析(推薦,立竿見影)

修改 /etc/my.cnf(Windows 為 my.ini),[mysqld] 區塊添加:

[mysqld]
skip-name-resolve

重啟 MySQL:systemctl restart mysqld

副作用與應對

影響說明應對措施
授權表 Host 列不能再使用主機名(如 'user'@'localhost')統一改用 IP:'user'@'127.0.0.1'、'user'@'192.168.1.%'
現有賬號失效原 localhost 賬號無法登入執行 RENAME USER 'user'@'localhost' TO 'user'@'127.0.0.1'; 或重新授權
複製/集群配置CHANGE MASTER TO MASTER_HOST='master-host' 需用 IP全鏈路統一使用 IP 地址

方案二:修復 DNS/Hosts 配置(治本)

  1. 檢查 /etc/hosts:確保包含 127.0.0.1 localhost、::1 localhost、服務器真實 IP 對應主機名
  2. 驗證 DNS 服務:dig -x 127.0.0.1、nslookup localhost 應秒級返回
  3. 檢查 /etc/resolv.conf:nameserver 指向可用 DNS,options 包含 timeout:1 attempts:1
  4. MySQL 內部主機名緩存:FLUSH HOSTS; 清理緩存的解析失敗記錄

方案三:調整連接超時參數(緩解)

[mysqld]
connect_timeout=10          # 默認 10 秒,TCP 握手後等待認證包超時
wait_timeout=30             # 非交互式連接空閒斷開
interactive_timeout=300     # 交互式連接空閒斷開

可減少阻塞線程堆積,但無法解決根因。

驗證與監控

-- 確認參數生效
SHOW VARIABLES LIKE 'skip_name_resolve';

-- 監視連接狀態
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Aborted_connects';

-- 定期清理緩存
FLUSH HOSTS;

避坑指南

  1. 不要忽視 IPv6:::1 解析失敗同樣導致阻塞,/etc/hosts 必須雙棧配置
  2. 容器化環境:Docker/K8s 內部 DNS 可能不穩,強烈建議啟用 skip-name-resolve
  3. 授權表清理:禁用 DNS 後,務必清理殘留的主機名賬號,避免權限審計混亂
  4. 監控告警:Aborted_connects 突增 + unauthenticated user 出現 = DNS 解析故障特徵

總結

unauthenticated user 並非入侵攻擊,而是 MySQL 反向 DNS 解析阻塞 的標誌性癥狀。生產環境強烈建議啟用 skip-name-resolve,以 IP 方式管理授權,徹底規避 DNS 不穩帶來的可用性風險。若業務強依賴主機名授權,則必須構建高可用、低延遲的內部 DNS 基礎設施,並配置完善的 /etc/hosts 兜底。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved