13.6.7.7 The MySQL Diagnostics AreaMySQL诊断领域

SQL statements produce diagnostic information that populates the diagnostics area. SQL语句生成填充诊断区域的诊断信息。Standard SQL has a diagnostics area stack, containing a diagnostics area for each nested execution context. 标准SQL有一个诊断区域堆栈,包含每个嵌套执行上下文的诊断区域。Standard SQL also supports GET STACKED DIAGNOSTICS syntax for referring to the second diagnostics area during condition handler execution.标准SQL还支持GET STACKED DIAGNOSTICS语法,用于在条件处理程序执行期间引用第二个诊断区域。

The following discussion describes the structure of the diagnostics area in MySQL, the information items recognized by MySQL, how statements clear and set the diagnostics area, and how diagnostics areas are pushed to and popped from the stack.下面的讨论描述了MySQL中诊断区域的结构、MySQL识别的信息项、语句如何清除和设置诊断区域,以及如何将诊断区域推送到堆栈中并从堆栈中弹出。

Diagnostics Area Structure诊断区域结构

The diagnostics area contains two kinds of information:诊断区域包含两种信息:

  • Statement information, such as the number of conditions that occurred or the affected-rows count.语句信息,例如发生的条件数或受影响的行数。

  • Condition information, such as the error code and message. 条件信息,例如错误代码和消息。If a statement raises multiple conditions, this part of the diagnostics area has a condition area for each one. 如果一条语句引发多个条件,则诊断区域的这一部分为每个条件都有一个条件区域。If a statement raises no conditions, this part of the diagnostics area is empty.如果语句没有引发任何条件,则诊断区域的这一部分为空。

For a statement that produces three conditions, the diagnostics area contains statement and condition information like this:对于产生三个条件的语句,诊断区域包含如下语句和条件信息:

Statement information:
  row count
  ... other statement information items ...
Condition area list:
  Condition area 1:
    error code for condition 1
    error message for condition 1
    ... other condition information items ...
  Condition area 2:
    error code for condition 2:
    error message for condition 2
    ... other condition information items ...
  Condition area 3:
    error code for condition 3
    error message for condition 3
    ... other condition information items ...
Diagnostics Area Information Items诊断区域信息项

The diagnostics area contains statement and condition information items. 诊断区域包含语句和条件信息项。Numeric items are integers. The character set for character items is UTF-8. 数字项是整数。字符项的字符集是UTF-8。No item can be NULL. 任何项都不能为NULLIf a statement or condition item is not set by a statement that populates the diagnostics area, its value is 0 or the empty string, depending on the item data type.如果语句或条件项不是由填充诊断区域的语句设置的,则其值为0或空字符串,具体取决于项数据类型。

The statement information part of the diagnostics area contains these items:诊断区域的语句信息部分包含以下项目:

  • NUMBER: An integer indicating the number of condition areas that have information.:一个整数,指示包含信息的条件区域的数量。

  • ROW_COUNT: An integer indicating the number of rows affected by the statement. :一个整数,指示受语句影响的行数。ROW_COUNT has the same value as the ROW_COUNT() function (see Section 12.16, “Information Functions”).ROW_COUNT的值与ROW_COUNT()函数的值相同(参见第12.16节,“信息函数”)。

The condition information part of the diagnostics area contains a condition area for each condition. 诊断区域的条件信息部分包含每个条件的条件区域。Condition areas are numbered from 1 to the value of the NUMBER statement condition item. 条件区域的编号范围从1到NUMBER语句条件项的值。If NUMBER is 0, there are no condition areas.如果NUMBER为0,则不存在条件区域。

