MySQL テーブル名変更ランブック:依存関係調査・安全な切替・ロールバック

テーブル名の変更は SQL 1 行に見えますが、アプリケーション、ビュー、ジョブ、権限、監視が共有しているオブジェクト名を瞬時に変えます。本番環境での安全性とは、文を成功させることだけではありません。すべての利用側が同じ変更時間帯に切り替えられ、異常時に明確な復旧経路が残ることを証拠で示す必要があります。

このガイドは Oracle MySQL 8.4 LTS と、サポート対象の MySQL 8.x を想定しています。MariaDB、Aurora MySQL、Cloud SQL、Azure Database for MySQL、HeatWave、NDB Cluster、その他のマネージド製品や互換製品では、DDL、バックアップ、レプリケーション、schema 間移動、権限に制約がある場合があります。正確な製品とバージョンの資料を先に確認してください。以下の名称と SQL はすべて仮定上の例であり、実データベースへそのまま実行してはいけません。

対象範囲と省略できないゲート

次のすべてを満たした場合だけ変更設計へ進みます。

  • 資産所有者と DBA が、正確なサーバー、schema、旧名、新名、保守時間帯を書面で承認している。
  • ディストリビューション、正確なバージョン、ストレージエンジン、レプリケーション構成、マネージドサービスの制限、lower_case_table_names の値を確認済みである。
  • 依存関係一覧がアプリケーション、設定、ORM、マイグレーション、ETL、レポート、バックアップ、監視、データベースオブジェクトを含む。
  • 新しく整合性のあるバックアップまたはサービススナップショット、検証済みの復元経路、復旧ポイント識別子、明確な復旧責任者が存在する。
  • アプリケーションの切替版とロールバック版が準備され、書込みを停止またはドレインでき、観測可能な保守時間帯がある。
  • DDL セッションは監査対象の DBA 経路を使い、コマンドライン引数、履歴、ログ、本文の例にパスワード、トークン、非公開 DSN を置かない。

一つでも欠ければ停止します。名前変更を一時しのぎにせず、「先に変更して後で確認」という方法を取ってはいけません。

RENAME TABLEALTER TABLE ... RENAME

適切な範囲重要な境界
RENAME TABLE一つ以上の通常テーブル。複数名を一緒に切り替える場合に明確TEMPORARY テーブルには使えない。複数オブジェクトは左から右へ処理される。エラーがあれば文全体が失敗するが、atomic DDL はエンジンとバージョンに依存する
ALTER TABLE ... RENAME TO一つの通常テーブル。セッション一時テーブル名を変更する公式経路でもある1 文につき 1 テーブル。同じく暗黙コミットとメタデータロックを伴う DDL。前者に加えて重複実行しない

どちらも ROLLBACK で元に戻せる通常のトランザクション操作ではありません。MySQL の文書では、DDL は実行前に現在のセッションのアクティブなトランザクションを暗黙に終了し、通常は実行後にもコミットすると説明されています。MySQL 8 の atomic DDL はデータディクショナリの変更、対応ストレージエンジンの操作、バイナリログ書込みを一つの原子的操作にまとめますが、トランザクショナル DDL ではありません。アプリケーション設定、外部ジョブ、誤った業務判断は元に戻しません。

MySQL 8.4 では InnoDB が atomic DDL をサポートします。この保証を非 InnoDB エンジン、旧版、フォーク、マネージドサービスの実装へ広げてはいけません。名前変更自体は通常テーブル内容をコピーしませんが、排他的メタデータロック待ちが長時間の停止を生むことはあります。

先にバージョン、エンジン、オブジェクト、大小文字モードを記録する

読取り専用の監査アカウントで対象接続上の次のクエリを実行し、結果を変更記録へ添付します。例では app_live.customer_order_legacy が旧名、app_live.customer_order が新名です。

SELECT VERSION() AS server_version,
       @@version_comment AS distribution,
       @@lower_case_table_names AS lower_case_table_names;

