データベース
PR

【MySQL】複数のSQLファイルを順に自動実行する安全な方法と活用例

saratogax
記事内に商品プロモーションを含む場合があります

データベースの移行作業や初期データの投入といった場面で、複数の SQL ファイルを MySQL に流し込む必要があるケースは少なくありません。

特に、大量の INSERT 文がファイル単位で分かれている場合、1つずつ手動で mysql コマンドに渡すのは非効率で、ミスの温床にもなります

この記事では、複数の SQL ファイルを自動かつ安全に MySQL に実行していく方法について解説します。

Unix系シェル環境で利用可能な find, xargs, mysql コマンドを組み合わせることで、再現性と保守性の高いデータ投入フローを構築できます。

今回は、複数の AWS アカウント間で、データを移行したい場面に遭遇したので、即席で mysqldump したデータを移行してみました。

複数の SQL ファイルを対象にしたい理由とは

たとえば、以下のようなシナリオを想定してみましょう。

  • 初期データをカテゴリー別・テーブル別にファイルに分けて管理している
  • アプリケーションの開発環境を毎回同じ状態に初期化したい
  • データマイグレーションにおいて、処理順序を意識しつつ段階的に投入したい

このような場合、1ファイルずつ mysql -u user -p database < file.sql を繰り返すのは現実的ではありません。

そこで、SQL ファイル群を自動で読み取り、1つずつ mysql に流し込むバッチ的な処理が役立ちます。

安全に、順番どおりに実行する方法

ポイントは「実行順を固定すること」と「途中で失敗したら止めること」の 2 つです。

もっともシンプルなのは、シェルの for ループでソート順に流す方法です。

#!/bin/bash
set -e   # どれか1つでも失敗したら止める

for f in /path/to/sql_dir/*.sql; do
    echo "== $f =="
    mysql --defaults-file=/path/to/.my.cnf your_database < "$f"
done

*.sql のグロブはアルファベット順に展開されるので、10_users.sql20_orders.sql のように連番のプレフィックスを付けておけば、実行順を固定できます。

set -e を付けておくと、途中の 1 ファイルで失敗した時点で処理が止まるため、中途半端な状態でデータが入るのを防げます。

サブディレクトリも対象にしたい場合(find 版)

再帰的にファイルを集めたい場合は find を使いますが、その場合も並び順をそろえます。

find /path/to/sql_dir -type f -name '*.sql' -print0 | sort -z | xargs -0 -I{} sh -c 'mysql --defaults-file=/path/to/.my.cnf your_database < "$1"' _ {}

-print0(NULL 区切り)に合わせて sort -z で並べ替えるのがポイントです(通常の sort は NULL 区切りをうまく扱えません)。

また、ファイル名を sh -c の文字列に直接埋め込まず、末尾の _ {} で位置引数 $1 として受け取ることで、特殊文字を含むファイル名でも安全に処理できます。

--defaults-file で認証情報を .my.cnf に分離しておく点は、どちらの方法でも共通のセキュリティ上のポイントです。

実務での活用例

この手法は、以下のような用途に非常に有効です:

  • 開発環境の初期セットアップ
    各テーブルやモジュールごとに分けた .sql ファイルを順に投入することで、整合性の取れた初期状態を簡単に再現できます。
  • 段階的なデータ移行
    古いシステムからのデータエクスポートをファイル単位で整理し、そのまま新しい環境へ順次移行するフローに組み込めます。
  • 運用タスクの自動化
    毎月定例で投入するマスターデータやテンプレート情報などを .sql にしておけば、自動で実行する仕組みを簡単に構築できます。

失敗しないための注意点

  • 実行順は連番プレフィックスで固定できます(find 版では -print0 に合わせて sort -z を併用)。
  • MySQL のエラー出力を確認したい場合は、--verbose --show-warnings オプションを付けることでログが見やすくなります。
  • .my.cnf ファイルのパーミッション600 に設定することで、認証情報の漏洩リスクを防げます。

まとめ

複数の SQL ファイルを MySQL に順番に投入する必要がある場面では、findxargs を組み合わせたワンライナーが非常に強力です。

安全性を確保しつつ、手作業を最小化できるため、開発・運用の効率が大きく向上します。

とくに .my.cnf による認証情報の分離は、セキュアな運用にも寄与する重要なポイントです。

SQL ファイルの処理が必要なワークフローに、この方法をぜひ取り入れてみてください。

mysqldump で取得したデータを別 DB に取り込む際、AUTO_INCREMENT の ID が衝突して困る場合は、mysqldumpでバックアップしたデータを別DBに安全に取り込む方法【IDずらし対応】もあわせてどうぞ。

mysqldump まわりの警告への対処は、以下の記事でまとめています。

あわせて読みたい
MySQL8.0.34でmysqldumpで「A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions」の警告
MySQL8.0.34でmysqldumpで「A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions」の警告
ABOUT ME
saratoga
saratoga
フリーランスエンジニア
仕事にも趣味にも IT を駆使するフリーランスエンジニア。技術的な TIPS や日々の生活の中で深堀りしてみたくなったことを備忘録として残していきます。
記事URLをコピーしました