操作系统重启后,MySQL 查询速度慢 10 到 100 倍

Max*_*Max 5 mysql performance optimization ubuntu query-performance

我有一个在 Ubuntu 上运行的 MySQL 服务器。如果我重新启动 MySQL,一切都很好。但是,如果我重新启动操作系统,我的查询时间会增加 10 到 100 倍。我发现的问题的唯一“解决方案”是optimize在每张桌子上运行。之后一切又恢复正常。然而,在每次操作系统重启后重建整个数据库显然是极其痛苦的,而且不是一个可行的长期解决方案。

我通过以下方式重新启动操作系统

  1. 停止所有查询数据库的程序
  2. 等待查询完成执行
  3. 跑步 stop mysql
  4. 确保服务器停止ps -C mysqlps -C mysqld
  5. 跑步 reboot

如果我不重启操作系统并再次启动 MySQL,一切都很好。

附加信息:

  • 错误日志不包含任何指向问题的内容,我也没有收到任何错误。一切都只是慢了一两个数量级。
  • 所有表都受到影响。我正在使用 InnoDB,但在使用 MyISAM 时也存在同样的问题。
  • 通常 MySQL 使用 8GB RAM 的 80%,但在操作系统重新启动后仅使用大约 1GB。CPU 使用率从一个内核的 30-80% 下降到大约 1%。
  • 优化查询可以正常使用完整的 80% RAM,CPU 也会上升到正常值。

眼镜:

  • MySQL 5.5.35-0ubuntu0.12.04.2
  • Ubuntu 12.04.4 LTS
  • 8GB 内存,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/
Run Code Online (Sandbox Code Playgroud)

key_buffer_size 为 1GB,这与重启后使用的 RAM 差不多。那可以连接吗?

编辑:在记录每个表的查询执行次数时,我注意到在修复了四个表中的三个之后,有时三个修复表的查询次数仍然很高。所以我不完全确定所有的桌子都坏了。也许只是一张桌子拉低了整个服务器的性能?然而,这与使用资源的低百分比并不真正匹配。

Phi*_*lᵀᴹ 6

当您重新启动操作系统时,您将删除之前放入操作系统磁盘缓存 (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 ~]$ 
Run Code Online (Sandbox Code Playgroud)

重新启动 MySQL 对该缓存没有影响,因为缓存数据的是操作系统,而不是 MySQL。

要“修复”您的问题,您必须强制操作系统从磁盘读取数据,以便缓存它。您可以使用 Unixdd工具来执行此操作。例如:

dd if=/var/mysql/data/mytable.idb of=/dev/null
Run Code Online (Sandbox Code Playgroud)

提示:您可以使用该vmtouch命令验证给定文件在磁盘缓存中的数量。该命令还可以将文件从文件系统缓存中清除,或强制将文件加载到文件系统缓存中。请参阅http://hoytech.com/vmtouch/