SELECT table_schema, table_name, table_type, engine
FROM information_schema.tables
WHERE table_schema IN ('app_live', 'app_archive')
  AND table_name IN ('customer_order_legacy', 'customer_order')
ORDER BY table_schema, table_name;

証拠では旧オブジェクトが存在し、新オブジェクトが存在せず、オブジェクト種別とエンジンが計画どおりでなければなりません。両方の名前が存在する、対象がビューである、オブジェクトが一時テーブルである、または問合せ権限が不足する場合は、推測せず停止します。

MySQL の schema 名とテーブル名の大小文字動作は、OS のファイルシステムと、初期化時に固定される lower_case_table_names の両方に依存します。大小文字だけ異なる名前が、あるサーバーでは別オブジェクト、別のサーバーでは競合になることがあります。ソース、レプリカ、復元環境、移行先のモードが違うと case-only rename の結果も変わります。DBA が同じ構成の隔離環境で設計・検証する必要があります。

権限、コミット、メタデータロック

公式の RENAME TABLE 文書は、旧オブジェクトに ALTERDROP、新オブジェクトに CREATEINSERT を要求しています。ALTER TABLE 文書では、名前変更時の新オブジェクトに ALTER も列挙されています。変更用の正確なアカウントと有効ロールで実効権限を確認します。不足時は権限所有者が対処し、一時的な広範囲グローバル権限やデータベース root で手順を迂回してはいけません。

MySQL はアクティブなトランザクションが使うオブジェクトにメタデータロックを保持します。名前変更には排他的メタデータロックが必要なため、アイドル状態でも未コミットの長時間トランザクションが DDL を待たせます。排他要求が待ち行列に入ると、その後のアクセスも後ろに並び、障害範囲が拡大する場合があります。小さなテーブルだからロック待ちが短いとは限りません。

変更セッションに承認済みの有限な lock_wait_timeout を設定すると、無期限に待たず失敗させられます。タイムアウト後は診断して再計画します。自動再試行せず、所有者不明のセッションを勝手に終了しないでください。

完全な依存関係一覧を作る

依存関係の分類保存すべき証拠切替責任者
アプリケーションコード、設定、ORM マッピング、マイグレーション完全文字列と生成 SQL の検索結果、リリース版、接続プール更新計画アプリケーション所有者
ビュー、トリガー、外部キー、プロシージャ、関数、イベントSHOW CREATEINFORMATION_SCHEMA の結果、オブジェクト所有者DBA と DB オブジェクト所有者
動的 SQL、ETL、キュー利用側、定期ジョブ、BI、エクスポート実行時カタログ、スケジューラ定義、データリネージ、停止または切替計画データ・運用所有者
レプリケーション、CDC、バックアップ、復元、アーカイブ、監査構成、フィルター、レプリケーション遅延、復旧ポイント、復元演習、名称依存DBA とプラットフォーム所有者
テーブルまたは列固有の権限変更前の権限一覧と新名称の最小権限計画セキュリティ・権限所有者
監視、アラート、容量、SLO、ランブッククエリテンプレート、ダッシュボード、アラート規則、新旧名称の観測期間SRE またはオンコール責任者

文字列検索は出発点にすぎません。連結された動的 SQL、ORM が生成する名称、大小文字を区別する参照、外部 SaaS コネクタ、古いバックアップスクリプトは静的検索から漏れる場合があります。各分類に責任者の承認が必要であり、「見つからない」は「依存しない」証明ではありません。

読取り専用のデータベース依存関係調査

GUI の列一覧だけではなく、正規定義とインデックスを先に保存します。出力には definer、コメント、業務識別子が含まれることがあります。広く共有する前に機密情報を除きつつ、変更証拠にはアクセス制御された原本を残します。

SHOW CREATE TABLE app_live.customer_order_legacy;
SHOW INDEX FROM customer_order_legacy FROM app_live;

