2026年8月3日

2026年8月3日

MySQLデータベースを別サーバーへ移行する手順|mysqldumpでの書き出し・取り込み・確認

データベースを別のサーバーへ移す方法はいくつかありますが、数GB程度までのMySQL・MariaDBなら、mysqldump でSQLファイルに書き出し、移行先で読み込む方法がもっとも手順が少なく、バージョンが違うサーバーの間でも使えます。この記事では、移行前の確認から、書き出し、転送、取り込み、照合、アプリの切り替えまでを順に説明します。MySQL 8.0・8.4とMariaDB 10.6以降を前提にしています(2026年10月時点)。

例では、移行元と移行先のデータベース名を wpdb、アプリ用のユーザーを wpuser とします。

移行前に確認すること

移行元と移行先で、次の項目を確認しておきます。

-- サーバーの種類とバージョン
SELECT VERSION();

-- データベースの文字コードと照合順序
SELECT default_character_set_name, default_collation_name
FROM information_schema.schemata WHERE schema_name = 'wpdb';

-- データベースの大きさ(MB)とストレージエンジン
SELECT engine, COUNT(*) AS tables,
       ROUND(SUM(data_length + index_length) / 1024 / 1024) AS size_mb
FROM information_schema.tables WHERE table_schema = 'wpdb'
GROUP BY engine;
  • 移行先のバージョンが移行元より古い、またはMySQLからMariaDBへ移す場合は、照合順序などで取り込みエラーが出ることがあります(後述)
  • 移行先のディスクに、データベースの大きさとダンプファイルを置ける空きがあるか
  • 移行中に書き込みが入ると、その分は移行先に入りません。アプリを止めるかメンテナンス表示にする時間を決めておきます

mysqldumpで書き出す

パスワードをコマンドラインに書くと、ほかのユーザーからプロセス一覧で見えたり、シェルの履歴に残ったりします。-p だけを付けて対話で入力するか、オプションファイルを使います。

# 自分だけが読めるオプションファイルを作る(パスワードは自分のものに置き換える)
cat > ~/.migrate.cnf << 'EOF'
[client]
user=root
password=パスワード
EOF
chmod 600 ~/.migrate.cnf

書き出します。--defaults-extra-file は最初のオプションとして書きます。

mysqldump --defaults-extra-file=~/.migrate.cnf \
  --single-transaction \
  --routines --triggers --events \
  --default-character-set=utf8mb4 \
  --no-tablespaces \
  --databases wpdb | gzip > wpdb_$(date +%Y%m%d%H%M).sql.gz
オプション 意味
--single-transaction InnoDBのテーブルを、書き出し開始時点のそろった状態で書き出す。テーブルをロックしないので、書き出し中もアプリは動く
--routines --events ストアドプロシージャ・関数とイベントも書き出す(既定では含まれない)
--triggers トリガーを書き出す(既定で有効。明示しておくと意図がわかる)
--default-character-set=utf8mb4 文字化けを防ぐため、接続の文字コードを指定する
--no-tablespaces 表領域の情報を書き出さない。MySQL 8.0.21以降は、これを付けないと PROCESS 権限の無いユーザーでエラーになる
--databases wpdb CREATE DATABASE と USE 文を含めて書き出す。付けない場合は、取り込み時にデータベース名を指定する

--single-transaction がそろった状態を保証するのはInnoDBのテーブルだけです。MyISAMのテーブルが残っている場合は、書き出しの間アプリを止めてください。

環境によって必要なオプション

  • MySQLでGTIDを有効にしている場合: ダンプにGTIDの設定文が入り、移行先で取り込めないことがあります。レプリケーションを組むのでなければ --set-gtid-purged=OFF を付けます
  • MySQL 8.0以降の mysqldump で、MySQL 5.7やMariaDBのサーバーから書き出す場合: Unknown table 'COLUMN_STATISTICS' というエラーが出たら --column-statistics=0 を付けます
  • MariaDB 10.5以降は mariadb-dump と mariadb が正式なコマンド名です。mysqldump や mysql という名前が入っていない環境では、こちらの名前で同じオプションを使います(MySQL固有の --set-gtid-purged と --column-statistics は除く)

移行先へ転送する

scp や rsync で転送し、転送前後でチェックサムを比べます。

# 移行元で
sha256sum wpdb_202610311200.sql.gz
scp wpdb_202610311200.sql.gz admin@203.0.113.20:/tmp/

# 移行先で(移行元と同じ値になることを確認する)
sha256sum /tmp/wpdb_202610311200.sql.gz

ダンプファイルにはデータベースの中身がすべて入っています。個人情報を含む場合は、作業が終わったら移行元・移行先の両方から削除してください。

移行先でデータベースとユーザーを作る

移行先のサーバーで、管理者としてログインして作業します。--databases を付けて書き出した場合は、ダンプの中の CREATE DATABASE でデータベースが作られますが、文字コードと照合順序を自分で指定したい場合は先に作っておきます。

CREATE DATABASE IF NOT EXISTS wpdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'アプリ用のパスワード';
GRANT ALL PRIVILEGES ON wpdb.* TO 'wpuser'@'localhost';

