MySQL在重负载下慢/下

MySQL服务器一直在运行apache / php的专用服务器上崩溃。 我不是MySQL PRO,所以我需要一些专家build议。

Innodb和MyISAM引擎都在网站上使用,但是Innodb使用频率很高。

从WHM phpmyadmin我发现以下红色选项

Innodb_buffer_pool_pages_dirty 18 Innodb_buffer_pool_reads 31 k Handler_read_rnd 128 k Handler_read_rnd_next 3,013 k Created_tmp_disk_tables 1,534 Sort_merge_passes 10 Opened_tables 807 Table_locks_waited 8 

这里是MySQLconfiguration

 max_connections = 500 safe-show-database skip-locking key_buffer = 700M max_allowed_packet = 32M table_cache = 512 sort_buffer_size = 64M read_buffer_size = 2M read_rnd_buffer_size = 2M myisam_sort_buffer_size = 128M thread_cache_size = 16 query_cache_size= 512M query_cache_limit=1024M thread_concurrency = 8 connect_timeout = 8 wait_timeout = 120 interactive_timeout = 15 wait_timeout = 500 innodb_buffer_pool_size=1024M open_files_limit = 8192 tmp_table_size = 64M long_query_time = 1 log_slow_queries innodb_autoinc_lock_mode = 2 set-variable = innodb_lock_wait_timeout=10 [mysqldump] quick max_allowed_packet = 16M [mysql] no-auto-rehash [isamchk] key_buffer = 128M sort_buffer_size = 128M read_buffer = 2M write_buffer = 2M [myisamchk] key_buffer = 128M sort_buffer_size = 128M read_buffer = 2M write_buffer = 2M 

错误日志

 100930 9:44:12 [Warning] /usr/sbin/mysqld: Forcing close of thread 283 user: 'rdf' 100930 9:44:19 [ERROR] /usr/sbin/mysqld: Sort aborted 100930 9:44:19 [ERROR] /usr/sbin/mysqld: Sort aborted 100930 9:44:21 [ERROR] /usr/sbin/mysqld: Sort aborted 100930 9:44:53 [Warning] /usr/sbin/mysqld: Option '--set-variable' is deprecated. Use --variable-name=value instead. 100930 10:37:16 [ERROR] Cannot find or open table XXXX from the internal data dictionary of InnoDB though the .frm file for the table exists. Maybe you have deleted and recreated InnoDB data files but have forgotten to delete the corresponding .frm files of InnoDB tables, or you have moved .frm files to another database? 

我看到很多错误无法find或打开表格。 我没有碰到MySQLconfiguration。

就我个人而言,我认为其中一些价值观是不合时宜的,但这不应该导致崩溃。

http://blog.mysqltuner.com/有一个脚本,可能会给你一些调整提示,但他们build议服务器运行48小时以上。

当你说崩溃,你的意思是mysqld终止,或没有响应? 是系统无响应或只是MySQL? 检查dmesg,/ var / log / messages,核心转储等。如果没有硬件问题,我们假设mysql正在locking。 你没有提到上述那些值的正常运行时间,也没有提及你正在使用的mysql的版本,但是,我们假定一个相对较短的正常运行时间。 在磁盘上创build的tmp表可能意味着您的临时表大小太小,或者您的查询无法在内存中caching。

我首先看到的是table_cache低于打开的表格。 这不一定是一个很大的问题,但会造成很多的stream失。 显示“open_tables”状态; 如果这个限制在你的table_cache上,你可能想要增加table_cache。

如果你有一个相对较新版本的mysql,/var/lib/mysql/hostname.err或/var/log/mysql/mysql.err可能包含一些额外的信息。 如果你可以在一个事件过程中执行一个'show processlist',或者你可能需要mysqladmin -u root -ppassword processlist> / var / tmp / pl(如果你的服务器需要重新启动,能够检查崩溃时发生了什么。 那么你的mysql slowquery日志呢? Longquery为1可能会产生大量额外的日志logging,但是,如果发现需要花费300+秒的查询,则需要花费4秒钟,则可能会指示挂起哪个表。

InnoDB并不能解决所有的问题。 不懂mysql的程序员会使用InnoDB,因为它使用行级locking和表级locking。 locking表的一小部分,你应该看到并发上升。 这个理论是有道理的,但是,你用InnoDB做的事情不像MyISAM那样工作。

 select count(*) from innodbtable where condition='asdf'; select count(*) from myisamtable where condition='asdf'; 

在第一种情况下,InnoDB将locking表并进行完整的扫描。 在第二种情况下,MyISAM不会locking表(如果条件包含在索引中,将从索引中回答)。

 select count(varname) from table where condition='asdf'; 

如果varname不是一个键,这将强制一个tablescan来确保varname不为空。 如果varname是一个键,它仍然检查所有的键值,看是否有空。

在涉及文本字段的表上进行select会自动创build一个磁盘临时表 – 您可能可以修改查询以避免这种情况。

如果你可以发布更多有关应用程序运行的信息,你的意思是崩溃,show variables / show status的输出,错误日志的内容等等,我确信有人在这里有更多的知识可能能够debugging它进一步。

我猜你重新启动服务器重启/ powercycle。 在/ var / lib / mysql目录下,应该有一些文件:

 ibdata1 ib_logfile0 ib_logfile1 

我会假设其中一个文件包含一些不良的数据。

您可以在[mysqld]节中使用innodb_force_recovery = 4重新启动mysql,以查看innodb文件是否能够被修复。 如果没有,加载你的一个hotcopies或最近转储。 您可能无法在没有任何魔法的情况下删除该表,但应该能够重命名该表并从备份中重新导入。