旧テーブルに定義された外部キーと、旧テーブルを参照する外部キーの両方を調べます。名前変更時、MySQL はそのテーブルを指す外部キー参照を更新します。内部生成の制約名と、旧表名に _ibfk_ を付けた接頭辞で始まるユーザー定義名も変わる場合があります。名称競合があると文は失敗するため、切替前に制約名を保存・審査します。

SELECT constraint_schema, constraint_name,
       table_schema, table_name,
       referenced_table_schema, referenced_table_name,
       ordinal_position
FROM information_schema.key_column_usage
WHERE (table_schema = 'app_live'
       AND table_name = 'customer_order_legacy')
   OR (referenced_table_schema = 'app_live'
       AND referenced_table_name = 'customer_order_legacy')
ORDER BY constraint_schema, constraint_name, ordinal_position;

同一 schema 内の名前変更では、トリガーはテーブルとの関連を維持します。トリガーを持つテーブルはこの方法で別 schema へ移せません。基底テーブルを改名しただけでビュー参照が安全なアプリケーション互換層になるわけではありません。MySQL は一部のテーブル変更で事前警告なくビューを無効化できるため、切替前にビューを列挙して定義を確認します。

SELECT trigger_schema, trigger_name,
       event_manipulation, action_timing
FROM information_schema.triggers
WHERE event_object_schema = 'app_live'
  AND event_object_table = 'customer_order_legacy'
ORDER BY trigger_schema, trigger_name;

SELECT view_schema, view_name
FROM information_schema.view_table_usage
WHERE table_schema = 'app_live'
  AND table_name = 'customer_order_legacy'
ORDER BY view_schema, view_name;

次はストアドプログラムとイベントの候補抽出にすぎません。定義の可視性は権限に依存し、動的 SQL が名称を連結する場合があり、偽陽性もあります。各候補について、管理下で SHOW CREATE PROCEDURESHOW CREATE FUNCTIONSHOW CREATE EVENT を実行して人が確認します。

SELECT routine_schema, routine_name, routine_type
FROM information_schema.routines
WHERE LOCATE('customer_order_legacy',
             COALESCE(routine_definition, '')) > 0
ORDER BY routine_schema, routine_name;

SELECT event_schema, event_name, status
FROM information_schema.events
WHERE LOCATE('customer_order_legacy',
             COALESCE(event_definition, '')) > 0
ORDER BY event_schema, event_name;

テーブル名固有の権限は新名称へ自動移行しません。テーブル権限、列権限、ロール対応、アプリケーション ID を保存します。新オブジェクトには承認済みの最小権限だけを再作成し、不要になった過去の権限を複製しないでください。

SELECT CURRENT_USER() AS authenticated_account,
       CURRENT_ROLE() AS active_roles;

SHOW GRANTS FOR CURRENT_USER;

SELECT grantee, privilege_type, is_grantable
FROM information_schema.table_privileges
WHERE table_schema = 'app_live'
  AND table_name = 'customer_order_legacy'
ORDER BY grantee, privilege_type;

SELECT grantee, column_name, privilege_type, is_grantable
FROM information_schema.column_privileges
WHERE table_schema = 'app_live'
  AND table_name = 'customer_order_legacy'
ORDER BY grantee, column_name, privilege_type;

これらの結果だけでは実効権限の完全な証明になりません。schema レベルまたはグローバルの権限、有効または強制ロール、ロール継承、partial revokes が結果を変え得ます。DBA が移動元と移動先の両方について実行時権限を算定し、SHOW GRANTS の出力を未審査のまま再実行してはいけません。

メタデータロックと長時間トランザクションの事前確認

保守時間帯の前と DDL の直前に 1 回ずつ確認します。performance_schema.metadata_locks は読取り専用ですが、マネージドサービスの権限や instrumentation 設定によって見えない場合があります。可視性がなければ、サービス提供者が承認した同等手段を使うか DBA へエスカレーションします。十分な可視性がない空の結果を「ロックなし」の証拠にしてはいけません。

