#### B.3.3.3 如果 MySQL 不断崩溃怎么办 [](<>) 每个 MySQL 版本在发布之前都在许多平台上进行了测试。这并不意味着 MySQL 中没有 bug,但如果有 bug,它们应该很少并且很难找到。如果您遇到问题,尝试找出系统崩溃的确切原因总是有帮助的,因为您有更好的机会快速解决问题。 首先,您应该尝试找出问题是否在于[**mysqld**](mysqld.html)服务器死了,或者您的问题是否与您的客户端有关。您可以查看您的[**mysqld**](mysqld.html)服务器已通过执行启动[**mysql管理员版本**](mysqladmin.html).如果[**mysqld**](mysqld.html)死机重启了,你可以通过查看服务器的错误日志找到原因。看[第 5.4.2 节,“错误日志”](error-log.html). 在某些系统上,您可以在错误日志中找到堆栈跟踪位置[**mysqld**](mysqld.html)死了。请注意,写入错误日志的变量值可能并不总是 100% 正确。 许多意外的服务器退出是由损坏的数据文件或索引文件引起的。MySQL 使用以下命令更新磁盘上的文件`写()`在每个 SQL 语句之后和客户端收到结果通知之前的系统调用。(如果您使用[`delay_key_write`](server-system-variables.html#sysvar_delay_key_write)启用系统变量,在这种情况下写入数据文件而不写入索引文件。)这意味着数据文件内容是安全的,即使[**mysqld**](mysqld.html)崩溃,因为操作系统确保将未刷新的数据写入磁盘。您可以通过启动强制 MySQL 在每个 SQL 语句之后将所有内容刷新到磁盘[**mysqld**](mysqld.html)与[`--冲洗`](server-options.html#option_mysqld_flush)选项。 前面的意思是通常你不应该得到损坏的表,除非发生以下情况之一: - MySQL 服务器或服务器主机在更新过程中被杀死。 - 你发现了一个错误[**mysqld**](mysqld.html)这导致它在更新过程中死机。 - 一些外部程序正在同时操作数据文件或索引文件[**mysqld**](mysqld.html)没有正确锁定桌子。 - 你跑了很多[**mysqld**](mysqld.html)在不支持良好文件系统锁的系统上使用相同数据目录的服务器(通常由`锁定`锁管理器),或者您正在运行多个禁用外部锁定的服务器。 - 您有一个崩溃的数据文件或索引文件,其中包含非常损坏的数据[**mysqld**](mysqld.html). - 您在数据存储代码中发现了一个错误。这不太可能,但至少是可能的。在这种情况下,您可以尝试将存储引擎更改为另一个引擎,方法是使用[`更改表`](alter-table.html)在表的修复副本上。 因为很难知道为什么会崩溃,所以首先尝试检查对其他人有用的事情是否会导致您意外退出。尝试以下操作: - 停止[**mysqld**](mysqld.html)服务器与[**mysqladmin 关闭**](mysqladmin.html), 跑步[**myisamchk --silent --force\*/\*。我的我**](myisamchk.html)从数据目录检查所有`MyISAM`表,然后重新启动[**mysqld**](mysqld.html).这可确保您从干净的状态运行。看[第 5 章,*MySQL 服务器管理*](server-administration.html). - 开始[**mysqld**](mysqld.html)启用通用查询日志(请参阅[第 5.4.3 节,“一般查询日志”](query-log.html))。然后尝试从写入日志的信息中确定某些特定查询是否会杀死服务器。大约 95% 的错误与特定查询有关。通常,这是服务器重新启动之前日志文件中的最后一个查询之一。看[第 5.4.3 节,“一般查询日志”](query-log.html).如果你可以用一个特定的查询反复杀死 MySQL,即使你在发出它之前检查了所有表,那么你已经隔离了这个 bug,应该为它提交一个 bug 报告。看[第 1.6 节,“如何报告错误或问题”](bug-reports.html). - 尝试制作一个我们可以用来重复问题的测试用例。看[第 5.9 节,“调试 MySQL”](debugging-mysql.html). - 试试`fork_big.pl`脚本。(它位于`测试`源分发目录。) - 配置 MySQL 进行调试可以在出现问题时更轻松地收集有关可能错误的信息。重新配置 MySQL[`-DWITH_DEBUG=1`](source-configuration-options.html#option_cmake_with_debug)选项**制作**然后重新编译。看[第 5.9 节,“调试 MySQL”](debugging-mysql.html). - 确保您已为您的操作系统应用了最新的补丁。 - 使用[`--skip-external-locking`](server-options.html#option_mysqld_external-locking)选项[**mysqld**](mysqld.html).在某些系统上,`锁定`锁管理器无法正常工作;这[`--skip-external-locking`](server-options.html#option_mysqld_external-locking)选项告诉[**mysqld**](mysqld.html)不要使用外部锁定。(这意味着你不能运行两个[**mysqld**](mysqld.html)服务器在同一个数据目录中,如果你使用你必须小心[**迈萨姆奇克**](myisamchk.html).尽管如此,尝试该选项作为测试可能是有益的。) - 如果[**mysqld**](mysqld.html)似乎正在运行但没有响应,请尝试[**mysqladmin -u 根进程列表**](mysqladmin.html).有时[**mysqld**](mysqld.html)没有挂起,即使它似乎没有反应。问题可能是所有连接都在使用中,或者可能存在一些内部锁定问题。[**mysqladmin -u 根进程列表**](mysqladmin.html)即使在这些情况下,通常也能够建立连接,并且可以提供有关当前连接数及其状态的有用信息。 - 运行命令[**mysqladmin -i 5 状态**](mysqladmin.html)要么[**mysqladmin -i 5 -r 状态**](mysqladmin.html)在单独的窗口中运行其他查询时生成统计信息。 - 尝试以下操作: 1. 开始[**mysqld**](mysqld.html)从**数据库**(或其他调试器)。看[第 5.9 节,“调试 MySQL”](debugging-mysql.html). 2. 运行您的测试脚本。 3. 打印三个最低级别的回溯和局部变量。在**数据库**,您可以使用以下命令执行此操作[**mysqld**](mysqld.html)已经坠毁在里面**数据库**: ``` backtrace info local up info local up info local ``` 和**数据库**,您还可以检查哪些线程存在`信息线程`并切换到特定线程`线 *`ñ`*`, 在哪里*`ñ`*是线程 ID。 - 尝试使用 Perl 脚本模拟您的应用程序,以强制 MySQL 退出或行为不端。 - 发送正常的错误报告。看[第 1.6 节,“如何报告错误或问题”](bug-reports.html).比平时更详细。因为 MySQL 适用于许多人,所以崩溃可能是由仅存在于您的计算机上的某些东西引起的(例如,与您的特定系统库相关的错误)。 - 如果您对包含动态长度行的表有疑问并且您只使用[`VARCHAR`](char.html)列(不是[`斑点`](blob.html)要么[`文本`](blob.html)列),您可以尝试更改所有[`VARCHAR`](char.html)到[`字符`](char.html)和[`更改表`](alter-table.html).这迫使 MySQL 使用固定大小的行。固定大小的行会占用一些额外的空间,但对损坏的容忍度要高得多。 当前的动态行代码已经使用了几年,几乎没有问题,但动态长度行本质上更容易出错,因此尝试这种策略看看它是否有帮助可能是个好主意。 - 诊断问题时考虑硬件故障的可能性。有缺陷的硬件可能是数据损坏的原因。在对硬件进行故障排除时,请特别注意您的内存和磁盘子系统。