# B.3.3.3 如果 MySQL 不断崩溃怎么办

每个 MySQL 版本在发布之前都在许多平台上进行了测试。这并不意味着 MySQL 中没有 bug,但如果有 bug,它们应该很少并且很难找到。如果您遇到问题,尝试找出系统崩溃的确切原因总是有帮助的,因为您有更好的机会快速解决问题。

首先,您应该尝试找出问题是否在于mysqld服务器死了,或者您的问题是否与您的客户端有关。您可以查看您的mysqld服务器已通过执行启动mysql管理员版本.如果mysqld死机重启了,你可以通过查看服务器的错误日志找到原因。看第 5.4.2 节,“错误日志”.

在某些系统上,您可以在错误日志中找到堆栈跟踪位置mysqld死了。请注意,写入错误日志的变量值可能并不总是 100% 正确。

许多意外的服务器退出是由损坏的数据文件或索引文件引起的。MySQL 使用以下命令更新磁盘上的文件写()在每个 SQL 语句之后和客户端收到结果通知之前的系统调用。(如果您使用delay_key_write启用系统变量,在这种情况下写入数据文件而不写入索引文件。)这意味着数据文件内容是安全的,即使mysqld崩溃,因为操作系统确保将未刷新的数据写入磁盘。您可以通过启动强制 MySQL 在每个 SQL 语句之后将所有内容刷新到磁盘mysqld--冲洗选项。

前面的意思是通常你不应该得到损坏的表,除非发生以下情况之一:

  • MySQL 服务器或服务器主机在更新过程中被杀死。

  • 你发现了一个错误mysqld这导致它在更新过程中死机。

  • 一些外部程序正在同时操作数据文件或索引文件mysqld没有正确锁定桌子。

  • 你跑了很多mysqld在不支持良好文件系统锁的系统上使用相同数据目录的服务器(通常由锁定锁管理器),或者您正在运行多个禁用外部锁定的服务器。

  • 您有一个崩溃的数据文件或索引文件,其中包含非常损坏的数据mysqld.

  • 您在数据存储代码中发现了一个错误。这不太可能,但至少是可能的。在这种情况下,您可以尝试将存储引擎更改为另一个引擎,方法是使用更改表在表的修复副本上。

    因为很难知道为什么会崩溃,所以首先尝试检查对其他人有用的事情是否会导致您意外退出。尝试以下操作:

  • 停止mysqld服务器与mysqladmin 关闭, 跑步myisamchk --silent --force*/*。我的我从数据目录检查所有MyISAM表,然后重新启动mysqld.这可确保您从干净的状态运行。看第 5 章,MySQL 服务器管理.

  • 开始mysqld启用通用查询日志(请参阅第 5.4.3 节,“一般查询日志”)。然后尝试从写入日志的信息中确定某些特定查询是否会杀死服务器。大约 95% 的错误与特定查询有关。通常,这是服务器重新启动之前日志文件中的最后一个查询之一。看第 5.4.3 节,“一般查询日志”.如果你可以用一个特定的查询反复杀死 MySQL,即使你在发出它之前检查了所有表,那么你已经隔离了这个 bug,应该为它提交一个 bug 报告。看第 1.6 节,“如何报告错误或问题”.

  • 尝试制作一个我们可以用来重复问题的测试用例。看第 5.9 节,“调试 MySQL”.

  • 试试fork_big.pl脚本。(它位于测试源分发目录。)

  • 配置 MySQL 进行调试可以在出现问题时更轻松地收集有关可能错误的信息。重新配置 MySQL-DWITH_DEBUG=1选项制作然后重新编译。看第 5.9 节,“调试 MySQL”.

  • 确保您已为您的操作系统应用了最新的补丁。

  • 使用--skip-external-locking选项mysqld.在某些系统上,锁定锁管理器无法正常工作;这--skip-external-locking选项告诉mysqld不要使用外部锁定。(这意味着你不能运行两个mysqld服务器在同一个数据目录中,如果你使用你必须小心迈萨姆奇克.尽管如此,尝试该选项作为测试可能是有益的。)

  • 如果mysqld似乎正在运行但没有响应,请尝试mysqladmin -u 根进程列表.有时mysqld没有挂起,即使它似乎没有反应。问题可能是所有连接都在使用中,或者可能存在一些内部锁定问题。mysqladmin -u 根进程列表即使在这些情况下,通常也能够建立连接,并且可以提供有关当前连接数及其状态的有用信息。

  • 运行命令mysqladmin -i 5 状态要么mysqladmin -i 5 -r 状态在单独的窗口中运行其他查询时生成统计信息。

  • 尝试以下操作:

    1. 开始mysqld数据库(或其他调试器)。看第 5.9 节,“调试 MySQL”.

    2. 运行您的测试脚本。

    3. 打印三个最低级别的回溯和局部变量。在数据库,您可以使用以下命令执行此操作mysqld已经坠毁在里面数据库

      backtrace
      info local
      up
      info local
      up
      info local
      

      数据库,您还可以检查哪些线程存在信息线程并切换到特定线程线 *ñ*, 在哪里*ñ*是线程 ID。

  • 尝试使用 Perl 脚本模拟您的应用程序,以强制 MySQL 退出或行为不端。

  • 发送正常的错误报告。看第 1.6 节,“如何报告错误或问题”.比平时更详细。因为 MySQL 适用于许多人,所以崩溃可能是由仅存在于您的计算机上的某些东西引起的(例如,与您的特定系统库相关的错误)。

  • 如果您对包含动态长度行的表有疑问并且您只使用VARCHAR列(不是斑点要么文本列),您可以尝试更改所有VARCHAR字符更改表.这迫使 MySQL 使用固定大小的行。固定大小的行会占用一些额外的空间,但对损坏的容忍度要高得多。

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

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