我們在生產環境中遇到一個嚴重的記憶體問題:主從庫均設定 innodb_buffer_pool = 80GB,主庫承載正常業務負載,而從庫僅運行複製線程,無其他查詢負載。然而隨著時間推移,從庫的記憶體佔用(RES)持續增長,數天後達到約 120GB,導致系統開始大量交換,最終觸發 Linux OOM Killer 殺死 MySQL 進程。
錯誤日誌顯示:
Out of memory: Kill process 43817 (mysqld) score 847 or sacrifice child Killed process 43817, UID 500, (mysqld) total-vm:126723628kB, anon-rss:125497616kB, file-rss:3388kB
同版本的 Percona Server 在主庫上運行正常,無此問題。此問題在近期多個版本中均存在,並非單一版本特有。
[mysqld] innodb_buffer_pool_size = 80G innodb_buffer_pool_instances = 8 innodb_page_size = 4K innodb_log_block_size = 4096 innodb_buffer_pool_dump_at_shutdown = 1 innodb_buffer_pool_load_at_startup = 1 innodb_use_sys_malloc = 0 innodb_flush_method = O_DIRECT max_connections = 2000 table_open_cache = 6144 table_definition_cache = 4096
從 SHOW ENGINE INNODB STATUS 輸出可見:
緩衝池實際分配記憶體(~107GB)顯著超過配置值(80GB),且隨時間持續增長。主從配置相同但僅從庫出現問題,提示可能與複製線程的內存管理、頁面清理或自適應哈希索引維護有關。建議關注 innodb_buffer_pool_instances 與 innodb_page_size=4K 的組合效應,以及複製 SQL 線程的內存分配模式。