
資料庫常見問題排查與日常維護
連線數相關的問題
Too many connections
連線數達到上限。先確認實際狀況:
SHOW STATUS LIKE 'Threads_connected'; SHOW STATUS LIKE 'Max_used_connections'; SHOW VARIABLES LIKE 'max_connections'; SHOW PROCESSLIST;
常見原因
- 應用端的行程數超過資料庫上限——PHP-FPM 的 max_children 設得比 max_connections 高
- 使用持久連線但未妥善管理
- 連線未正確關閉
- 有查詢卡住不放——連線被長時間佔用
處理
調高 max_connections 是治標。應先確認是不是有查詢卡住,用 SHOW PROCESSLIST 看有沒有長時間執行的語句。
相關的行程池設定見網頁伺服器的效能相關設定。
鎖等待與死結
Lock wait timeout exceeded
交易在等待另一個交易釋放鎖,超過等待時間。
-- 查看目前的交易 SELECT * FROM information_schema.innodb_trx; -- 查看鎖等待情況(版本不同名稱有異) SHOW ENGINE INNODB STATUS;
常見原因
- 交易開啟後長時間未提交——最常見
- 交易中包含了耗時的操作——例如呼叫外部服務
- 大量資料的更新未分批
處理原則
- 交易要短——只包含必要的資料庫操作
- 不要在交易中做網路請求或檔案處理
- 大批量更新要分批
- 必要時可終止卡住的連線
磁碟空間耗盡
這是實際會導致資料庫停止運作的事故。常見的空間消耗來源:
- 二進位日誌未設定保留期限——最常見
- 慢查詢日誌與一般日誌累積
- 暫存檔案
- 資料表本身的成長
檢查
-- 各資料表的大小
SELECT table_name,
ROUND((data_length + index_length) / 1024 / 1024, 2) AS size_mb
FROM information_schema.tables
WHERE table_schema = 'your_database'
ORDER BY (data_length + index_length) DESC;
建議把磁碟用量納入監控,並設定二進位日誌的保留期限。
資料表損毀
多見於 MyISAM,InnoDB 較少見但仍可能發生。
CHECK TABLE tablename; REPAIR TABLE tablename; -- 僅適用 MyISAM
InnoDB 的損毀處理較複雜,通常需要以特殊模式啟動並匯出資料。操作前務必先備份現有檔案。
遇到這種情況時,從備份還原通常比嘗試修復更可靠。
資料表空間未釋放
刪除大量資料後,磁碟空間沒有減少。這是正常現象——空間被標記為可重複使用,但沒有歸還給作業系統。
OPTIMIZE TABLE tablename;
注意這個操作會鎖表並需要額外的磁碟空間(相當於該表的大小),大表應選在離峰時段執行。
查詢突然變慢
原本正常的查詢突然變慢,可能的原因:
- 資料量成長——原本沒索引也夠快,資料多了就不行
- 統計資訊過期——最佳化器選錯了執行計畫
- 索引被刪除或失效
- 排序規則不一致——JOIN 時導致索引無法使用
- 伺服器資源被其他行程佔用
更新統計資訊
ANALYZE TABLE tablename;
這個操作成本低,遇到執行計畫異常時值得先試。
日常監控的指標
| 指標 | 意義 |
|---|---|
| 連線數 | 是否接近上限 |
| 緩衝池命中率 | 偏低代表記憶體不足 |
| 慢查詢數量 | 趨勢是否上升 |
| 磁碟用量 | 資料與日誌的成長 |
| 複寫延遲 | 若有複寫架構 |
定期維護建議
每月
- 檢視慢查詢日誌,處理新出現的問題查詢
- 確認備份正常產生
- 檢查磁碟用量趨勢
每季
- 檢視資料表大小,評估是否需要歸檔舊資料
- 檢查未使用的索引
- 確認字元集與排序規則一致
每半年
- 實際還原一次備份到測試環境驗證
- 檢視版本的支援狀態
- 檢視使用者帳號與權限
權限的最小化
應用程式使用的資料庫帳號,不應該有超出需要的權限。
- 一般網站應用——通常只需要基本的增刪改查權限
- 不需要 DROP、CREATE USER、GRANT 等權限
- 不要用最高權限帳號連線
- 不同的應用使用不同的帳號
- 限制連線來源——若資料庫與網站同機,可限制為本機連線
這是降低入侵後損害範圍最有效的做法之一。詳見主機層與存取控制的防護設定。
排查的通用順序
- 看錯誤日誌——資料庫的錯誤日誌通常直接說明原因
- 看目前的連線與查詢——
SHOW PROCESSLIST - 檢查系統資源——磁碟、記憶體、負載
- 比對最近的變更——程式部署、設定調整、資料量成長
- 在測試環境重現
第四項最有效——突然出現的問題,幾乎都能對應到某個具體的變更。
本文以 MySQL 與 MariaDB 的常見版本為例,實際的指令、預設值與可用選項可能因版本與發行版而異。執行任何變更前請確實備份,並先在測試環境驗證。