SELECT object_schema, object_name,
       lock_type, lock_duration, lock_status,
       owner_thread_id
FROM performance_schema.metadata_locks
WHERE object_type = 'TABLE'
  AND object_schema = 'app_live'
  AND object_name = 'customer_order_legacy'
ORDER BY lock_status, owner_thread_id;

SELECT trx_id, trx_state, trx_started,
       TIMESTAMPDIFF(SECOND, trx_started, NOW()) AS age_seconds,
       trx_tables_locked, trx_rows_modified,
       trx_mysql_thread_id
FROM information_schema.innodb_trx
ORDER BY trx_started;

チケットには機密情報を除いた必要最小限のスレッド ID、継続時間、ロック状態だけを記載します。生の process list や SQL には個人データや秘密情報が含まれ得るため、公開ログへ貼り付けてはいけません。長時間トランザクション、所有者不明のロック、異常なレプリケーション適用スレッド、待機中の DDL があれば停止します。コミット、ロールバック、取消、延期の判断はセッション所有者または DBA が行います。

Schema 間、トリガー、ビュー、エンジン、ファイルシステムの境界

MySQL の構文では通常テーブルを別 schema へ改名できますが、一般的な移行手順ではありません。以下は構文説明だけで、標準の切替手順には含みません

RENAME TABLE app_live.customer_order_legacy
TO app_archive.customer_order_legacy;

テーブルにトリガーがあると schema 間の名前変更は失敗し、RENAME TABLE でビューを別 schema へ移すこともできません。移動元と移動先のデータベースが別ファイルシステムにある場合、成功可否はプラットフォームの基盤となる移動処理に依存します。暗号化既定値、テーブルスペース、ストレージエンジン、マネージドサービス権限、バックアップ方針も操作を妨げたり挙動を変えたりします。この場合は同一 schema の手順を流用せず、バージョンと提供者に固有の移行ランブックを使います。

RENAME TABLETEMPORARY テーブルに使えません。作成した同じセッションで一時テーブル名を本当に変更する必要がある場合、文書化された経路は次のとおりです。

ALTER TABLE app_work.customer_order_session
RENAME TO app_work.customer_order_session_v2;

一時テーブルの可視性、有効期間、暗黙コミットの境界は永続テーブルと異なります。現在のセッションの一時テーブルであることを確認し、この例を本番の永続オブジェクトに使わないでください。

Case-only rename は通常の名前変更ではない

大小文字だけを変える前に、@@lower_case_table_names、基盤ファイルシステム、すべてのレプリカ、すべての復元先を調べます。テーブル名を「直す」ためにサーバー初期化変数を変更してはいけません。MySQL 8 は初期化後のこの設定変更を禁止しています。

正確な環境を検証し、移動先が存在しない場合、競合しない中間名が必要になることがあります。以下は隔離テスト環境向けの候補構文にすぎず、どの本番構成にも適する保証はありません。

RENAME TABLE app_live.CustomerOrder
TO app_live.customer_order_case_stage,
app_live.customer_order_case_stage
TO app_live.customerorder;

大小文字比較によって移動元、移動先、中間名が同一オブジェクトと扱われる場合、またはレプリカの設定が異なる場合は直ちに停止します。データディレクトリのファイルを直接操作したり、OS の mv で MySQL データディクショナリを迂回したりしてはいけません。

