MySQL 8.0 リファレンスマニュアル


13.6.7.7 MySQL の診断領域

SQL ステートメントは、診断領域を移入する診断情報を生成します。 標準 SQL には、ネスト化された実行のコンテキストごとの診断領域を含んだ、診断領域スタックがあります。 標準 SQL はまた、条件ハンドラの実行中に 2 番目の診断領域を参照するための GET STACKED DIAGNOSTICS 構文もサポートしています。

次の説明では、MySQL の診断領域の構造、MySQL で認識される情報項目、ステートメントが診断領域をクリアおよび設定する方法、およびスタックに対して診断領域をプッシュおよびポップする方法について説明します。

診断領域の構造

診断領域には、次の 2 種類の情報が含まれています。

  • 発生した条件の数や、影響を受けた行数などのステートメント情報。

  • エラーコードやメッセージなどの条件情報。 ステートメントが複数の条件を発生させた場合、診断領域のこの部分には条件ごとの条件領域が含まれています。 ステートメントがどの条件も発生させない場合、診断領域のこの部分は空です。

3 つの条件を生成するステートメントの場合、診断領域には、次のようなステートメント情報と条件情報が含まれています。

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 ...
診断領域の情報項目

診断領域には、ステートメント情報と条件情報項目が含まれています。 数値項目は整数です。 文字項目の文字セットは UTF-8 です。 どの項目も NULL にはできません。 診断領域を移入するステートメントによってステートメントまたは条件項目が設定されていない場合、その値は、項目のデータ型に応じて 0 または空の文字列になります。

診断領域のステートメント情報の部分には、次の項目が含まれています。

  • NUMBER: 情報が含まれている条件領域の数を示す整数。

  • ROW_COUNT: このステートメントによって影響を受けた行数を示す整数。 ROW_COUNT には、ROW_COUNT() 関数と同じ値が含まれています (セクション12.16「情報関数」を参照してください)。

診断領域の条件情報の部分には、条件ごとの条件領域が含まれています。 条件領域には、1 から NUMBER ステートメント条件項目の値の番号が付けられています。 NUMBER が 0 である場合、条件領域は存在しません。

各条件領域には、次のリスト内の項目が含まれています。 MySQL 拡張である MYSQL_ERRNO を除き、すべての項目が標準 SQL です。 これらの定義は、シグナル以外によって (つまり、SIGNAL または RESIGNAL ステートメントによって) 生成された条件に適用されます。 シグナル以外の条件の場合、MySQL は、常に空であるとは示されていない条件項目のみを移入します。 条件領域に対するシグナルの影響については、あとで説明されています。

  • CLASS_ORIGIN RETURNED_SQLSTATE 値のクラスを含む文字列。 RETURNED_SQLSTATE 値が SQL 標準のドキュメント ISO 9075-2 (セクション 24.1、SQLSTATE) で定義されているクラス値で始まる場合、CLASS_ORIGIN'ISO 9075' です。 それ以外の場合、CLASS_ORIGIN'MySQL' です。

  • SUBCLASS_ORIGIN: RETURNED_SQLSTATE 値のサブクラスを含む文字列。 CLASS_ORIGIN'ISO 9075' であるか、または RETURNED_SQLSTATE'000' で終わる場合、SUBCLASS_ORIGIN'ISO 9075' です。 それ以外の場合、SUBCLASS_ORIGIN'MySQL' です。

  • RETURNED_SQLSTATE: この条件の SQLSTATE 値を示す文字列。

  • MESSAGE_TEXT: この条件のエラーメッセージを示す文字列。

  • MYSQL_ERRNO: この条件の MySQL エラーコードを示す整数。

  • CONSTRAINT_CATALOGCONSTRAINT_SCHEMACONSTRAINT_NAME: 違反した制約のカタログ、スキーマ、および名前を示す文字列。 これらは常に空です。

  • CATALOG_NAMESCHEMA_NAMETABLE_NAMECOLUMN_NAME: この条件に関連したカタログ、スキーマ、テーブル、およびカラムを示す文字列。 これらは常に空です。

  • CURSOR_NAME: カーソル名を示す文字列。 これは常に空です。

RETURNED_SQLSTATEMESSAGE_TEXT、および MYSQL_ERRNO 値の特定のエラーについては、Server Error Message Referenceを参照してください。

SIGNAL (または RESIGNAL) ステートメントが診断領域を移入する場合、その SET 句は、RETURNED_SQLSTATE を除く任意の条件情報項目に、その項目のデータ型に対して正当な任意の値を割り当てることができます。 SIGNAL はまた、RETURNED_SQLSTATE 値も設定しますが、その SET 句で直接設定するわけではありません。 その値は、SIGNAL ステートメントの SQLSTATE 引数から取得されます。

SIGNAL は、ステートメント情報項目も設定します。 NUMBER を 1 に設定します。 エラーの場合は ROW_COUNT を−1 に設定し、それ以外の場合は 0 に設定します。

診断領域のクリアおよび移入方法

診断以外の SQL ステートメントは診断領域に自動的に移入され、その内容は SIGNAL および RESIGNAL ステートメントを使用して明示的に設定できます。 診断領域は、特定の項目を抽出するために GET DIAGNOSTICS を使用して、あるいは条件またはエラーを確認するために SHOW WARNINGS または SHOW ERRORS を使用して検査できます。

