ER_WARN_I_S_SKIPPED_TABLE / Table '%s'.'%s' was skipped since its definition is being modified by concurrent DDL statement とは

見慣れないエラーに遭遇したので調べてみた。

https://github.com/mysql/mysql-server/blob/8.0/sql/sql_show.cc#L718

コメントにあるように、特定のテーブルのメタデータロックが競合した場合に発生するエラーのようです。

We are in situation when we have encountered conflicting metadata lock and deadlocks can occur due to waiting for it to go away. So instead of waiting skip this table with an appropriate warning.

https://github.com/mysql/mysql-server/blob/8.0/sql/sql_show.cc#L670

  • とあるスレッドがSHOWI_S (Information Schema)へのステートメントを発行するとき、MDL_SHARED_HIGH_PRIO でMDLを取得しようとする
    • https://github.com/mysql/mysql-server/blob/8.0/sql/sql_show.cc#L670
    • lock_wait_timeout ぶん待機してMDLを取得しようとする場合と、待機しない場合がある(以下の場合は待機しないらしい)
      • When .FRM is being open in order to get data for an I_S table, we might have some tables not only open but also locked. E.g. this happens when a SHOW or I_S statement is run under LOCK TABLES or inside a stored function. By waiting for the conflicting metadata lock to go away we might create a deadlock which won't entirely belong to the MDL subsystem and thus won't be detectable by this subsystem's deadlock detector. To avoid such situation, when there are other locked tables, we prefer not to wait on a conflicting lock.

    • when a SHOW or I_S statement is run under LOCK TABLES or inside a stored function. のunderというのは、他のスレッドでロックしているという意味でよいのかわからず...
  • すでに別のスレッドが対象のテーブルを MDL_EXCLUSIVE でMDLを取得していると、ロックが取得できずエラーになる

上記のコメントにも記載の通り、このケースでロックを待った場合に発生しうるデッドロックは、通常のデッドロック検知機構によって検知されないため、ロックを待たずに掲題のエラーにするようです。