MySQL 啟動日誌出現 Changed limits: max_open_files: 2048 max_connections: 1910 table_cache: 64 警告,表示參數組合超過系統文件描述符限制,MySQL 自動降級調整。本文解析匹配公式、調整策略、Windows/Linux 差異。
MySQL 根據 max_connections、table_open_cache (舊名 table_cache) 估算所需文件描述符,若超過 max_open_files (系統/進程限制),自動降低參數並記錄警告。
所需文件描述符 ≈ max_connections + table_open_cache * 2
-- 系統限制 (Windows 固定 2048,Linux 可調)
max_open_files ≥ max_connections + table_open_cache * 2 + 安全餘量
原理: 每個連線需 1-2 個文件描述符 (通訊、臨時表),每個緩存表需 2 個 (.frm + .ibd/.MYD/.MYI)。
[mysqld]
max_connections = 500
table_open_cache = 1024
-- 估算: 500 + 1024*2 = 2548 > 2048 (Windows 仍超限)
-- Windows 建議:
max_connections = 300
table_open_cache = 800
-- 估算: 300 + 800*2 = 1900 < 2048 ✓
# /etc/security/limits.conf
mysql soft nofile 65535
mysql hard nofile 65535
# /etc/sysctl.conf
fs.file-max = 1000000
# systemd
# /usr/lib/systemd/system/mysqld.service
[Service]
LimitNOFILE=65535
# my.cnf
[mysqld]
max_connections = 2000
table_open_cache = 4000
open_files_limit = 65535 # 明確聲明,MySQL 將嘗試 setrlimit
Windows 進程預設最大打開文件 2048,修改註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MySQL\Parameters\MaxOpenFiles 可能導致不穩定。建議**降低參數適配 2048 限制**。
# 重啟後檢查錯誤日誌
grep "Changed limits" /var/log/mysql/error.log
# 無輸出表示修正成功
# 確認實際生效值
mysql> SHOW VARIABLES LIKE 'max_open_files';
mysql> SHOW VARIABLES LIKE 'table_open_cache';
mysql> SHOW VARIABLES LIKE 'max_connections';
| 參數 | 舊名 | 含義 | 影響 |
|---|---|---|---|
max_connections | - | 最大客戶端連線數 | 每連線佔用文件描述符、線程記憶體 |
table_open_cache | table_cache | 表緩存數量 | 每表佔用 2-3 個文件描述符 |
max_open_files | - | 進程最大打開文件數 | 系統硬限制,超過則 MySQL 自動降級 |
open_files_limit | - | MySQL 請求的文件限制 | Linux 下可通過 setrlimit 提升 |
open_files_limit,按業務併發設定 max_connections、table_open_cachemax_connections=300, table_open_cache=800,應用層強制連線池Opened_tables 增長速率 (應緩慢)、Table_open_cache_misses、Connection_errors_max_connectionsgrep -i "changed limits\|too many open files" /var/log/mysql/error.log