保守時間帯と切替の進行手順

  1. 計画を固定: 旧名、新名、変更 ID、責任者、開始時刻、最大ロック待ち、合格条件、ロールバック期限を固定し、時間帯内の他の schema 変更を禁止します。
  2. バックアップゲート: 整合バックアップまたはマネージドスナップショット、バイナリログまたはサービス復旧ポイント、復元演習の証拠を記録します。レプリケーションはバックアップではなく、atomic DDL は論理的な誤りからの復旧策ではありません。
  3. 利用側ゲート: 新名称を利用可能なリリースを、まだトラフィックを切り替えずに配置します。書込み、ETL、CDC 下流、レポート、バックアップ、保守ジョブを停止またはドレインし、接続プール更新計画を準備します。
  4. 健全性ゲート: レプリケーションとバックアップサービスが正常で、未知の長時間トランザクション、メタデータロック待ち、プラットフォーム警告がないことを確認します。旧オブジェクトが存在し、新オブジェクトがなく、SHOW CREATE、インデックス、外部キー、トリガー、権限の証拠を保存済みにします。
  5. 単一実行者: 権限を与えられた 1 人だけが監査対象セッションで審査済み DDL 1 文を実行します。START TRANSACTION で囲まず、自動化に無制限の再試行をさせません。
  6. 即時検証: 名称、正規定義、インデックス、制約、トリガー、最小権限、レプリケーション適用、読取り専用アプリケーション canary を確認します。差異があれば書込み停止を維持します。
  7. 制御された切替: アプリケーション、ORM、ジョブ、監視を切り替え、接続プールを更新します。読取りと書込みを段階的に戻しながら、エラー率、遅延、ロック待ち、レプリケーション遅延を観測します。
  8. 時間帯を終了: すべての利用側とレプリカが合格し、ロールバック責任者が同意してから終了します。バックアップ、旧設定、ロールバック成果物をすぐ削除しないでください。

仮定上の同一 schema DDL

次の例は app_live.customer_order_legacyapp_live.customer_order に変えます。上記の全ゲートを通過し、書込みが計画どおり処理され、新名称が空いていると確認した場合だけ候補になります。15 秒は例であり、実際の値は変更計画から決めます。

SET SESSION lock_wait_timeout = 15;

RENAME TABLE app_live.customer_order_legacy
TO app_live.customer_order;

同じ対象に等価な ALTER TABLE を後から実行してはいけません。ランブックで単一テーブルの ALTER TABLE を明示的に選んだ場合の審査候補は次です。

SET SESSION lock_wait_timeout = 15;

ALTER TABLE app_live.customer_order_legacy
RENAME TO app_live.customer_order;

二つのブロックから一つだけを選びます。成功、失敗、タイムアウトのどの場合も、正確なエラーとオブジェクト状態を記録してから次へ進み、すぐ再試行しません。複数テーブルの交換では、全名称を包括的に審査した一つの RENAME TABLE に入れ、すべてのエンジン、ロック、依存関係、移動先名称を再確認します。別々の単一テーブル DDL は原子的トランザクションではありません。

検証を COUNT(*) だけに依存させない

まず新名が存在し旧名が存在しないことを証明し、定義を再取得します。information_schema.tables.table_rows と正確な行数が違うだけで警告してはいけません。一部エンジンでは推定値です。無条件の COUNT(*) も既定の検証にしません。高コストになり得るうえ、インデックス、制約、権限、利用側、レプリケーションの正しさを証明しません。

SELECT table_schema, table_name, table_type, engine
FROM information_schema.tables
WHERE table_schema = 'app_live'
  AND table_name IN ('customer_order_legacy', 'customer_order')
ORDER BY table_name;

SHOW CREATE TABLE app_live.customer_order;
SHOW INDEX FROM customer_order FROM app_live;

変更前後の正規定義、インデックス、外部キー、トリガーの証拠を比較します。承認済みのアプリケーション読取り経路、ビュー、ジョブ、監視、バックアップ検出、すべてのレプリカを検証します。既知で機密性のないインデックスキーがある場合は有界な確認を使えます。例の列名を確認済みの列に置き換え、未知の大規模テーブルを走査しないでください。

SELECT order_id, created_at
FROM app_live.customer_order
ORDER BY order_id
LIMIT 5;

業務が承認したテストデータ、冪等性、後始末がすべて定義されている場合だけ書込み canary を行います。このガイドでは汎用的な書込み文を意図的に示しません。検証出力の機密情報を除き、単一クエリの成功ではなく、注文量、エラー率、遅延、レプリケーション遅延、既存の業務検査を組み合わせて判断します。

ロールバックも制御対象の DDL 操作である

ロールバック前に利用側を再び停止またはドレインします。app_live.customer_order が直前に改名した正確なオブジェクトのままで、旧名が空いており、他の schema 変更や並行復元がなく、アプリケーション設定を戻せることを確認します。その後にだけ、次の逆向き候補を審査します。

SET SESSION lock_wait_timeout = 15;

RENAME TABLE app_live.customer_order
TO app_live.customer_order_legacy;

ロールバックも暗黙コミットし、権限とメタデータロックが必要で、タイムアウトし得ます。完了後は検証全体を繰り返して旧利用側を戻します。旧名が再作成された、切替後に構造変更があった、schema 間移動をした、レプリケーションが分岐した、オブジェクトの同一性が不確かな場合は、上書きや連続改名をしません。書込み停止を維持し、DBA 承認済みの復旧ポイントまたは専用復旧計画を使います。

停止してエスカレーションする条件

次のいずれかに該当すれば DDL を止め、DBA、プラットフォーム所有者、アプリケーション所有者へエスカレーションします。

  • 正確なディストリビューション、バージョン、エンジン、マネージドサービス制限、schema、オブジェクト種別を確認できない。
  • 移動先が既に存在する、または旧名と新名の大小文字が対象環境やレプリカで異なる意味になる。
  • トリガー付きテーブルを schema 間移動する計画、未処理のビューまたはストアドプログラム依存、所有者不在の動的 SQL がある。
  • テーブルまたは列権限、definer、アプリケーション ID、最小権限再作成計画が不完全である。
  • バックアップが古い、復元が未検証、復旧ポイントまたは責任者が不明である。
  • 未知の長時間トランザクション、メタデータロック待ち、レプリケーションフィルターや遅延、CDC 滞留、バックアップ競合、プラットフォーム警告がある。
  • 書込みを停止または調整できない、アプリケーションとジョブを同一時間帯に切り替えられない、検証済みロールバック版がない。
  • DDL がタイムアウト、エラー、接続切断、状態不明になった。まずオブジェクト状態を再照会し、決して盲目的に再試行しない。
  • 定義、インデックス、外部キー、トリガー、権限、アプリケーション canary、レプリケーション、監視のいずれかが検証で一致しない。

公式資料

以上の公式リンクは 2026-09-01 に確認しました。実行前には、正確なサーバーバージョンとマネージド提供者の対応資料へ切り替えてください。

歴史的な原文アーカイブ(現行ランブックではありません)

以下に source_export の可視本文を完全に保存します。原文には行末空白がなく、安全性、プライバシー、追跡情報に関する墨消しも不要だったため、正規化も省略もしていません。これは MySQL 5.0 時代の短い構文メモにすぎず、本番依存関係、ロック、権限、バックアップ、検証、ロールバックの境界がありません。外側を 4 個のバッククォートで囲み、原文内の 3 個のバッククォートを不活性なテキストとして保持しています。

在mysql中修改表名的SQL语句


在使用mysql时,经常遇到表名不符合规范或标准,但是表里已经有大量的数据了,如何保留数据,只更改表名呢?
 可以通过建一个相同的表结构的表,把原来的数据导入到新表中,但是这样视乎很麻烦。

能否简单使用一个SQL语句就搞定呢?当然可以,mysql5.0下我们使用这样的SQL语句就可以了。

Alter TABLE table_name RENAME TO new_table_name

例如:

Alter TABLE admin_user RENAME TO a_user

Leave a Reply