孤立したテーブル

このページでは、MySQL の孤立テーブルに関する既知の問題について説明します。

孤立したテーブルとは

孤立したテーブルは、MySQL データ ディクショナリ全体で定義が切断されたテーブルです。MySQL 5.6 または MySQL 5.7 で発生する可能性があります。次のいずれかのシナリオでは、MySQL 5.7 から MySQL 8.0 へのメジャー バージョン アップグレード(MVU)がブロックされる可能性があります。

  • 対応する定義ファイル(.frm)のない InnoDB データファイル(.ibd)が存在する場合、またはその逆の場合。
  • アクティブなアプリケーション ロジックで参照または使用されなくなった ALTER TABLE ステートメントから残された中間テーブルが存在する。

孤立した一時テーブル

孤立した一時テーブルの名前は、#sql-123 など、#sql- 接頭辞で始まります。

次のクエリは、孤立した一時テーブル(temp)を特定するのに役立ちます。

SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME RLIKE '#sql-[0-9].*';

DROP TABLE コマンドを使用すると、他の追加の手順なしで孤立した一時テーブルを削除できます。これにより、ほとんどのケースに対応できます。

DROP TABLE `DB`.`#mysql50#TEMPORARY_ORPHAN_TABLE`;

DB は、使用するデータベースの名前に置き換えます。

例を次に示します。

DROP TABLE `testdb`.`#mysql50##sql-1234`;

上記の DROP テーブル コマンドが機能しない場合、定義ファイル(.frm)が別の ALTER TABLE オペレーションで再利用されている可能性があります。このような場合は、テーブルを削除するために、ディスク上にプレースホルダ .frm ファイルを作成する必要があります。サポートが必要な場合は、Cloud SQL サポートにお問い合わせください。サポート契約を結んでいない場合は、セルフサービスの方法でトラブルシューティングの手順をご確認ください。

孤立した中間テーブル

孤立した中間テーブル名は、#sql-ib 接頭辞で始まります(例: #sql-ib23-343224)。

次のクエリを使用して、孤立した中間テーブルを特定します。

SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE '%#sql-ib%';

中間孤立テーブルを削除するには、まず孤立定義ファイル名(.frm)をテーブル名と一致するように変更し、コマンドラインからテーブルを削除します。

中間孤立テーブルを削除するには、Cloud SQL サポートチームにお問い合わせください。サポート契約を結んでいない場合は、セルフサービスの方法でトラブルシューティングの手順を確認してください。

孤立した通常のテーブル

孤立した InnoDB テーブルは、対応するデータファイル(.ibd)ファイルがファイル システムに残っているにもかかわらず、データ ディクショナリがデータファイルを正しく参照しなくなった場合に発生します。このシナリオでは手動での介入が必要です。

この問題を解決するには、Cloud SQL サポートにお問い合わせください。サポートチームは、プレースホルダ .frm ファイルを作成し、DROP TABLE コマンドを使用してテーブルの削除を試みることができます。失敗した場合は、InnoDB.ibd)ファイルをデータ ディレクトリから手動で削除する必要がある可能性があります。

ファイルを削除したら、すべてのテーブルとデータベース構造をバックアップできます。

DROP DATABASE を使用してデータベースを削除し、CREATE DATABASE を使用してデータベースを作成します。この最後の手順では、影響を受けるデータベースに接続されているアプリケーションのダウンタイムが必要になることがあります。

サポート契約を結んでいない場合は、セルフサービスの方法でトラブルシューティングの手順をご確認ください。

セルフサービス トラブルシューティング

次のセルフサービス トラブルシューティング方法では、個々のテーブルの削除が機能しない場合に、データベース全体を削除または移行して孤立したテーブルを削除します。この方法は中断を伴います。組織がサポート契約を結んでいる場合は、Cloud SQL サポートチームに支援を依頼することを強くおすすめします。

孤立した一時テーブルを削除するには、まず 孤立した一時テーブルの手順に沿って操作してください。DROP TABLE コマンドが失敗した場合は、次の方法をお試しください。

始める前に

オブジェクト移行を使用してスキーマを削除する

データベース オブジェクトの移行は、テーブルなどのデータベース オブジェクトを一時スキーマに移動する複数ステップのプロセスです。

  1. プロシージャ、関数、ビューなどの他のデータベース オブジェクトをバックアップします。
  2. 影響を受けたスキーマを削除して再作成します。
  3. バックアップしたオブジェクトを元のスキーマにインポートします。

この移行方法では、通常、アプリケーションのダウンタイムが発生します。中断を最小限に抑えるため、必要なスクリプトをすべて事前に準備します。たとえば、スクリプトが次の処理に対応できるようにします。

  • テーブルの名前を変更して、一時スキーマに移動します。
  • プロシージャ、関数、ビューなどの他のデータベース オブジェクトのバックアップ。
  • すべてのデータベース オブジェクトを元のスキーマに復元する。

