2017-08-05 91 views
2

我有MySQL 5.6.36數據庫,其中大小爲35G,在CentOS 7.3上運行,內存爲48G。爲什麼MySQL消耗這麼多內存?

[UPDATE 17-08-06]我會更新相關信息here

我看到我的服務器內存不足,即使使用大約48G的RAM也會崩潰。例如,我無法讓它在24G上運行。這個大小的DB應該能夠運行得更少。顯然,我缺少一些根本性的東西。

[UPDATE:17-08-05]死機,我的意思是mysqld的停止並重新啓動與日誌中沒有有用的信息,比從崩潰重啓等。而且,這一切的記憶,我在恢復過程中得到這個錯誤:

[ERROR] InnoDB: space header page consists of zero bytes in tablespace ./ca_uim/t_qos_snapshot.ibd (table ca_uim/t_qos_snapshot) 

我的配置文件中的相關部分看起來像這樣[EDITED 17-08-05添加缺少的行]:

[mysqld] 
datadir=/var/lib/mysql 
socket=/var/lib/mysql/mysql.sock 
lower_case_table_names = 1 
symbolic-links=0 
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 
max_allowed_packet = 32M 
max_connections = 300 
table_definition_cache=2000 
innodb_buffer_pool_size = 18G 
innodb_buffer_pool_instances = 9 
innodb_log_file_size = 1G 
innodb_file_per_table=1 

[mysqld_safe] 
log-error=/var/log/mysqld.log 
pid-file=/var/run/mysqld/mysqld.pid 

這是一個忽略每個表使用文件,我需要改變(我有6000個表,其中大部分是分區)。

一會兒(一小時)運行後,mytop表明這一點:

MySQL on 10.238.40.209 (5.6.36) load 0.95 1.08 1.01 1/1003 8525 up 0+01:31:01 [17:44:39] 
Queries: 1.5M  qps: 283 Slow: 22.0   Se/In/Up/De(%): 50/07/09/01 
Sorts:  27 qps now: 706 Slow qps: 0.0 Threads: 118 ( 3/ 2) 43/28/01/00 
Key Efficiency: 100.0% Bps in/out: 76.7k/176.8k Now in/out: 144.3k/292.1k 

而且免費演出這樣的:

# free -h 
       total  used  free  shared buff/cache available 
Mem:   47G   40G  1.5G  8.1M  5.1G  6.1G 
Swap:   3.9G  508K  3.9G 

頂部顯示這一點:

PID USER  PR NI VIRT RES SHR S %CPU %MEM  TIME+ COMMAND                
2010 mysql  20 0 45.624g 0.039t 9008 S 95.0 84.4 62:31.93 mysqld                

如何這可以嗎?這是每個表的相關文件嗎?整個DB可以放在內存中。我究竟做錯了什麼?

+0

如果您使用'join',那麼結果可能是表格大小的許多倍。可能有其他進程使用內存。服務器崩潰時正在運行什麼查詢?當你說'崩潰'時,它是否會停止響應任何應用程序,或只有MySQL?最後,可以肯定的是,你每秒有283個查詢? –

+0

使用http://mysqltuner.pl驗證你的內存配置 – Geoffrey

+1

'mysql> show processlist;'將有助於辨別SO或[SF]。 – Sal

回答

0

嗯,我解決了這個問題。我很欣賞那些迴應者的所有見解。解決方案非常奇怪,我無法解釋爲什麼這能解決問題,但它確實如此。我所做的是將以下行添加到我的。CNF:

log_bin 

您可能,此外,需要增加以下內容:

expire_logs_days = <some number> 

我們已經看到至少一個實例,其中日誌積累和裝滿了的磁盤。默認值是0(不自動刪除)。 https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_expire_logs_days

0

結果從內存中存儲和饋送,並且假設您每秒運行283次,那麼在任何給定的時刻都可能有大量數據被拋出。

我認爲你正在做一個很好的工作,擠出很多的服務器。考慮一下表格是一回事,然後是涉及6000個表格的模式,再加上你每秒鐘對35 GB數據庫抽取283個查詢的事實,並且這些結果在服務時保存在內存中。我們其他人不妨向你學習。

關於MySQL的

的停止和重新啓動
[ERROR] InnoDB: space header page consists of zero bytes in tablespace ./ca_uim/t_qos_snapshot.ibd (table ca_uim/t_qos_snapshot) 

你可能會考慮嘗試這是推薦herehere,但我不能保證它會工作 innodb_flush_method=normal

0

使用www.mysqlcalculator.com將是一個快速的方法,在不到2分鐘的時間內對大約十幾個內存消耗因素進行大腦檢查。

118個活動線程可能是合理的,但似乎會導致嘗試同時回答118個問題的極端上下文切換。

很想看到您的SHOW GLOBAL STATUS和SHOW GLOBAL VARIABLES,如果您可以讓他們發佈。

+0

我將配置更改爲我需要運行該應用程序的絕對最小更改。它像狗一樣運行,mysql最終會耗盡內存。你可以在這裏看到這些信息:https://github.com/julio-garcia-fc/mysql-problems/tree/master/small-config –

0

請在您平時的配置中啓用MySQL錯誤日誌。 當MySQL崩潰時,請在重新啓動之前保護錯誤日誌,並添加可用於您的問題的最後一個錯誤日誌。它應該有一個線索爲什麼MySQL失敗。 當支持SHOW GLOBAL STATUS報告的活動量時,運行「小」配置將像狗一樣運行。 請回到你平常的生產配置。 我正在查看您提供的詳細信息,並在接下來的24小時內提供一些調整建議。看來大多數進程列表活動都與複製有關。這是真的嗎?

1

希望您一次只能進行一次更改,因此您可以跟蹤配置原因的進度。 2017-08-07 17:00左右SHOW GLOBAL VARIABLES表示innodb_buffer_pool_size是128M。請將my.cnf更改爲24G,並在允許的情況下關機/重新啓動。 A)1G的max_allowed_pa​​cket_size很可能是您在配置中的含義,考慮到2017年7月8日您的遠程代理正在發送1G數據包以便在此設備上處理。遠程代理如何在調度發送數據方面進行管理,以防止這臺主機上的所有48G耗盡這一次使用的內存?狀態表示2017年8月6日的bytes_received爲885,485,832,其正常運行時間的前1520秒內來自max_used_connections爲86。
B)innodb_io_capacity at 200很可能會對您可能的IOPS造成嚴重影響,我們在此處運行700.我們使用sqlio.exe實用程序來引導我們朝這個方向發展。 C)innodb_io_capacity_max應該也可能被調整。 D)thread_cache_size 11,考慮去128. E)thread_concurrency 10,考慮去做30.
F)我明白process-list.txt的長度在Sleep ID中的數量可能是由於使用持續連接。連接只是在延長的時間內等待客戶端的一些額外活動。 G)狀態Com_begin計數通常非常接近Com_commit計數,而不是您的情況。 8/8/2017 Com_begin爲2,Com_commit爲709,910,正常運行時間爲11小時。 H)如果可能的話,只看3分鐘的綜合日誌可能會有所幫助。 讓我發佈你的進度。

+0

謝謝!我無法解釋max_allowed_pa​​cket_size。它在my.cnf中明確設置爲32M。很奇怪。在11小時後,我使用最新信息在https://github.com/julio-garcia-fc/mysql-problems/tree/master/small-config更新了信息。增加了mysqld.log。這是無用的,因爲我應該增加日誌級別。我會解決這個問題並瞭解你提到的其他設置。我想改變一件事,但在這一點上,我不確定要改變什麼,除此之外還有增加交換空間或在該虛擬機上投入更多內存的問題。 –

1

我會檢查table_open_cache。你有很多的表格,它清楚地反映在每秒平均打開的文件中:當正常值在1和5之間時,大約爲48. 這由Table_open_cache_missesTable_open_cache_overflows, 的值確定,理想情況下這些值應該是cero。這意味着嘗試使用緩存失敗並導致內存浪費。 您應該嘗試將其至少增加到3000並查看結果。

由於你在CentOS:

  1. 我會仔細檢查ulimit是無限或約20000爲您的6000個表。
  2. 考慮將swappiness設置爲1.我認爲最好有一些swapp(同時觀察)而不是崩潰。
相關問題