Each condition area contains the items in the following list. 每个条件区域包含以下列表中的项目。All items are standard SQL except MYSQL_ERRNO, which is a MySQL extension. MYSQL_ERRNO是MYSQL的扩展外,所有项目都是标准SQL。The definitions apply for conditions generated other than by a signal (that is, by a SIGNAL or RESIGNAL statement). 这些定义适用于由信号(即,由SIGNALRESIGNAL语句)以外的其他方式生成的条件。For nonsignal conditions, MySQL populates only those condition items not described as always empty. 对于非信号条件,MySQL只填充那些没有被描述为总是空的条件项。The effects of signals on the condition area are described later.信号对条件区域的影响将在后面描述。

  • CLASS_ORIGIN: A string containing the class of the RETURNED_SQLSTATE value. :包含RETURNED_SQLSTATE值的类的字符串。If the RETURNED_SQLSTATE value begins with a class value defined in SQL standards document ISO 9075-2 (section 24.1, SQLSTATE), CLASS_ORIGIN is 'ISO 9075'. 如果RETURNED_SQLSTATE值以SQL标准文件ISO 9075-2(第24.1节,SQLSTATE)中定义的类值开头,则CLASS_ORIGIN'ISO 9075'Otherwise, CLASS_ORIGIN is 'MySQL'.否则,CLASS_ORIGIN'MySQL'

  • SUBCLASS_ORIGIN: A string containing the subclass of the RETURNED_SQLSTATE value. :包含RETURNED_SQLSTATE值的子类的字符串。If CLASS_ORIGIN is 'ISO 9075' or RETURNED_SQLSTATE ends with '000', SUBCLASS_ORIGIN is 'ISO 9075'. 如果CLASS_ORIGIN'ISO 9075'RETURNED_SQLSTATE'000'结尾,则SUBCLASS_ORIGIN'ISO 9075'Otherwise, SUBCLASS_ORIGIN is 'MySQL'.否则,SUBCLASS_ORIGIN就是'MySQL'

  • RETURNED_SQLSTATE: A string that indicates the SQLSTATE value for the condition.:指示条件的SQLSTATE值的字符串。

  • MESSAGE_TEXT: A string that indicates the error message for the condition.:一个字符串,指示条件的错误消息。

  • MYSQL_ERRNO: An integer that indicates the MySQL error code for the condition.:一个整数,指示该条件的MySQL错误代码。

  • CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME: Strings that indicate the catalog, schema, and name for a violated constraint. They are always empty.:表示违反约束的目录、架构和名称的字符串。它们总是空的。

  • CATALOG_NAME, SCHEMA_NAME, TABLE_NAME, COLUMN_NAME: Strings that indicate the catalog, schema, table, and column related to the condition. They are always empty.:表示与条件相关的目录、架构、表和列的字符串。它们总是空的。

  • CURSOR_NAME: A string that indicates the cursor name. This is always empty.:指示游标名称的字符串。这个总是空的。

For the RETURNED_SQLSTATE, MESSAGE_TEXT, and MYSQL_ERRNO values for particular errors, see Server Error Message Reference.有关返回的特定RETURNED_SQLSTATEMESSAGE_TEXTMYSQL_ERRNO值,请参阅服务器错误消息参考

If a SIGNAL (or RESIGNAL) statement populates the diagnostics area, its SET clause can assign to any condition information item except RETURNED_SQLSTATE any value that is legal for the item data type. 如果SIGNAL(或RESIGNAL)语句填充了诊断区域,则其SET子句可以为任何条件信息项赋值,但RETURNED_SQLSTATE除外,该项数据类型的任何合法值。SIGNAL also sets the RETURNED_SQLSTATE value, but not directly in its SET clause. SIGNAL还设置RETURNED_SQLSTATE值,但不直接在其SET子句中设置。That value comes from the SIGNAL statement SQLSTATE argument.该值来自SIGNAL语句SQLSTATE参数。

SIGNAL also sets statement information items. SIGNAL还设置语句信息项。It sets NUMBER to 1. 它将NUMBER设置为1。It sets ROW_COUNT to −1 for errors and 0 otherwise.它将错误的ROW_COUNT设置为1,否则设置为0。

How the Diagnostics Area is Cleared and Populated如何清除和填充诊断区域

Nondiagnostic SQL statements populate the diagnostics area automatically, and its contents can be set explicitly with the SIGNAL and RESIGNAL statements. 非诊断SQL语句自动填充诊断区域,其内容可以通过SIGNALRESIGNAL语句显式设置。The diagnostics area can be examined with GET DIAGNOSTICS to extract specific items, or with SHOW WARNINGS or SHOW ERRORS to see conditions or errors.可以使用GET DIAGNOSTICS(获取诊断)来检查诊断区域以提取特定项目,或者使用SHOW WARNINGS(显示警告)或SHOW ERRORS(显示错误)来查看条件或错误。

SQL statements clear and set the diagnostics area as follows:SQL语句清除并设置诊断区域,如下所示:

  • When the server starts executing a statement after parsing it, it clears the diagnostics area for nondiagnostic statements. 当服务器在解析语句后开始执行该语句时,它会清除诊断区域中的非诊断语句。Diagnostic statements do not clear the diagnostics area. 诊断语句无法清除诊断区域。These statements are diagnostic:这些陈述是诊断性的:

  • If a statement raises a condition, the diagnostics area is cleared of conditions that belong to earlier statements. 如果语句引发条件,则诊断区域将清除属于早期语句的条件。The exception is that conditions raised by GET DIAGNOSTICS and RESIGNAL are added to the diagnostics area without clearing it.例外情况是,GET DIAGNOSTICSRESIGNAL引发的条件被添加到诊断区域,而不清除它。

