閱讀889 返回首頁    go 阿裏雲 go 技術社區[雲棲]


從MySQL導出到PostgreSQL


異構
數據庫的導入、導出是一個大難題。從MySQL到PG目前沒有特別完善的工具,還需要人工的參與。本文將簡單介紹下如何利用一些工具,手工將MySQL導出數據到PostgreSQL。

導出、轉換、導入


數據導出、導入的思路是:

  1. 導出結構

  2. 導出數據

  3. 對結構進行轉換

  4. 對數據進行轉換

  5. 導入結構

  6. 導入數據

這裏的想法是將結構和數據分開處理,這樣有很多好處。首先DDL的語句的差別相比DML要大一些,比如各種類型的轉換、符號的變化等,分開之後可以針對性的處理;其次,DDL和DML分開更好做批量的處理;其他好處……

當前的開源轉換工具,尚沒有一個完善的。不同的工具分別做了些不同的轉換,因此本文將會利用多個工具互相配合使用,可以達到較好的效果。主要用到的工具有:

  1. mysql-postgresql-converter

    單個python腳本,依賴較少。對文件內容、格式的轉換,比較好的是enum類型改寫等。

  2. my2pg.pl

    單個perl腳本,依賴較少,會對數據類型做不錯的轉換。

  3. SED、VIM, 文本編輯神器,你懂得~

導出


導出主要采用的是mysql自帶的mysqldump,導出成sql文件的形式。這裏隻給出直接的例子,更多的參數請參考文檔(mysqldump --help)。

導出結構

/usr/local/mysql/bin/mysqldump --skip-opt --compatible=postgresql --compact --no-data --default-character-set=utf8 --skip-dump-date -u cvusr -p -h mysqlhostaddress cvdb > schm.sql

  • --no-data,故名思議,就是不帶數據

  • --compatible=postgresql, 盡量兼容PostgreSQL的語法的方式,至少能減少後麵一部分工作量

  • --default-character-set=utf8,編碼盡量與目標庫保持一致

  • 這裏有更多的說明

導出數據

/usr/local/mysql/bin/mysqldump --skip-opt --compatible=postgresql --compact --no-create-info --default-character-set=utf8 --skip-comments --skip-dump-date -u cvusr -p -h mysqlhost cvdb > data.sql

轉換


數據的導出是比較容易的,麻煩的地方在於將數據文件轉換成另一種數據庫可以采用的方式。在這個過程中,至少需要處理以下幾個問題,這裏有詳細的MySQL與PG的對比

在結構上

  1. 類型

    如mediumint、char等,其實PG是可以自定義類型,這個應該是細節的處理,現有工具已經能做的不錯。my2pg.pl工具可以完成得較好

  2. 語義轉換

    典型的,在MySQL中可以create table的時候對字段采用enum類型,在PG中就需要抽出來先建個enum數據類型。另外如UK、default value等。 這方麵,mysql-postgresql-converter可以滿足部分需求。

  3. 其他地方

在數據上:

  1. 格式

  2. '與"

  3. 默認值

  4. 其他地方

可以在PG上做如下設置:

backslash_quote = on

escape_string_warning = off

standard_conforming_strings = off

在mysqldump的時候,在建表語句中會有注釋,但發現幾個工具都去不掉,mysqldump的"--skip-comments"選項也沒起作用,百思不得姐之後決定手動處理:

sed -i "s/ COMMENT '.*',/ ,/g" schm.dump

sed -i "s/ COMMENT '.*',/ ,/g" data.dump

自動轉換

經過多次嚐試,發現沒有一個工具能夠將導出的結構處理的比較完善,使得可以直接在PG中導入。開了腦洞後嚐試工具的合作,主要是因為懶,不想手動改:

// 一些數據類型的修改,讀者可以自行作個對比。目前my2pg.pl做得比其他工具要好一些。 (但其將blob類型轉換成了text,需要注意,可以將腳本my2pg.pl中的“s/\w*blob$chareg/text/i; ”改為“s/\w*blob$chareg/bytea/i; ”

perl my2pg.pl  schm.dump  > my2pg-schm.dump

// enum類型改寫等,這個是上麵的工具沒有處理的,還有一些其他的

python mysql-postgresql-converter/db_converter.py schm.dump > db_cvtr-my2pg-schm.dump

這裏需要注意的是,這兩個工具的順序不能變,變了之後結果就不認識了。如果有興趣,可以嚐試下與其他工具的配合。

這還不是結束!這個時候,並不一定所有的類型都修改完全,可能還有一些需要手工處理,如:

特殊字符的處理:

SHELL$ vim mysql2pgsql-data.dump

:%s /\E'/E\'/g

——這裏是去除一些地方轉換出的問題,在插入語句中,"insert into tbl values(0, E\'0\')"會被處理成了"insert into tbl values(0, \E'0\')"。幸好隻是少數!

日期默認值:

'0000-00-00' 改為CURRENT_DATE,或者某固定日期等

——在MySQL中,日期'0000-00-00'值為空、或者無效,但這個日期不是正確日期,因此在PG中不支持。CURRENT_DATE是指當前時間。

其他的修改,也隻能見招拆招了。

數據導入

在轉換處理完成了之後,剩下的也就簡單了。依次導入結構和數據就好,如果有問題,隻能具體問題具體分析了。

結構導入

~/Workspace/pg94/bin/psql -h pghost -p 3432 -U cvusr -d cvdb -f schm.dump

數據導入

~/Workspace/pg94/bin/psql -h pghost -p 3432 -U cvusr -d cvdb -f data.dump

檢查、驗證


數據導進來了,不代表就結束了。因為不確定中間是否出了什麼幺蛾子。需要做一些驗證:

  1. 表結構、類型

  2. 記錄數

  3. 抽樣記錄

  4. 存儲過程就算了

  5. 編碼、亂碼的問題

  6. 其他差異地方的對比,如blob、clob等

針對這些做過檢查無誤之後,需要應用做相應的全麵的測試。

參考


  1. mysql-to-postgresql-migration-tips

  2. Converting_from_other_Databases_to_PostgreSQL

  3. Converting_MySQL_to_PostgreSQL

  4. mysql-postgresql-converter

  5. py-mysql2pgsql

  6. py-mysql2pgsql源碼

  7. mysqldump參數解釋

  8. Migrating from MySQL to PostgreSQL

最後更新:2017-04-01 13:39:23

  上一篇:go silverlight iis MIME 類型
  下一篇:go RDS MySQL參數調優最佳實踐