作業系統重啟後 MySQL 查詢速度會慢 10 到 100 倍
我有一個在 Ubuntu 上執行的 MySQL 伺服器。如果我重新啟動 MySQL,一切都很好。但是,如果我重新啟動作業系統,我的查詢將花費 10 倍到 100 倍的時間。我發現的問題的唯一“解決方案”是
optimize
在每張桌子上執行。之後一切都恢復正常。然而,在每次作業系統重啟後重建整個數據庫顯然是非常痛苦的,而且不是一個可行的長期解決方案。我重新啟動作業系統
- 停止所有查詢數據庫的程序
- 等待查詢完成執行
- 跑步
stop mysql
- 確保伺服器停止
ps -C mysql
並ps -C mysqld
- 跑步
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。
要“解決”您的問題,您必須強制作業系統從磁碟讀取數據,以便將其記憶體。您可以使用 Unix
dd
工具來執行此操作。例如:dd if=/var/mysql/data/mytable.idb of=/dev/null
vmtouch
提示:您可以使用該命令驗證磁碟記憶體中有多少給定文件。該命令還可以將文件從文件系統記憶體中清除,或強制將文件載入到文件系統記憶體中。請參閱http://hoytech.com/vmtouch/