mysqld-nt: Out of memory (Needed 1677720 bytes)
錯誤日志反復出現,服務器雖有 32GB 物理內存,但運行 32 位 Windows/Linux 系統,MySQL 進程無法利用超 4GB 內存(實際可用約 2-3GB)。
key_buffer_size + innodb_buffer_pool_size + (read_buffer_size + sort_buffer_size + join_buffer_size) * max_connections + 線程棧、臨時表、解析樹等文中配置片段存在嚴重超分配:
key_buffer_size = 1.2GB # 1294963200 bytes
sort_buffer_size = 2.1GB # 2294967295 bytes <-- 極度危險!
read_buffer_size = 2GB # 2147479552 bytes <-- 極度危險!
max_connections = 100 (假設)
**理論峰值內存** = 1.2G + 1.5G (InnoDB) + (2G + 2.1G) * 100 = **411 GB** 💥 遠超 32 位 4GB 限制。
| 參數 | 推薦值(32位/4GB RAM) | 推薦值(64位/32GB RAM) | 說明 |
|---|---|---|---|
| key_buffer_size | 128-256M | 1-2G | MyISAM 索引緩衝,InnoDB 可適當減小 |
| innodb_buffer_pool_size | 512M-1G | 20-24G (60-75% RAM) | InnoDB 核心緩衝,**最關鍵參數** |
| innodb_log_buffer_size | 8-16M | 64-128M | 事務日志緩衝 |
| query_cache_size | 0 (禁用) | 0 (禁用) | MySQL 5.7+ 建議關閉,高並發下鎖爭用嚴重 |
| 參數 | 推薦值 | 危險閾值 | 說明 |
|---|---|---|---|
| read_buffer_size | 128K-256K | > 4M | 全表掃描緩衡 |
| read_rnd_buffer_size | 256K-512K | > 4M | 排序後隨機讀緩衡 |
| sort_buffer_size | 256K-2M | > 4M | 排序緩衡,**超大值極易 OOM** |
| join_buffer_size | 256K-1M | > 4M | 無索引 JOIN 緩衡 |
| thread_stack | 256K | 默認即可 | 線程棧大小 |
| max_connections | 200-500 | > 1000 | 配合線程池使用 |
tmp_table_size = 64M
max_heap_table_size = 64M
# 兩者取較小值為內存臨時表上限,超過轉 MyISAM 磁盤表
# 建議:key_buffer_size ≈ max_heap_table_size / 4
[mysqld]
# 全局緩衝
key_buffer_size = 128M
innodb_buffer_pool_size = 1G
innodb_log_buffer_size = 16M
query_cache_size = 0
query_cache_type = 0
# 線程緩衝(保守值)
read_buffer_size = 256K
read_rnd_buffer_size = 512K
sort_buffer_size = 512K
join_buffer_size = 256K
thread_stack = 256K
# 連接控制
max_connections = 300
max_user_connections = 250
# 臨時表
tmp_table_size = 64M
max_heap_table_size = 64M
# InnoDB 核心
innodb_log_file_size = 256M
innodb_log_files_in_group = 2
innodb_flush_log_at_trx_commit = 1
innodb_file_per_table = ON
# 其它
max_allowed_packet = 32M
table_open_cache = 2000
**估算峰值**:1.1G (全局) + (1.5M * 300) ≈ 1.5G,**安全裕度充足**。
同服務器 PHP 报錯:
Fatal error: Out of memory (allocated 262144) (tried to allocate 19456 bytes)
**獨立於 MySQL**,屬於 PHP 進程內存耗盡:
php.ini:memory_limit = 256M(視腳本需求調整)opcache.enable=1 opcache.memory_consumption=128MySQL "Out of memory" 本質是 **32 位進程虛擬地址空間耗盡**,而非物理內存不足。核心對策:
配置修改後**必須重啟 MySQL 生效**,建議變更前備份 my.cnf,變更後觀察錯誤日志 24h 確認穩定。
