在发布有关问题的错误报告之前,请尝试验证它是否是一个错误,以及是否已经有人报告过该错误。
首先在 https://dev.mysqlserver.cn/doc/ 搜索 MySQL 在线手册。我们会通过频繁更新手册来解决新发现的问题,以保持手册的最新状态。此外,手册附带的发行说明可能特别有用,因为新版本很可能包含您的问题的解决方案。您可以在手册的相同位置找到发行说明。
如果您收到 SQL 语句的解析错误,请仔细检查您的语法。如果您找不到任何错误,则极有可能您当前版本的 MySQL 服务器不支持您正在使用的语法。如果您正在使用当前版本,并且手册中未涵盖您正在使用的语法,则 MySQL 服务器不支持您的语句。
如果手册涵盖了您正在使用的语法,但是您使用的是较旧版本的 MySQL 服务器,则应查看 MySQL 更改历史记录,以了解该语法何时实现。在这种情况下,您可以选择升级到较新版本的 MySQL 服务器。
有关一些常见问题的解决方案,请参阅第 B.3 节,“问题和常见错误”。
在 http://bugs.mysql.com/ 搜索错误数据库,以查看该错误是否已报告并修复。
您还可以使用 https://www.mysqlserver.cn/search/ 搜索位于 MySQL 网站上的所有网页(包括手册)。
如果您在手册、错误数据库或邮件列表存档中找不到答案,请咨询您当地的 MySQL 专家。如果您仍然找不到问题的答案,请使用以下准则报告错误。
报告错误的通常方法是访问 http://bugs.mysql.com/,这是我们错误数据库的地址。该数据库是公开的,任何人都可以浏览和搜索。如果您登录到系统,则可以输入新报告。
在 http://bugs.mysql.com/ 的错误数据库中发布的错误,如果在给定版本中已得到纠正,则会在发行说明中注明。
如果您在 MySQL 服务器中发现安全漏洞,请立即发送电子邮件至 <[email protected]>
通知我们。例外:支持客户应通过 http://support.oracle.com/ 向 Oracle 支持部门报告所有问题,包括安全漏洞。
要与其他用户讨论问题,可以使用 MySQL 社区 Slack。
撰写一份良好的错误报告需要耐心,但第一次就把它做好可以为我们和您自己节省时间。一份包含完整的错误测试用例的良好错误报告,可以使我们很有可能在下一次发布的版本中修复该错误。本节将帮助您正确撰写报告,以便您不会浪费时间做一些对我们帮助不大或根本没有帮助的事情。请仔细阅读本节,并确保您的报告中包含此处描述的所有信息。
最好在发布之前使用最新版本或开发版本的 MySQL 服务器测试该问题。任何人都应该能够通过在您的测试用例上使用 mysql test < script_file
或运行您在错误报告中包含的 shell 或 Perl 脚本来重现该错误。我们能够重现的任何错误都很有可能在下一次 MySQL 版本中得到修复。
在错误报告中包含对问题的良好描述是最有帮助的。也就是说,请提供您为解决问题所做的一切的良好示例,并详细描述问题本身。最好的报告是那些包含完整示例,说明如何重现错误或问题的报告。请参阅第 7.9 节,“调试 MySQL”。
请记住,我们有可能对包含过多信息的报告做出回应,但对包含过少信息的报告则不能。人们常常忽略一些事实,因为他们认为自己知道问题的根源,并认为某些细节无关紧要。一个要遵循的好原则就是,如果您对是否要陈述某件事有疑问,那就陈述出来。在报告中多写几行文字要比在我们必须要求您提供初始报告中遗漏的信息时等待更长时间的答案更快、更省事。
错误报告中最常见的错误是:(a) 未包含您使用的 MySQL 发行版的版本号,以及 (b) 未完整描述安装 MySQL 服务器的平台(包括平台类型和版本号)。这些都是高度相关的信息,在 100 个案例中,有 99 个案例在没有这些信息的情况下,错误报告是无用的。我们经常会收到这样的问题:“为什么这对我不起作用?” 然后我们发现,请求的功能在该 MySQL 版本中没有实现,或者报告中描述的错误已在新版本的 MySQL 中修复。错误通常与平台有关。在这种情况下,如果不知道操作系统和平台的版本号,我们几乎不可能修复任何东西。
如果您从源代码编译 MySQL,请记住还要提供有关编译器的信息(如果与问题相关)。人们经常在编译器中发现错误,并认为问题与 MySQL 相关。大多数编译器始终处于开发状态,并且版本越来越好。为了确定您的问题是否取决于您的编译器,我们需要知道您使用了什么编译器。请注意,每个编译问题都应视为错误并进行相应报告。
如果程序产生错误消息,则务必在报告中包含该消息。如果我们尝试从存档中搜索某些内容,则最好使报告的错误消息与程序产生的错误消息完全匹配。(即使是大写字母也应注意。)最好将整个错误消息复制并粘贴到您的报告中。您永远不要试图凭记忆重现消息。
如果您在使用 Connector/ODBC (MyODBC) 时遇到问题,请尝试生成跟踪文件并将其与您的报告一起发送。请参阅如何报告 Connector/ODBC 问题或错误。
如果您的报告包含使用 mysql 命令行工具运行的测试用例的长查询输出行,则可以使用 --vertical
选项或 \G
语句终止符使输出更具可读性。EXPLAIN SELECT
示例(在本节后面)演示了 \G
的用法。
请在您的报告中包含以下信息:
您正在使用的 MySQL 发行版的版本号(例如,MySQL 5.7.10)。您可以通过执行 mysqladmin version 找出您正在运行的版本。mysqladmin 程序可以在 MySQL 安装目录下的
bin
目录中找到。您遇到问题的机器的制造商和型号。
操作系统名称和版本。如果您使用的是 Windows,通常可以通过双击“我的电脑”图标并下拉““帮助/关于 Windows””菜单来获取名称和版本号。对于大多数类 Unix 操作系统,您可以通过执行命令
uname -a
获取此信息。有时,内存量(实际和虚拟)也很重要。如有疑问,请包含这些值。
MySQL 安装中
docs/INFO_BIN
文件的内容。该文件包含有关如何配置和编译 MySQL 的信息。如果您使用的是 MySQL 软件的源代码发行版,请包含您使用的编译器的名称和版本号。如果您使用的是二进制发行版,请包含发行版名称。
如果问题发生在编译期间,请包含确切的错误消息,以及错误发生的文件中出现错误的代码前后几行的上下文。
如果 mysqld 崩溃,您还应该报告导致 mysqld 意外退出的语句。您通常可以通过在启用查询日志记录的情况下运行 mysqld,然后在 mysqld 退出后查看日志来获取此信息。请参阅 第 7.9 节,“调试 MySQL”。
如果数据库表与问题相关,请在错误报告中包含
SHOW CREATE TABLE
语句的输出。这是获取数据库中任何表定义的一种非常简单的方法。这些信息可以帮助我们创建与您遇到的情况相匹配的情况。db_name
.tbl_name
发生问题时生效的 SQL 模式可能很重要,因此请报告
sql_mode
系统变量的值。对于存储过程、存储函数和触发器对象,相关的sql_mode
值是创建对象时生效的值。对于存储过程或函数,SHOW CREATE PROCEDURE
或SHOW CREATE FUNCTION
语句会显示相关的 SQL 模式,或者您可以查询INFORMATION_SCHEMA
获取信息。SELECT ROUTINE_SCHEMA, ROUTINE_NAME, SQL_MODE FROM INFORMATION_SCHEMA.ROUTINES;
对于触发器,您可以使用以下语句
SELECT EVENT_OBJECT_SCHEMA, EVENT_OBJECT_TABLE, TRIGGER_NAME, SQL_MODE FROM INFORMATION_SCHEMA.TRIGGERS;
对于与性能相关的错误或
SELECT
语句的问题,您应该始终包含EXPLAIN SELECT ...
的输出,以及SELECT
语句产生的行数。您还应该包含每个相关表的SHOW CREATE TABLE
的输出。您提供的信息越多,就越有可能得到帮助。tbl_name
以下是一个非常好的错误报告示例。这些语句是使用 mysql 命令行工具运行的。请注意,对于那些否则会产生难以阅读的长输出行的语句,使用了
\G
语句终止符。mysql> SHOW VARIABLES; mysql> SHOW COLUMNS FROM ...\G <output from SHOW COLUMNS> mysql> EXPLAIN SELECT ...\G <output from EXPLAIN> mysql> FLUSH STATUS; mysql> SELECT ...; <A short version of the output from SELECT, including the time taken to run the query> mysql> SHOW STATUS; <output from SHOW STATUS>
如果在运行 mysqld 时发生错误或问题,请尝试提供一个可以重现异常的输入脚本。此脚本应包含所有必要的源文件。脚本越能重现您的情况,就越好。如果您可以创建一个可重现的测试用例,您应该将其上传并附加到错误报告中。
如果您无法提供脚本,则至少应在报告中包含 mysqladmin variables extended-status processlist 的输出,以提供有关系统性能的一些信息。
如果您无法仅用几行数据生成测试用例,或者测试表太大而无法包含在错误报告中(超过 10 行),则应使用 mysqldump 转储您的表,并创建一个描述您问题的
README
文件。使用 tar 和 gzip 或 zip 创建文件的压缩存档。在您在我们的错误数据库 http://bugs.mysql.com/ 上提交错误报告后,请单击错误报告中的“文件”选项卡,以获取有关将存档上传到错误数据库的说明。如果您认为 MySQL 服务器从语句中生成了奇怪的结果,请不仅包含结果,还包含您对结果应该是什么的看法,以及对您看法依据的解释。
当您提供问题的示例时,最好使用实际情况中存在的表名、变量名等,而不是想出新的名称。问题可能与表名或变量名有关。这些情况可能很少见,但安全总比后悔好。毕竟,为您而言,提供一个使用实际情况的示例应该更容易,对我们而言也绝对更好。如果您有不想在错误报告中公开的数据,可以使用前面描述的“文件”选项卡上传。如果信息确实是绝密的,您甚至不想向我们展示,请继续使用其他名称提供示例,但请将此视为最后的选择。
如果可能,请包含提供给相关程序的所有选项。例如,指出您在启动 mysqld 服务器时使用的选项,以及您在运行任何 MySQL 客户端程序时使用的选项。提供给 mysqld 和 mysql 等程序以及 configure 脚本的选项通常是解决问题的关键,并且非常相关。包含它们绝不是坏事。如果您的问题涉及用 Perl 或 PHP 等语言编写的程序,请包含语言处理器版本号以及程序使用的任何模块版本号。例如,如果您有一个使用
DBI
和DBD::mysql
模块的 Perl 脚本,请包含 Perl、DBI
和DBD::mysql
的版本号。如果您的问题与权限系统有关,请包含 mysqladmin reload 的输出,以及您在尝试连接时收到的所有错误消息。当您测试您的权限时,您应该执行 mysqladmin reload version 并尝试使用给您带来麻烦的程序连接。
如果您有针对某个错误的补丁,请务必包含它。但不要认为补丁是我们需要的全部,或者我们可以使用它,如果您没有提供一些必要的信息,例如显示您的补丁修复的错误的测试用例。我们可能会发现您的补丁有问题,或者我们可能根本不理解它。如果是这样,我们就无法使用它。
如果我们无法验证补丁的确切目的,我们将不会使用它。测试用例可以帮助我们。证明补丁可以处理所有可能出现的情况。如果我们发现一个边界情况(即使是罕见的情况),补丁将无法工作,它可能是无用的。
关于错误是什么、错误为何发生或错误依赖于什么的猜测通常是错误的。即使是 MySQL 团队,在不首先使用调试器确定错误的真正原因的情况下,也无法猜测出这些东西。
在您的错误报告中说明您已经查阅了参考手册和邮件存档,以便其他人知道您已经尝试过自行解决问题。
如果您的数据看起来已损坏,或者您在访问特定表时遇到错误,请首先使用
CHECK TABLE
检查您的表。如果该语句报告了任何错误InnoDB
崩溃恢复机制会在服务器被杀死后重启时处理清理工作,因此在典型操作中,无需“修复”表。如果您在使用InnoDB
表时遇到错误,请重启服务器,看看问题是否仍然存在,或者错误是否只影响了内存中的缓存数据。如果磁盘上的数据已损坏,请考虑在启用innodb_force_recovery
选项的情况下重启,以便您可以转储受影响的表。对于非事务性表,请尝试使用
REPAIR TABLE
或 myisamchk 修复它们。请参阅 第 7 章,*MySQL 服务器管理*。
如果您运行的是 Windows,请使用
SHOW VARIABLES LIKE 'lower_case_table_names'
语句验证lower_case_table_names
的值。此变量会影响服务器如何处理数据库名和表名的字母大小写。其对于给定值的效果应该如 第 11.2.3 节,“标识符大小写敏感性” 中所述。如果您经常遇到表损坏的情况,您应该尝试找出这种情况发生的时间和原因。在这种情况下,MySQL 数据目录中的错误日志可能包含有关发生情况的一些信息。(这是名称中带有
.err
后缀的文件。)请参阅 第 7.4.2 节,“错误日志”。请在您的错误报告中包含此文件中任何相关的信息。通常情况下,如果没有任何东西在更新过程中杀死 mysqld,它永远不会损坏表。如果您能找到 mysqld 崩溃的原因,我们就能更容易地为您提供解决问题的方案。请参阅 第 B.3.1 节,“如何确定是什么导致了问题”。如果可能,请下载并安装最新版本的 MySQL 服务器,并检查它是否解决了您的问题。所有版本的 MySQL 软件都经过了彻底的测试,应该可以正常工作。我们相信尽可能地向后兼容,您应该能够毫无困难地切换 MySQL 版本。请参阅 第 2.1.2 节,“要安装哪个 MySQL 版本和发行版”。