Mysql

我可以減少 MySQL 記憶體使用量,還是需要添加更多 RAM?

  • February 16, 2015

我有一個 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_packetopen_files_limittable_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_readsInnodb_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每秒為零。

您可以使緩衝池更小,然後一些讀取將來自磁碟,而不是來自記憶體。

引用自:https://dba.stackexchange.com/questions/92074