應用報錯:Out of memory (Needed 16777224 bytes),約 16 MB 記憶體分配失敗。
依據官方文檔,重點調整以下記憶體相關參數(單位:bytes):
| 參數 | 預設值 | 調整後 | 說明 |
|---|---|---|---|
max_heap_table_size | 16,777,216 (16M) | 67,108,864 (64M) | MEMORY 表最大容量,臨時表轉磁碟閾值 |
tmp_table_size | 16,777,216 (16M) | 67,108,864 (64M) | 內部臨時表最大值,超過則轉 MyISAM 磁碟表 |
query_cache_limit | 1,048,576 (1M) | 4,194,304 (4M) | 單條查詢快取上限,大結果集需調大 |
修改 my.cnf 後重啟驗證:
mysql> SHOW VARIABLES LIKE 'max_heap_table_size';
+---------------------+----------+
| Variable_name | Value |
+---------------------+----------+
| max_heap_table_size | 67108864 |
+---------------------+----------+
查閱官方 Bug #31898 及文檔 Out of Memory,發現核心原因在於:
DEALLOCATE PREPARE 或將用戶變量置空PREPARE stmt FROM @sql;
EXECUTE stmt;
-- 缺少清理步驟,導致記憶體洩漏
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @sql = ''; -- 釋放用戶變量佔用的記憶體
PREPARE 都有對應的 DEALLOCATE PREPARE。LEFT JOIN,配合 EXPLAIN 建立必要索引。Prepared_stmt_count、Qcache_free_memory、Created_tmp_disk_tables。修正部署後持續觀察一週,錯誤完全消失,記憶體佔用穩定在合理區間。