照合順序は、移行元で確認したものに合わせます。移行元がMySQL 8.0の既定(utf8mb4_0900_ai_ci)で、移行先もMySQL 8.0以降なら、そのままでかまいません。ユーザーのホスト部分(localhost など)は、移行先でアプリが接続してくる場所に合わせます。

取り込む

gunzip < /tmp/wpdb_202610311200.sql.gz | mysql --defaults-extra-file=~/.migrate.cnf --default-character-set=utf8mb4

--databases を付けずに書き出したファイルの場合は、取り込み先のデータベース名を最後に指定します。

gunzip < /tmp/wpdb_202610311200.sql.gz | mysql --defaults-extra-file=~/.migrate.cnf --default-character-set=utf8mb4 wpdb

よくあるエラー

エラー 原因と対処
Unknown collation: 'utf8mb4_0900_ai_ci' MySQL 8.0以降のダンプを、この照合順序を持たないMariaDBやMySQL 5.7に取り込んだ。ダンプ内の照合順序を置き換えてから取り込む(下のコマンド)
Access denied; you need (at least one of) the SUPER ... privilege(s) ビュー・トリガー・ストアドプロシージャの DEFINER に、移行先に無いユーザーや、自分以外のユーザーが指定されている。移行先に同じユーザーを作ってから管理者で取り込むか、DEFINER を取り込むユーザーに合わせる
Got a packet bigger than 'max_allowed_packet' bytes 1つの行やINSERT文がサーバーの上限を超えた。移行先の [mysqld] の max_allowed_packet を大きくして再起動する(例: 256M)
ERROR 1046 (3D000): No database selected --databases を付けずに書き出したファイルを、データベース名を指定せずに取り込んだ
# 照合順序を置き換える(展開してから置き換え、元のファイルは残す)
gunzip -c /tmp/wpdb_202610311200.sql.gz > /tmp/wpdb.sql
sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' /tmp/wpdb.sql
mysql --defaults-extra-file=~/.migrate.cnf --default-character-set=utf8mb4 < /tmp/wpdb.sql

DEFINER に指定されたユーザーと異なるユーザーで取り込むには、MySQLでは SUPER か SET_USER_ID(MySQL 8.2以降は SET_ANY_DEFINER)の権限が必要です。移行先でもアプリと同じユーザー名・ホストのアカウントを先に作っておくと、この問題は起きにくくなります。

移行できたかを照合する

テーブルの数と、各テーブルの行数を、移行元と移行先で比べます。information_schema.tables の table_rows はInnoDBでは概算値なので、正確に比べるには COUNT(*) を使います。

# 移行元・移行先の両方で実行し、出力を diff で比べる
for t in $(mysql --defaults-extra-file=~/.migrate.cnf -N -e "SHOW TABLES" wpdb); do
  echo "$t $(mysql --defaults-extra-file=~/.migrate.cnf -N -e "SELECT COUNT(*) FROM \`$t\`" wpdb)"
done > counts_$(hostname).txt

ストアドプロシージャやトリガーを使っている場合は、移行先でも存在するかを確認します。

SHOW TRIGGERS FROM wpdb;
SHOW PROCEDURE STATUS WHERE Db = 'wpdb';
SHOW FUNCTION STATUS WHERE Db = 'wpdb';

アプリを切り替える

  1. アプリをメンテナンス表示にするなどして、移行元への書き込みを止める
  2. 最後のダンプを取り、転送して取り込み、照合する
  3. アプリの接続先(ホスト名、ユーザー名、パスワード)を移行先に変える
  4. 動作を確認してから、メンテナンス表示を解除する

移行元のサーバーは、問題が出たときに戻せるよう、しばらく残しておきます。

WordPressの場合は、wp-config.php の DB_NAME、DB_USER、DB_PASSWORD、DB_HOST を移行先の値にします。サイトのドメインも変わる場合は、データベース内のURLを wp search-replace で置き換えます。手順は下の関連記事を参照してください。

大きなデータベースの場合

数十GBを超えると、mysqldump の書き出しと取り込みには時間がかかります。並列で処理できるツールとして、MySQL ShellのダンプユーティリティやMydumperがあります。また、同じ種類・同じ系列のバージョンの間なら、レプリケーションで移行先に同期してから切り替えると、停止時間を短くできます。いずれも、使っているバージョンの公式ドキュメントで手順を確認してください。

まとめ

  • 移行前に、バージョン、文字コードと照合順序、大きさ、停止できる時間を確認する
  • mysqldump --single-transaction --routines --triggers --events --no-tablespaces で書き出し、パスワードはオプションファイルで渡す
  • 転送したらチェックサムを比べ、移行先で文字コードを合わせたデータベースとユーザーを作ってから取り込む
  • 照合順序、DEFINER、max_allowed_packet のエラーはよく出るので、対処を知っておく
  • テーブルごとの COUNT(*) を比べてから、アプリの接続先を切り替える

関連記事:

お気軽にご相談ください

お見積りへ お問い合わせへ
▲