我可以減少 MySQL 記憶體使用量,還是需要添加更多 RAM?
我有一個 2.25GB 記憶體的 VPS。MySQL 目前使用 1.4GB,我的站點上只有四個使用者。即使沒有使用者線上,它似乎也會使用這個數量。我的伺服器的可用記憶體經常低於 100MB,這令人不安。
昨天 MySQL 一直因 OOM 錯誤而崩潰並導致數據庫損壞,所以這才是真正促使我研究這個問題的原因。
我正在使用 Percona 配置嚮導生成的以下配置(稍作修改):
# Generated by Percona Configuration Wizard (http://tools.percona.com/) version REL5_20120208 # MODIFIED SLIGHTLY [mysql] # CLIENT # port = 3306 socket = "/var/lib/mysql/mysql.sock" [mysqld] slow-query-log=1 long-query-time=1 # GENERAL # user = mysql default_storage_engine = InnoDB socket = "/var/lib/mysql/mysql.sock" pid_file = "/var/lib/mysql/mysql.pid" # MyISAM # key_buffer_size = 32M myisam_recover = FORCE,BACKUP # SAFETY # max_allowed_packet = 256M # Percona said 16M, but I need it larger to avoid errors max_connect_errors = 1000000 # DATA STORAGE # datadir = "/var/lib/mysql/" ######### removed the following because the logs were taking up TONS Of space: # BINARY LOGGING # #log_bin = /var/lib/mysql/mysql_bin #expire_logs_days = 14 #sync_binlog = 1 # CACHES AND LIMITS # tmp_table_size = 32M max_heap_table_size = 32M query_cache_type = 0 # was previously 1 query_cache_size = 0 # was previously 32M max_connections = 500 thread_cache_size = 50 open_files_limit = 65535 # was previously 4822 table_definition_cache = 1024 table_open_cache = 2048 # was previously 1024 # INNODB # innodb_flush_method = O_DIRECT innodb_log_files_in_group = 2 innodb_log_file_size = 128M innodb_flush_log_at_trx_commit = 1 innodb_file_per_table = 1 innodb_buffer_pool_size = 1456M # LOGGING # log_error = "/var/lib/mysql/mysql_error.log" log_queries_not_using_indexes = 1
如您所見,我增加了
max_allowed_packet
、open_files_limit
和table_open_cache
。我進行更改是因為我收到了錯誤(我現在完全忘記了導致它們的原因)並且進行這些更改導致錯誤消失。此外,我注意到該
innodb_buffer_pool_size
設置接近 MySQL 使用的 RAM 量(這可能只是巧合),但正如這個答案所暗示的那樣,我執行了以下命令:SELECT CEILING(Total_InnoDB_Bytes*1.6/POWER(1024,3)) RIBPS FROM (SELECT SUM(data_length+index_length) Total_InnoDB_Bytes FROM information_schema.tables WHERE engine='InnoDB') A;
輸出是
2
,我相信這意味著推薦innodb_buffer_pool_size
的是 2GB。如果這是正確的,那麼我目前的設置甚至低於推薦的數量。我真的不知道自己在做什麼,也不想盲目地更改
my.cnf
. 我可以做一些改變來減少記憶體使用,還是我只需要升級我的 VPS 計劃?
嚴格來說,上面推薦的緩衝池大小的計算是不正確的。它假設 InnoDB 積極地處理所有數據。實際上,InnoDB 只能觸及數據庫的一小部分。
檢查如何
Innodb_buffer_pool_reads
隨Innodb_buffer_pool_read_requests
時間變化。mysqladmin -r -i 1 ext | grep -e Innodb_buffer_pool_read_requests -e Innodb_buffer_pool_reads
如果
Innodb_buffer_pool_reads
沒有太大變化,那麼所有工作集(數據庫的一部分 InnoDB 積極使用)都適合緩衝池。理想情況下,緩衝池應該大到
Innodb_buffer_pool_reads
每秒為零。您可以使緩衝池更小,然後一些讀取將來自磁碟,而不是來自記憶體。