これらのスクリプトの準備ができたら、次の手順を完了します。

  1. 同じインスタンスに一時スキーマ(例: fix_orphan_tables)を作成します。
  2. 影響を受けるスキーマのアプリケーション トラフィックを停止します。
  3. RENAME TABLE を使用して、すべてのテーブルを一時スキーマに移動します。

    RENAME TABLE DB.TABLE_NAME TO fix_orphan_tables.TABLE_NAME;
    

    次のように置き換えます。

    • DB: 使用するデータベース名。
    • TABLE_NAME: テーブル名。
  4. ビュー、ルーティン、ストアド プロシージャ、トリガー、イベントなどのデータベース オブジェクトをバックアップします。その方法の 1 つに、mysqldump を使用する方法があります。

    mysqldump -u USER --password=PASSWORD \
      -h HOST_IP --set-gtid-purged=OFF --no-data --no-create-db  \
      --no-create-info --routines --triggers --skip-opt --events \
      DB > DB_export.sql
    

    次のように置き換えます。

    • USER: ユーザー名。
    • PASSWORD: データベースのパスワード。
    • HOST_IP: ホストの IP アドレス。
    • DB: 使用するデータベース名。

    SHOW CREATE VIEW コマンド スニペットを使用して、ビューを手動でバックアップすることを強くおすすめします。

  5. 孤立したテーブルを含むスキーマを削除します。

  6. 元の名前でスキーマを作成します。

  7. 孤立したテーブルが削除されたかどうかを確認します。

    SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE '%ORPHAN_TABLE_NAME</var>';
    

    ORPHAN_TABLE_NAME は、孤立したテーブル名に置き換えます。

  8. テーブルを元のスキーマにコピーします。

    RENAME TABLE fix_orphan_tables.TABLE_NAME TO DB.TABLE_NAME;
    

    次のように置き換えます。

    • TABLE_NAME: テーブル名。
    • DB: 使用するデータベース名。
  9. ステップ 4 で作成したバックアップからすべてのデータベース オブジェクトをコピーします。

    mysql -u USER \
      --password=PASSWORD \
      -h <var>HOST_IP \
      -D<var>DB < <var>DB_export.sql
    

    次のように置き換えます。

    • USER: ユーザー名。
    • PASSWORD: データベースのパスワード。
    • HOST_IP: ホストの IP アドレス。
    • DB: 使用するデータベース名。

    CREATE VIEW ステートメントを使用してビューを再作成し、手動で復元することを強くおすすめします。

  10. 以前に停止したアプリ トラフィックを再開します。

ダンプを使用してスキーマを削除し、同じインスタンスに読み込む

孤立したテーブルを削除するもう 1 つの方法は、影響を受けるスキーマの完全なダンプを実行し、スキーマを削除して再作成してから、ダンプを復元することです。シナリオによっては、この方法がより高速で複雑でない場合があります。中断を最小限に抑えるため、バックアップ スクリプトと復元スクリプトを事前に準備してください。

これらのスクリプトの準備ができたら、次の手順を完了します。

  1. 影響を受けるスキーマのアプリケーション トラフィックを停止します。
  2. mysqldump を使用して、孤立したテーブルがあるスキーマをバックアップします。これには、すべてのストアド プロシージャ、トリガー、ビュー、イベントが含まれます。
  3. スキーマを削除します。
  4. スキーマを再作成し、バックアップ ファイルを復元します。
  5. 最初の手順で停止したアプリケーション トラフィックを再開します。

新しいインスタンスまたは再作成されたインスタンスにダンプして読み込む

特定の条件では、孤立したテーブルを含むスキーマを削除できません。このような場合は、新しいインスタンスに移行するか、論理ダンプと読み込みを使用して既存のインスタンスを再作成する必要があります。どちらの方法でもアプリケーションが中断する可能性があり、新しく作成または再作成されたデータベース インスタンスを指すようにアプリケーションを再構成する必要がある場合があります。以降のセクションでは、両方の方法について説明します。

Database Migration Service(DMS)を使用してデータを新しいインスタンスに移行する

  1. Database Migration Service を使用して、新しい Cloud SQL for MySQL インスタンスを作成します。
  2. レプリカ インスタンスが新しいインスタンスに関連付けられたデータのレプリケーションを完了したら、ソース インスタンスに接続するアプリケーションをすべて停止します。
  3. レプリカの Cloud SQL for MySQL インスタンスを昇格させます。
  4. すべてのアプリケーション接続を、新しく昇格した Cloud SQL for MySQL インスタンスを指すように変更し、アプリケーションを再起動します。

手動ダンプと復元

  1. 新しいデータベース インスタンスを作成する場合は、現在のインスタンスと同じ構成でインスタンスを作成します。
  2. 現在のデータベース インスタンスのすべてのアプリケーショントラフィックを停止します。
  3. mysqldump などのユーティリティを使用して、すべてのスキーマをバックアップします。
  4. 同じインスタンスを使用している場合は、インスタンスを削除して再作成します。
  5. 手順 3 で作成したバックアップを使用して、新しいインスタンスまたは同じ再作成されたインスタンスにバックアップを復元します。
  6. アプリケーションを新しいインスタンスまたは同じ再作成されたインスタンスに指定し、アプリケーションのオペレーションを再開します。

次のステップ

  1. トラブルシューティング
  2. データベースのメジャー バージョンをインプレースでアップグレードする