長くアプリケーションをメンテナンスしているうちに、データベースを別の環境に移行する機会もあるかと思います。私が経験した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の前に移動します。
参考:
- http://dev.mysql.com/doc/refman/5.1/ja/alter-table.html
- http://dev.mysql.com/doc/refman/5.1/ja/create-index.html
修正したら下記の通りインポートします。
$ 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は最適化を自動的に実行するそうですので、データ量がそれなりに有っても結構速いです。
参考: