查了不少資料,也嘗試了一些,最後采用的辦法如下:
1. 導出mysql表定義(無數據)
mysqldump --no-data [dbname] >dbdef.sql
2. 使用mysql2postgres把腳本轉換為pgsql
3. 上面生成的腳本還不一定很完美,可以嘗試導入pgsql,調試錯誤並手動修改之。我遇到的問題就只有一個,mysql列定義中的zerofill需要手工去掉。一些unsinged定義會生成constraint,如果不需要可以去掉。另外,trigger都有問題,只能後面手工重建
4. 導出mysql數據:
mysqldump -v -nt --complete-insert=TRUE --compact --no-create-info --skip-quote-names [dbname] >dbdata.sql
老一些版本的pgsql如果不支持批量插入的話還需要加上--extended-insert=FALSE,這個性能損失巨大。
5. 轉義符
mysql默認字符串裡的'\'是轉義符,而pgsql默認不是,修改postgresql.conf:
backslash_quote = on
escape_string_warning = off
standard_conforming_strings = off
數據導入完成後可以改回默認值。
5. pgsql裡導入表定義和數據
psql -d [dbname] <dbdef.sql
psql -d [dbname] <dbdata.sql
6. 重建trigger
7. 自增主鍵(字段)的處理
由於導入數據時此字段都是有值的,所以pgsql裡面seq並不會增加,可以用如下語句設置自增列的當前值:
SELECT setval('sample_id_seq',max(id)) from sample;
最後,如果數據量大,導入時考慮性能可以先把主鍵、索引、約束都去掉,導入完成後再加上。另外,psql客戶端從管道導入數據似乎不夠快,可以用tcp方式psql -h localhost ,還有一些為大數據量導入優化的參數,大概列一下:
autovacuum = off
wal_level = minimal
archive_mode = off
full_page_writes = off
fsync = off
checkpoint_segments = 50
checkpoint_timeout = 1h
maintenance_work_mem視內存情況盡量大點
作者 RuralHunter