Mysql

作業系統重啟後 MySQL 查詢速度會慢 10 到 100 倍

  • December 14, 2015

我有一個在 Ubuntu 上執行的 MySQL 伺服器。如果我重新啟動 MySQL,一切都很好。但是,如果我重新啟動作業系統,我的查詢將花費 10 倍到 100 倍的時間。我發現的問題的唯一“解決方案”是optimize在每張桌子上執行。之後一切都恢復正常。然而,在每次作業系統重啟後重建整個數據庫顯然是非常痛苦的,而且不是一個可行的長期解決方案。

我重新啟動作業系統

  1. 停止所有查詢數據庫的程序
  2. 等待查詢完成執行
  3. 跑步stop mysql
  4. 確保伺服器停止ps -C mysqlps -C mysqld
  5. 跑步reboot

如果我忽略作業系統重新啟動並再次啟動 MySQL,一切都很好。

附加資訊:

  • 錯誤日誌不包含任何指向問題的內容,我也沒有收到任何錯誤。一切都只是慢了一兩個數量級。
  • 所有表都受到影響。我正在使用 InnoDB,但在使用 MyISAM 時也存在同樣的問題。
  • 通常 MySQL 使用 80% 的 8GB RAM,但在作業系統重新啟動後僅使用大約 1GB。CPU 使用率從一個核心的 30-80% 下降到大約 1%。
  • 優化查詢正常使用了全部 80% 的 RAM,並且 CPU 也上升到正常值。

眼鏡:

  • MySQL 5.5.35-0ubuntu0.12.04.2
  • Ubuntu 12.04.4 LTS
  • 8GB RAM,4 個 CPU 核心

my.cnf文件:

[client]
port        = 3306
socket      = /var/run/mysqld/mysqld.sock

[mysqld_safe]
socket      = /var/run/mysqld/mysqld.sock
nice        = 0

[mysqld]

local-infile=0

user        = mysql
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
port        = 3306
basedir     = /usr
datadir     = /var/lib/mysql
tmpdir      = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking

innodb_file_per_table

innodb_autoinc_lock_mode = 0

innodb_thread_concurrency=8
innodb_buffer_pool_size=6G
innodb_log_file_size=1600M
innodb_additional_mem_pool_size=1M
innodb_log_buffer_size=4M
innodb_flush_log_at_trx_commit=0

innodb_read_io_threads=3000
innodb_write_io_threads=7000
innodb_io_capacity=10000

key_buffer_size     = 1024M
max_allowed_packet  = 16M
thread_stack        = 192K
thread_cache_size       = 8

myisam-recover         = BACKUP

query_cache_limit   = 1M
query_cache_size        = 16M

log_error = /var/log/mysql/error.log

expire_logs_days    = 10
max_binlog_size         = 100M

[mysqldump]
quick
quote-names
max_allowed_packet  = 16M

[mysql]


[isamchk]
key_buffer      = 16M

!includedir /etc/mysql/conf.d/

key_buffer_size 為 1GB,這與重新啟動後使用的 RAM 差不多。那可以連接嗎?

編輯:在記錄每個表的查詢執行時間時,我注意到在修復四個表中的三個後,有時三個修復表的查詢時間仍然很高。所以我不完全確定所有桌子都壞了。也許只是一張桌子拉低了整個伺服器的性能?但是,這與使用資源的低百分比並不匹配。

當您重新啟動作業系統時,您會刪除之前放入作業系統磁碟記憶體 (RAM) 的所有磁碟讀取。重新啟動後,作業系統將不得不從磁碟讀取 MySQL 數據,這比從記憶體 (RAM) 讀取要慢幾個數量級。

優化“修復”了這個問題,因為它導致 MySQL 從磁碟讀取所有表數據,從而使作業系統能夠記憶體數據。

Linux 使用大多數空閒 RAM 作為磁碟記憶體。您可以使用以下free命令查看:

[oracle@ora12c1 ~]$ free
            total       used       free     shared    buffers     cached
Mem:       4050844     840072    3210772          0      97268     349716
-/+ buffers/cache:     393088    3657756
Swap:      4063228          0    4063228
[oracle@ora12c1 ~]$ 

重新啟動 MySQL 對此記憶體沒有影響,因為記憶體數據的是作業系統,而不是 MySQL。

要“解決”您的問題,您必須強制作業系統從磁碟讀取數據,以便將其記憶體。您可以使用 Unixdd工具來執行此操作。例如:

dd if=/var/mysql/data/mytable.idb of=/dev/null

vmtouch提示:您可以使用該命令驗證磁碟記憶體中有多少給定文件。該命令還可以將文件從文件系統記憶體中清除,或強制將文件載入到文件系統記憶體中。請參閱http://hoytech.com/vmtouch/

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