Thus, even a statement that does not normally clear the diagnostics area when it begins executing clears it if the statement raises a condition.因此,即使是在开始执行时通常不清除诊断区域的语句,如果该语句引发条件,也会将其清除。

The following example shows the effect of various statements on the diagnostics area, using SHOW WARNINGS to display information about conditions stored there.以下示例显示了diagnostics(诊断)区域中各种语句的效果,使用SHOW WARNINGS(显示警告)来显示有关存储在该区域的条件的信息。

This DROP TABLE statement clears the diagnostics area and populates it when the condition occurs:DROP TABLE语句清除诊断区域,并在出现以下情况时填充:

mysql> DROP TABLE IF EXISTS test.no_such_table;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> SHOW WARNINGS;
+-------+------+------------------------------------+
| Level | Code | Message                            |
+-------+------+------------------------------------+
| Note  | 1051 | Unknown table 'test.no_such_table' |
+-------+------+------------------------------------+
1 row in set (0.00 sec)

This SET statement generates an error, so it clears and populates the diagnostics area:SET语句生成错误,因此会清除并填充诊断区域:

mysql> SET @x = @@x;
ERROR 1193 (HY000): Unknown system variable 'x'

mysql> SHOW WARNINGS;
+-------+------+-----------------------------+
| Level | Code | Message                     |
+-------+------+-----------------------------+
| Error | 1193 | Unknown system variable 'x' |
+-------+------+-----------------------------+
1 row in set (0.00 sec)

The previous SET statement produced a single condition, so 1 is the only valid condition number for GET DIAGNOSTICS at this point. 上一个SET语句生成了一个条件,因此1是此时GET DIAGNOSTICS的唯一有效条件号。The following statement uses a condition number of 2, which produces a warning that is added to the diagnostics area without clearing it:以下语句使用的条件编号为2,会产生一个警告,该警告会添加到诊断区域,而不会清除该区域:

mysql> GET DIAGNOSTICS CONDITION 2 @p = MESSAGE_TEXT;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> SHOW WARNINGS;
+-------+------+------------------------------+
| Level | Code | Message                      |
+-------+------+------------------------------+
| Error | 1193 | Unknown system variable 'xx' |
| Error | 1753 | Invalid condition number     |
+-------+------+------------------------------+
2 rows in set (0.00 sec)

Now there are two conditions in the diagnostics area, so the same GET DIAGNOSTICS statement succeeds:现在diagnostics区域中有两种情况,因此相同的GET DIAGNOSTICS语句会成功:

mysql> GET DIAGNOSTICS CONDITION 2 @p = MESSAGE_TEXT;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @p;
+--------------------------+
| @p                       |
+--------------------------+
| Invalid condition number |
+--------------------------+
1 row in set (0.01 sec)
How the Diagnostics Area Stack Works诊断区域堆栈的工作原理

