このページでは、MySQL の孤立テーブルに関する既知の問題について説明します。
孤立テーブルとは
孤立テーブルとは、MySQL データ ディクショナリ全体で定義が切断されたテーブルのことです。MySQL 5.6 または MySQL 5.7 で発生する可能性があります。次のいずれかのシナリオでは、MySQL 5.7 から MySQL 8.0 へのメジャー バージョン アップグレード(MVU)がブロックされる可能性があります。
InnoDBデータファイル(.ibd)が存在するのに対応する定義ファイル(.frm)が存在しない場合、またはその逆の場合。- アクティブなアプリケーション ロジックで参照または使用されなくなった
ALTER TABLEステートメントから残された中間テーブルが存在する場合。
孤立した一時テーブル
孤立した一時テーブルの名前は、#sql- 接頭辞で始まります(例: #sql-123)。
次のクエリを使用すると、孤立した一時(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 コマンドが失敗した場合は、次の方法をお試しください。
始める前に
データ損失のリスクを軽減するため、インスタンスの完全バックアップを作成することを強くおすすめします。
アプリケーションのダウンタイムを短縮するため、インスタンスのクローンを作成し、本番環境で移行を実施する前に、次の移行手順を確認することを強くおすすめします。
詳細については、インスタンスのクローンを作成するをご覧ください。
オブジェクトの移行を使用してスキーマを削除する
データベース オブジェクトの移行は、テーブルなどのデータベース オブジェクトを一時スキーマに移動するための複数の手順から成るプロセスです。
- プロシージャ、関数、ビューなど、他のデータベース オブジェクトをバックアップします。
- 影響を受けたスキーマを削除して再作成します。
- バックアップしたオブジェクトを元のスキーマにインポートします。
この移行方法では、通常、アプリケーションのダウンタイムが発生します。中断を最小限に抑えるため、必要なスクリプトをすべて事前に準備してください。たとえば、スクリプトで次の処理に対応できることを確認します。
- テーブルの名前を変更して、一時スキーマにテーブルを移動する。
- プロシージャ、関数、ビューなど、他のデータベース オブジェクトをバックアップする。
- すべてのデータベース オブジェクトを元のスキーマに復元する。
これらのスクリプトの準備ができたら、次の手順を行います。
- 同じインスタンスに一時スキーマ(例:
fix_orphan_tables)を作成します。 - 影響を受けるスキーマのアプリケーション トラフィックを停止します。
RENAME TABLEを使用して、すべてのテーブルを一時スキーマに移動します。RENAME TABLE DB.TABLE_NAME TO fix_orphan_tables.TABLE_NAME;次のように置き換えます。
DB: 使用するデータベース名。TABLE_NAME: テーブル名。
ビュー、ルーティン、ストアド プロシージャ、トリガー、イベントなどのデータベース オブジェクトをバックアップします。その方法の一つとして、
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コマンド スニペットを使用して、ビューを手動でバックアップすることを強くおすすめします。孤立テーブルを含むスキーマを削除します。
元の名前でスキーマを作成します。
孤立テーブルが削除されたかどうかを確認します。
SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE '%ORPHAN_TABLE_NAME</var>';ORPHAN_TABLE_NAMEは、孤立テーブル名に置き換えます。テーブルを元のスキーマにコピーします。
RENAME TABLE fix_orphan_tables.TABLE_NAME TO DB.TABLE_NAME;次のように置き換えます。
TABLE_NAME: テーブル名。DB: 使用するデータベース名。
手順 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ステートメントを使用してビューを再作成し、手動で復元することを強くおすすめします。先ほどの手順で停止したアプリケーション トラフィックを再開します。
ダンプを使用してスキーマを削除し、同じインスタンスに読み込む
孤立テーブルを削除するもう一つの方法は、影響を受けるスキーマの完全なダンプを実行し、スキーマを削除して再作成してから、ダンプを復元することです。シナリオによっては、この方法のほうが高速かつ複雑でない場合があります。中断を最小限に抑えるため、バックアップ スクリプトと復元スクリプトをすべて事前に準備してください。
これらのスクリプトの準備ができたら、次の手順を行います。
- 影響を受けるスキーマのアプリケーション トラフィックを停止します。
mysqldumpを使用して、孤立テーブルを含むスキーマをバックアップします。これには、すべてのストアド プロシージャ、トリガー、ビュー、イベントが含まれます。- スキーマを削除します。
- スキーマを再作成し、バックアップ ファイルを復元します。
- 最初の手順で停止したアプリケーション トラフィックを再開します。
ダンプして新しいインスタンスまたは再作成されたインスタンスに読み込む
特定の条件では、孤立テーブルを含むスキーマを削除できません。このような場合は、新しいインスタンスに移行するか、論理ダンプを使用して既存のインスタンスを再作成してから読み込む必要があります。どちらの方法でもアプリケーションが中断する可能性があり、新しく作成または再作成されたデータベース インスタンスを指すようにアプリケーションを再構成する必要がある場合があります。以降のセクションでは、両方の方法について説明します。
Database Migration Service(DMS)を使用してデータを新しいインスタンスに移行する
- Database Migration Service を使用して、新しい Cloud SQL for MySQL インスタンスを作成します。
- レプリカ インスタンスが新しいインスタンスに関連付けられたデータのレプリケーションを完了したら、ソース インスタンスに接続しているすべてのアプリケーションを停止します。
- Cloud SQL for MySQL レプリカ インスタンスをプロモートします。
- 新しくプロモートした Cloud SQL for MySQL インスタンスを指すようにすべてのアプリケーション接続を変更し、アプリケーションを再起動します。
手動でダンプして復元する
- 新しいデータベース インスタンスを作成する場合は、現在のインスタンスと同じ構成でインスタンスを作成します。
- 現在のデータベース インスタンスのすべてのアプリケーション トラフィックを停止します。
mysqldumpなどのユーティリティを使用して、すべてのスキーマをバックアップします。- 同じインスタンスを使用する場合は、インスタンスを削除して再作成します。
- 手順 3 で作成したバックアップを使用して、新しいインスタンスまたは再作成された同じインスタンスにバックアップを復元します。
- 新しいインスタンスまたは再作成された同じインスタンスをアプリケーションが指すようにして、アプリケーションのオペレーションを再開します。