#### 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 使用固定大小的行。固定大小的行会占用一些额外的空间，但对损坏的容忍度要高得多。

    当前的动态行代码已经使用了几年，几乎没有问题，但动态长度行本质上更容易出错，因此尝试这种策略看看它是否有帮助可能是个好主意。

-   诊断问题时考虑硬件故障的可能性。有缺陷的硬件可能是数据损坏的原因。在对硬件进行故障排除时，请特别注意您的内存和磁盘子系统。