When a push to the diagnostics area stack occurs, the first (current) diagnostics area becomes the second (stacked) diagnostics area and a new current diagnostics area is created as a copy of it. 当推送到诊断区域堆栈时,第一个(当前)诊断区域成为第二个(堆叠)诊断区域,并创建一个新的当前诊断区域作为其副本。Diagnostics areas are pushed to and popped from the stack under the following circumstances:在以下情况下,诊断区域被推送到堆栈中并从堆栈中弹出:

  • Execution of a stored program存储程序的执行

    A push occurs before the program executes and a pop occurs afterward. 推送在程序执行之前发生,然后弹出。If the stored program ends while handlers are executing, there can be more than one diagnostics area to pop; this occurs due to an exception for which there are no appropriate handlers or due to RETURN in the handler.如果存储程序在处理程序执行时结束,则可以弹出多个诊断区域;这是由于没有适当的处理程序或由于处理程序中RETURN的异常而发生的。

    Any warning or error conditions in the popped diagnostics areas then are added to the current diagnostics area, except that, for triggers, only errors are added. 弹出的诊断区域中的任何警告或错误条件都会添加到当前诊断区域,但对于触发器,只会添加错误。When the stored program ends, the caller sees these conditions in its current diagonstics area.当存储程序结束时,调用者会在其当前诊断区域中看到这些情况。

  • Execution of a condition handler within a stored program在存储程序中执行条件处理程序

    When a push occurs as a result of condition handler activation, the stacked diagnostics area is the area that was current within the stored program prior to the push. 当条件处理程序激活导致推送时,堆叠诊断区域是推送之前存储程序中的当前区域。The new now-current diagnostics area is the handler's current diagnostics area. 新的当前诊断区域是处理程序的当前诊断区域。GET [CURRENT] DIAGNOSTICS and GET STACKED DIAGNOSTICS can be used within the handler to access the contents of the current (handler) and stacked (stored program) diagnostics areas. GET [CURRENT] DIAGNOSTICSGET STACKED DIAGNOSTICS可在处理程序内用于访问当前(处理程序)和堆叠(存储程序)诊断区域的内容。Initially, they return the same result, but statements executing within the handler modify the current diagnostics area, clearing and setting its contents according to the normal rules (see How the Diagnostics Area is Cleared and Populated). 最初,它们返回相同的结果,但在处理程序中执行的语句会修改当前诊断区域,并根据正常规则清除和设置其内容(请参见如何清除和填充诊断区域)。The stacked diagnostics area cannot be modified by statements executing within the handler except RESIGNAL.除了RESIGNAL之外,在处理程序中执行的语句不能修改堆叠的诊断区域。

    If the handler executes successfully, the current (handler) diagnostics area is popped and the stacked (stored program) diagnostics area again becomes the current diagnostics area. 如果处理程序成功执行,则弹出当前(处理程序)诊断区域,堆叠(存储程序)诊断区域再次成为当前诊断区域。Conditions added to the handler diagnostics area during handler execution are added to the current diagnostics area.处理程序执行期间添加到处理程序诊断区域的条件将添加到当前诊断区域。

  • Execution of RESIGNAL执行RESIGNAL

    The RESIGNAL statement passes on the error condition information that is available during execution of a condition handler within a compound statement inside a stored program. RESIGNAL语句传递错误条件信息,这些信息在存储程序中的复合语句中的条件处理程序执行期间可用。RESIGNAL may change some or all information before passing it on, modifying the diagnostics stack as described in Section 13.6.7.4, “RESIGNAL Statement”.RESIGNAL可能会在传递信息之前更改部分或全部信息,如第13.6.7.4节,“RESIGNAL语句”所述修改诊断堆栈。

Diagnostics Area-Related System Variables诊断区域相关系统变量

Certain system variables control or are related to some aspects of the diagnostics area:某些系统变量控制或与诊断领域的某些方面有关:

  • max_error_count controls the number of condition areas in the diagnostics area. 控制诊断区域中条件区域的数量。If more conditions than this occur, MySQL silently discards information for the excess conditions. 如果出现更多的情况,MySQL会自动丢弃多余情况的信息。(Conditions added by RESIGNAL are always added, with older conditions being discarded as necessary to make room.)RESIGNAL添加的条件始终会被添加,旧的条件会被丢弃以腾出空间。)

  • warning_count indicates the number of conditions that occurred. 指示发生的情况数。This includes errors, warnings, and notes. 这包括错误、警告和注释。Normally, NUMBER and warning_count are the same. 通常情况下,NUMBERwarning_count是相同的。However, as the number of conditions generated exceeds max_error_count, the value of warning_count continues to rise whereas NUMBER remains capped at max_error_count because no additional conditions are stored in the diagnostics area.然而,由于生成的条件数量超过了max_error_countwarning_count的值继续上升,而该NUMBER仍以max_error_count为上限,因为诊断区域中没有存储其他条件。

  • error_count indicates the number of errors that occurred. 指示发生的错误数。This value includes not found and exception conditions, but excludes warnings and notes. 此值包括“未找到”和异常条件,但不包括警告和注释。Like warning_count, its value can exceed max_error_count.warning_count一样,其值可以超过max_error_count

  • If the sql_notes system variable is set to 0, notes are not stored and do not increment warning_count.如果sql_notes系统变量设置为0,则不会存储注释,也不会增加warning_count

Example: If max_error_count is 10, the diagnostics area can contain a maximum of 10 condition areas. 示例:如果max_error_count为10,则诊断区域最多可包含10个条件区域。Suppose that a statement raises 20 conditions, 12 of which are errors. 假设一条语句引发20个条件,其中12个是错误。In that case, the diagnostics area contains the first 10 conditions, NUMBER is 10, warning_count is 20, and error_count is 12.在这种情况下,诊断区域包含前10个条件,NUMBER为10,warning_count为20,error_count为12。

Changes to the value of max_error_count have no effect until the next attempt to modify the diagnostics area. 在下次尝试修改诊断区域之前,对max_error_count值的更改无效。If the diagnostics area contains 10 condition areas and max_error_count is set to 5, that has no immediate effect on the size or content of the diagnostics area.如果诊断区域包含10个条件区域,且max_error_count设置为5,则不会立即影响诊断区域的大小或内容。