SQL ステートメントは、次のように診断領域をクリアおよび設定します。

  • 解析後にサーバーがステートメントの実行を開始すると、非診断ステートメントの診断領域がクリアされます。 診断ステートメントは診断領域をクリアしません。 次のステートメントは診断です:

    • GET DIAGNOSTICS

    • SHOW ERRORS

    • SHOW WARNINGS

  • ステートメントが条件を発生させた場合は、以前のステートメントに属する条件の診断領域がクリアされます。 例外として、GET DIAGNOSTICS および RESIGNAL によって発生した条件は、診断領域にその領域をクリアすることなく追加されます。

そのため、通常は実行開始時に診断領域をクリアしないステートメントであっても、そのステートメントが条件を発生させた場合は診断領域をクリアします。

次の例は、診断領域に対するさまざまなステートメントの影響を、SHOW WARNINGS を使用して、そこに格納されている条件に関する情報を表示することによって示しています。

次の 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)

次の 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)

前の SET ステートメントは 1 つの条件を生成したため、1 がこの時点での GET DIAGNOSTICS の唯一の有効な条件番号です。 次のステートメントは 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)

これで、診断領域には 2 つの条件が存在するようになったため、同じ 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)
診断領域スタックの動作

診断領域スタックへのプッシュが発生すると、最初の (現在の) 診断領域が 2 番目の (スタックされた) 診断領域になり、新しい現在の診断領域がそのコピーとして作成されます。 診断領域は、次の状況でスタックにプッシュされ、スタックからポップされます:

  • ストアドプログラムの実行

    プログラムが実行される前にプッシュが発生し、その後ポップが発生します。 ハンドラの実行中にストアドプログラムが終了した場合、ポップする診断領域が複数存在する可能性があります。これは、適切なハンドラがない例外またはハンドラ内の RETURN が原因で発生します。

    ポップされた診断領域の警告またはエラーの状態は、トリガーの場合はエラーのみが追加されることを除き、現在の診断領域に追加されます。 ストアドプログラムが終了すると、呼び出し元の現在の診断領域にこれらの状態が表示されます。

  • ストアドプログラム内での条件ハンドラの実行

    条件ハンドラのアクティブ化の結果としてプッシュが発生した場合、スタック診断領域はプッシュ前にストアドプログラム内で最新だった領域です。 新しい非現在の診断領域は、ハンドラの現在の診断領域です。 ハンドラ内で GET [CURRENT] DIAGNOSTICS および GET STACKED DIAGNOSTICS を使用して、現在 (ハンドラ) およびスタック (ストアドプログラム) の診断領域の内容にアクセスできます。 最初は同じ結果が返されますが、ハンドラ内で実行されているステートメントは現在の診断領域を変更し、通常の規則に従ってその内容をクリアおよび設定します (診断領域のクリアおよび移入方法 を参照)。 スタック診断領域は、RESIGNAL を除くハンドラ内で実行されているステートメントでは変更できません。

    ハンドラが正常に実行されると、現在の (ハンドラ) 診断領域がポップされ、スタック (ストアドプログラム) 診断領域が再度現在の診断領域になります。 ハンドラの実行中にハンドラ診断領域に追加された条件は、現在の診断領域に追加されます。

  • RESIGNAL の実行

    RESIGNAL ステートメントは、ストアドプログラム内の複合ステートメント内で条件ハンドラの実行中に使用可能なエラー条件情報を渡します。 RESIGNAL は、情報の一部またはすべてを変更してから渡すことができ、セクション13.6.7.4「RESIGNAL ステートメント」 の説明に従って診断スタックを変更します。

診断領域関連のシステム変数

特定のシステム変数が診断領域のいくつかの側面を制御するか、またはそれに関連しています。

  • max_error_count は、診断領域内の条件領域の数を制御します。 これより多い条件が発生した場合、MySQL は、超過した条件に関する情報を暗黙のうちに破棄します。 (RESIGNAL によって追加された条件は、常に追加されます。空きを作るために、古い条件が必要に応じて破棄されます。)

  • warning_count は、発生した条件の数を示します。 これには、エラー、警告、および注意が含まれます。 通常、NUMBERwarning_count は同じです。 ただし、生成された条件の数が max_error_count を超えると、診断領域にはそれ以上の条件が格納されないため、warning_count の値が引き続き増えるのに対して、NUMBERmax_error_count に上限が設定されたままになります。

  • error_count は、発生したエラーの数を示します。 この値には見つからないと例外条件が含まれますが、警告と注意は除外されます。 warning_count と同様に、その値は max_error_count を超えることができます。

  • sql_notes システム変数が 0 に設定されている場合、注意は格納されず、warning_count も増分しません。

例: max_error_count が 10 である場合、診断領域には最大 10 個の条件領域を含めることができます。 ステートメントが 20 個の条件を発生させ、そのうちの 12 個がエラーであるとします。 その場合、診断領域には最初の 10 個の条件が含まれ、NUMBER は 10、warning_count は 20、error_count は 12 です。

max_error_count の値を変更しても、次に診断領域を変更しようとするまでは何の効果もありません。 診断領域に 10 個の条件領域が含まれているときに max_error_count が 5 に設定された場合、その診断領域のサイズまたは内容への即座の影響は何もありません。


関連キーワード:  ステートメント, 領域, 診断, 条件, CREATE, TABLE, 情報, DROP, 発生, ハンドラ