1 rds_dbsync (推薦使用)
《MySQL準實時同步到PostgreSQL, Greenplum的方案之一 - rds_dbsync》
這個效率最高,支持不落地,支持流式導入,支持單表併發(通過配置文件,寫WHERE條件,拆成多個併發導同一張表)。
用法
以CentOS 7.x x64爲例。
mysql2pgsql已打包所有依賴包,可以不安裝pgsql和mysql。不過你如果想連接數據庫做一些管理工作、或者排錯等,還是有必要安裝一下。
1、pgsql
《PostgreSQL on Linux 最佳部署手冊 - 珍藏級》
《PostgreSQL 10 on ECS 實施 流複製備庫鏡像+自動快照備份+自動備份驗證+自動清理備份與歸檔 - 珍藏級》
《PostgreSQL 10 + PostGIS + Sharding(pg_pathman) + MySQL(fdw外部表) on ECS 部署指南(適合新用戶) - 珍藏級》
-
su - digoal
-
vi .bash_profile
-
export PS1="$USER@`/bin/hostname -s`-> "
-
export PGPORT=1921
-
export PGDATA=/data01/pg/pg_root$PGPORT
-
export LANG=en_US.utf8
-
export PGHOME=/home/digoal/pgsql11
-
export LD_LIBRARY_PATH=$PGHOME/lib:/lib64:/usr/lib64:/usr/local/lib64:/lib:/usr/lib:/usr/local/lib:$LD_LIBRARY_PATH
-
export PATH=$PGHOME/bin:$PATH:.
-
export DATE=`date +"%Y%m%d%H%M"`
-
export MANPATH=$PGHOME/share/man:$MANPATH
-
export PGHOST=$PGDATA
-
export PGUSER=postgres
-
export PGDATABASE=postgres
-
alias rm='rm -i'
-
alias ll='ls -lh'
-
unalias vi
2、mysql
https://dev.mysql.com/downloads/repo/yum/
https://dev.mysql.com/doc/mysql-yum-repo-quick-guide/en/
-
su - root
-
vi /etc/yum.repos.d/mysql.repo
-
[mysql57-community]
-
name=MySQL 5.7 Community Server
-
baseurl=http://repo.mysql.com/yum/mysql-5.7-community/el/7/$basearch/
-
enabled=1
-
gpgcheck=0
-
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
yum install -y mysql-community-server.x86_64 mysql-community-devel.x86_64
3、rds_dbsync
詳細配置文檔參考
-
./mysql2pgsql --help
-
ignore copy error count 0 each table
-
Unsupported option: -Usage: -l <table list file> -j <thread number> -d -n -f -s -b -h
-
-l specifies a file with table listed;
-
-j specifies number of threads to do the job;
-
-d means get DDL only without fetching data;
-
-n means no partion info in DDLs;
-
-f means taking first column as distribution key;
-
-s specifies the target schema;
-
-b specifies the buffer size in KB used to sending copy data to target db, the default is 0
https://github.com/aliyun/rds_dbsync/blob/master/doc/mysql2pgsql_ch.md
https://github.com/aliyun/rds_dbsync/releases
-
wget https://github.com/aliyun/rds_dbsync/files/1555186/mysql2pgsql.bin.el7.20171213.zip
-
unzip mysql2pgsql.bin.el7.20171213.zip
4、rds_dbsync 將mysql遷移到pgsql
確保執行mysql2pgsql的機器,可以同時連接到mysql, pgsql.
如果無法直接互聯,可以使用SSH打通隧道進行互相訪問。
1、配置my.cfg文件,源(mysql)、目標(pgsql)
-
cd mysql2pgsql.bin.el7.20171213
-
cd bin
-
vi my.cfg
-
[src.mysql]
-
host = "數據庫IP"
-
port = "數據庫PORT"
-
user = "數據庫user"
-
password = "數據庫user密碼"
-
db = "數據庫名"
-
encodingdir = "share"
-
encoding = "utf8"
-
[desc.pgsql]
-
connect_string = "host=127.0.0.1 port=1921 dbname=postgres user=postgres password=pgsql"
-
target_schema = "public"
如果postgresql在本地,可以使用unix socket連接,導入性能比tcp要快一點。例如
connect_string = "host=/tmp dbname=postgres port=1921 user=postgres password=pgsql"
unix socket dir配置可從配置文件讀取
-
postgres=# show unix_socket_directories ;
-
unix_socket_directories
-
-------------------------
-
/tmp,.
-
(1 row)
2、生成mysql 轉換爲pgsql 的建表 DDL
./mysql2pgsql -d > ddl.sql
3、執行輸出的DDL文件
在pgsql對應的數據庫中,執行第二步生成的DDL語句,創建目標表。
psql -f ./ddl.sql -1
如果有問題,需要手工修復一下。
遷移例子
1、全量遷移
-
cd mysql2pgsql.bin.el7.20171213/bin
-
nohup ./mysql2pgsql >./load.log 2>&1 &
2、選擇性遷移
如果不想遷移所有表的數據,或者某些表只想遷移部分數據,可以寫配置文件。
2.1、甚至可以多個源寫入單個表,例如多個MYSQL節點數據,匯入單個PG節點。
2.2、如果源表與PG的目標表名字不一樣,可以在配置文件中映射表名。(冒號分隔:第一列爲mysql裏面的表名,第二列爲MYSQL裏面的表名,或者QUERY)
-
vi lo.txt
-
tbl1
-
tbl2 : select * from tbl_from_mysql where id<10000;
-
tbl2 : select * from tbl_from_mysql where id >= 100000 and id< 10000000;
-
tbl3 : tbl_from_mysql_1
-
tbl3 : tbl_from_mysql_2
然後執行
-
cd mysql2pgsql.bin.el7.20171213/bin
-
nohup ./mysql2pgsql -l ./lo.txt >./load.log 2>&1 &
3、並行遷移
默認爲5個遷移線程操作(每個線程COPY一張表),通過-j參數指定。
-
cd mysql2pgsql.bin.el7.20171213/bin
-
nohup ./mysql2pgsql -l ./lo.txt -j 8 >./load.log 2>&1 &
4、單表如何支持並行遷移
單表,通過where條件分段,可以實現單表的並行遷移(但是幾個SQL分開執行,他們的SNAPSHOT不一樣,不滿足全局一致性)
-
vi lo.txt
-
tbl2 : select * from tbl_from_mysql where id < 1000000;
-
tbl2 : select * from tbl_from_mysql where id >= 1000000 and id < 2000000;
-
tbl2 : select * from tbl_from_mysql where id >= 2000000 and id < 3000000;
-
tbl2 : select * from tbl_from_mysql where id >= 3000000;
-
cd mysql2pgsql.bin.el7.20171213/bin
-
nohup ./mysql2pgsql -l ./lo.txt -j 4 >./load.log 2>&1 &
2 mysql_fdw
《PostgreSQL 10 + PostGIS + Sharding(pg_pathman) + MySQL(fdw外部表) on ECS 部署指南(適合新用戶) - 珍藏級》
https://github.com/EnterpriseDB/mysql_fdw
http://blog.163.com/digoal@126/blog/static/1638770402011111233524987/
http://blog.163.com/digoal@126/blog/static/163877040201493145214445/
3 mysql
通過管道導入
-
export PGHOST=
-
export PGPORT=
-
export PGDATABASE=
-
export PGUSER=
-
export PGPASSWORD=
-
nohup mysql -C -h主機 -P端口 -u用戶 -p密碼 庫 -B -e "select * from 表" | psql -c "copy 表 from stdin with (format csv, HEADER true, null 'NULL', DELIMITER E'\t')" > /dev/null 2>&1 &
如果表很大,可能OOM,因爲需要將數據完全HOLD到mysql客戶端後,纔開始輸出。暫不清楚mysql客戶端有沒有流式輸出的功能。
4 mysqldump
通過管道導入
-
export PGHOST=
-
export PGPORT=
-
export PGDATABASE=
-
export PGUSER=
-
export PGPASSWORD=
-
mysqldump 庫名 -t -h主機 -P端口 -u用戶 -p密碼 --no-create-db --skip-quote-names --skip-add-locks --skip-lock-tables --skip-tz-utc -y --default-character-set=UTF8 -C --compact --compatible=postgresql --tables 表 | psql -f - >/dev/null 2>&1 &
如果在mysql服務器上運行,可以dump CSV格式。
MySQL沒有像PostgreSQL這樣的COPY to stdout或COPY from stdin這樣的COPY協議,只有服務端COPY。
mysqldump有一些格式問題(即使使用--compatible=postgresql),可能導致數據導入到PG時出錯。
參考
man mysql
man mysqldump