內存分配是 MySQL 調優的核心。理解「線程共享」與「線程獨享」兩大內存池的組成、參數控制、計算公式,才能精準規劃實例記憶體上限,避免 OOM 或資源浪費。
SHOW GLOBAL VARIABLES LIKE '%buffer%'; +-------------------------+------------+ | Variable_name | Value | +-------------------------+------------+ | bulk_insert_buffer_size | 4194304 | | innodb_buffer_pool_size | 2013265920 | -- 1.9GB | innodb_change_buffering | inserts | | innodb_log_buffer_size | 8388608 | | join_buffer_size | 1048576 | | key_buffer_size | 16777216 | | myisam_sort_buffer_size | 262144 | | net_buffer_length | 16384 | | preload_buffer_size | 32768 | | read_buffer_size | 1048576 | | read_rnd_buffer_size | 1048576 | | sort_buffer_size | 1048576 | | sql_buffer_result | OFF | +-------------------------+------------+ SHOW GLOBAL VARIABLES LIKE '%cache%'; +------------------------------+----------------------+ | Variable_name | Value | +------------------------------+----------------------+ | binlog_cache_size | 1048576 | | have_query_cache | YES | | key_cache_age_threshold | 300 | | key_cache_block_size | 1024 | | key_cache_division_limit | 100 | | max_binlog_cache_size | 18446744073709547520 | | query_cache_limit | 1048576 | | query_cache_min_res_unit | 4096 | | query_cache_size | 0 | | query_cache_type | ON | | query_cache_wlock_invalidate | OFF | | table_definition_cache | 256 | | table_open_cache | 100 | | thread_cache_size | 100 | +------------------------------+----------------------+
Used_Mem =
-- 全局共享內存
key_buffer_size
+ query_cache_size
+ innodb_buffer_pool_size
+ innodb_additional_mem_pool_size -- 5.7 移除
+ innodb_log_buffer_size
-- 線程獨享內存 × max_connections
+ max_connections * (
read_buffer_size
+ read_rnd_buffer_size
+ sort_buffer_size
+ join_buffer_size
+ binlog_cache_size
+ thread_stack
+ tmp_table_size
+ bulk_insert_buffer_size
)
關鍵認知:線程獨享內存不會在連線建立時一次性分配,而是按需、分階段分配(如排序時才分配 sort_buffer)。實際峰值遠低於理論上限,但規劃時必須按上限預留。
| 參數 | 用途 | 觸發場景 | 調優建議 |
|---|---|---|---|
| read_buffer_size | 順序掃描緩存 | 全表掃描、全索引掃描 | 256K-1M,大表可適當增大 |
| read_rnd_buffer_size | 隨機讀取緩存 | 索引查找回表、排序後 JOIN | 1-2M,配合 sort_buffer |
| sort_buffer_size | 排序緩存 | ORDER BY、GROUP BY、DISTINCT | 1-4M,超大排序會落盤 |
| join_buffer_size | JOIN 緩存 | 無索引 JOIN (ALL/INDEX JOIN) | 256K-1M,過大反增 CPU |
| thread_stack | 線程棧 | 每線程固定分配 | 256K-512K,勿動 |
| tmp_table_size | 內存臨時表上限 | 衍生表、UNION、複雜 GROUP BY | 64M-256M,受 max_heap_table_size 限制 |
| bulk_insert_buffer_size | 批量插入緩存 | INSERT ... VALUES (),()... / LOAD DATA | 8M-32M,MyISAM 專用 |
| binlog_cache_size | 事務 Binlog 緩存 | 事務執行過程 | 32K-1M,長事務需增大 |
| 參數 | 用途 | 關鍵特性 | 調優建議 |
|---|---|---|---|
| key_buffer_size | MyISAM 索引緩存 | 全局共享、塊式存儲 | MyISAM 表總索引 25% 內存,純 InnoDB 可設極小 |
| query_cache_size | 查詢結果緩存 | 表變更即失效、高並發鎖爭用 | 5.7 建議關閉 (0),8.0 已移除 |
| innodb_buffer_pool_size | InnoDB 數據+索引緩存 | 核心性能決定因素、頁式管理 | 專用機 60-80% 物理內存,命中率 > 99% |
| innodb_log_buffer_size | Redo Log 緩存 | 配合 flush_log_at_trx_commit | 16M-64M,大事務增大 |
| innodb_additional_mem_pool_size | 字典/內部結構 | 5.7 移除,自動從 Buffer Pool 分配 | 忽略 |
innodb_flush_log_at_trx_commit = 0 | 1 | 2 -- 0: log_buffer --1s--> log_file --實時--> disk (延遲寫,高效能風險丟數據) -- 1: log_buffer --實時--> log_file --實時--> disk (最安全,效能最低) -- 2: log_buffer --實時--> log_file --1s--> disk (折中推薦,配合電池備電 RAID) sync_binlog = N (N>0) -- 每 N 次 Binlog 寫入觸發 fdatasync(),建議 500-1000
(Innodb_buffer_pool_read_requests - Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests * 100% -- 目標 > 99%,否則擴大 buffer_pool 或優化索引/查詢
innodb_buffer_pool_size 為剩餘 60-80%max_connections,按 2-4MB/連接預留線程私有內存tmp_table_size/max_heap_table_sizeVmRSS、Innodb_buffer_pool_pages_*、Threads_connected 動態調整