MySQL
postgres

PostgreSQLのデータをMySQLに移行する

More than 3 years have passed since last update.

長くアプリケーションをメンテナンスしているうちに、データベースを別の環境に移行する機会もあるかと思います。私が経験したPostgreSQLからMySQLへの移行における手順を示しておきます。

このシステムは下記のような特徴を持っているため、かなり簡単な部類に入るかと思います。


  • データをバッチで突っ込む以外に更新は無い

  • TRIGGERは使わない

  • VIEWは使わない

  • それらしい機能は全然使わない

機能も大したこと無い、それゆえに制限も無いということで、データベース・エンジンはMyISAMにしました。テーブルの関連付けは移行しないということです。関連付けも移行する場合はまた別途手順が必要になるでしょう。


PostgreSQLのデータをエクスポートする

PostgreSQLの付属のプログラムpg_dumpを使います。ここでは、ダンプするデータベースの名前をdb1としておきます。この時、後の作業のためにデータとスキーマを別々に出力します。

$ pg_dump --data-only --no-owner --no-privileges --disable-dollar-quoting db1 > /var/tmp/dump_data.sql

$ pg_dump --schema-only --no-owner --no-privileges --disable-dollar-quoting db1 > /var/tmp/dump_schema.sql


MySQLにデータをインポートする

インポートするためには、ダンプしたファイルを多少加工する必要があります。


schemaファイルの修正

互換性のない部分を手作業で修正します。下記のような対処をしないとSyntax Errorが起きたりします。


  • 先頭のSET構文を削除します。

  • ALTER TABLE ONLY … のONLYを削除します。

  • CREATE INDEX … ON table_name USING btreeはUSING btreeをONの前に移動します。

参考:

修正したら下記の通りインポートします。

$ mysql -h database.example.com -u root -p db1 < dump_schema.sql

エラーが出ていなければ成功です(たぶん)。


dataファイルの修正

pg_dumpではデータをCOPYステートメントでインポートするように記述されているのですが、MySQLにはCOPYが無いようです。COPYステートメントは、その宣言の後にタブ区切りでデータを並べ、\.で示されるデータの終端までをインサートするというシンプルな構文です。そのため、多少の加工で対応できるLOAD DATA INFILE構文でインポートすることにします。

データの加工には即席のプログラムを作って対応しました。

下記のように実行します。

$ conv-pg_dump-tsv.pl dump_data.sql

ダンプファイルがテーブル毎にTSVとしてdataディレクトリ配下に出力されます。出力されたTSVファイルをmysqlimportでインポートします。

$ mysqlimport --local -h database.example.com -u root -p db1 data/*

インポートするテーブルが空の場合は、LOAD DATA INFILEは最適化を自動的に実行するそうですので、データ量がそれなりに有っても結構速いです。

参考: