一、Thread Cache (線程緩存池)
核心作用
避免頻繁創建/銷毀線程開銷。短連接場景效果顯著,長連接亦有益。
關鍵參數
| 參數 | 含義 | 建議值 (物內存) |
thread_cache_size | 緩存池最大線程數 | 1G→8, 2G→16, 4G→32, >4G→64 (短連接可適當加大) |
thread_stack | 每線程棧大小 | 默認 192KB/256KB 通常足夠,勿隨意調小 |
thread_handling | 處理模式 | one-thread-per-connection (默認),no-threads 僅調試用 |
狀態監控與命中率計算
mysql> SHOW VARIABLES LIKE 'thread%';
+-------------------+-------------------------+
| Variable_name | Value |
+-------------------+-------------------------+
| thread_cache_size | 32 |
| thread_handling | one-thread-per-connection|
| thread_stack | 196608 |
+-------------------+-------------------------+
mysql> SHOW STATUS LIKE '%connections%';
+----------------------+--------+
| Variable_name | Value |
+----------------------+--------+
| Connections | 199156 |
| Max_used_connections | 31 |
+----------------------+--------+
mysql> SHOW STATUS LIKE '%thread%';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Threads_cached | 3 |
| Threads_connected | 6 |
| Threads_created | 8689 |
| Threads_running | 5 |
+-------------------------+-------+
命中率公式
Thread_Cache_Hit = (Connections - Threads_created) / Connections * 100%
= (199156 - 8689) / 199156 ≈ 95.6%
判斷:> 90% 為優秀,95%+ 為極佳。本例中 thread_cache_size=32 略大,實際 Threads_cached=3,建議調至 16 或 8。
二、Table Cache (表緩存) — 即 table_open_cache
機制差異
- MyISAM:數據文件描述符獨享,索引文件描述符共享
- InnoDB 共享表空間:單一數據文件,FD 極少
- InnoDB 獨立表空間:每表一
.ibd,FD 隨表數增長
官方建議 vs 實戰
- 手冊建議:
table_cache = max_connections × N (N = 單查詢最大表數) + 臨時表預留
- 實戰:夠用即可,監控
Opened_tables 增長率決定是否擴容
關鍵狀態
| 變量 | 含義 | 告警閾值 |
Open_tables | 當前打開表數 | 接近 table_open_cache |
Opened_tables | 緩存未命中累計 | 快速增長 (>50/秒) |
Open_table_definitions | 緩存 .frm 文件數 (5.1.3+) | - |
Opened_table_definitions | .frm 緩存未命中 (5.1.24+) | - |
緩存淘汰與擴容邏輯
- 緩存滿 + 新表訪問 → LRU 淘汰最舊未用表
- 緩存滿 + 無可淘汰表 + 新表訪問 → 臨時擴容緩存
- 臨時擴容狀態下表釋放 → 立即縮容回標準大小
FLUSH TABLES → 全量清理緩存
三、綜合調優清單
| 參數 | 典型值 | 監控指標 | 調整觸發條件 |
| thread_cache_size | 16-64 | Threads_created 增長率 | 命中率 < 90% 或 Threads_created 急增 |
| table_open_cache | 4000-20000 | Opened_tables 增長率 | Opened_tables > 100/秒 或 Open_tables ≈ 參數值 |
驗證腳本
#!/bin/bash
# 每 5 分鐘採樣一次
mysql -e "SHOW GLOBAL STATUS LIKE 'Threads_created'; SHOW GLOBAL STATUS LIKE 'Opened_tables';" \
| awk '/Threads_created|Opened_tables/{print strftime("%F %T"), $1, $2}' >> /var/log/mysql_cache_trend.log