|
MySQL을 PostgreSQL 로 이관하는 방법은 PostgreSQL에서 제공하는 기능인 pgloader 를 사용하면 오브젝트부터 데이터까지 쉽게 이관할 수 있지만
반대인 PostgreSQL -> MySQL 은 적당한 툴도 없고, 두 DB의 schema 개념도 달라 사전에 알아둬야 할 점이 많습니다.
이번에 이관했던 서비스를 예시로 PostgreSQL => MySQL 이관 방법을 정리해보았습니다.
PostgreSQL 과 MySQL schema 차이
amon=# \dn List of schemas Name | Owner --------------------+-------------- information_schema | testuser pg_catalog | testuser pg_toast | testuser pg_toast_temp_1 | testuser public | testuser (5 rows) => public 을 제외한 나머지 schema는 시스템 관련 스키마, pulic은 모든 schema가 접근 가능한 default schema test=# select count(*) from information_schema.tables where table_schema='public'; count ------- 100 (1 row)
=> 해당 서비스에서는 다른 서비스용 schema 를 생성하지 않고 기본 public schema에 오브젝트를 생성하였음
이관대상 확인databasepostgres=# \l+ List of databases Name | Owner | Encoding | Collation | Ctype | Access privileges | Size | Tablespace | Description -----------+--------------+----------+------------+------------+-----------------------------------+---------+------------+--------------------------- test1 | testuser | UTF8 | en_US.UTF8 | en_US.UTF8 | | 13 MB | pg_default | test2 | testuser | UTF8 | en_US.UTF8 | en_US.UTF8 | | 172 MB | pg_default | : template0 | postres | UTF8 | en_US.UTF8 | en_US.UTF8 | =c/"testuser" | 5408 kB | pg_default | : "testuser"=CTc/"testuser" template1 | postgres | UTF8 | en_US.UTF8 | en_US.UTF8 | =c/"testuser" | 5408 kB | pg_default | default template database : "testuser"=CTc/"testuser"
schematest1=# \dn List of schemas Name | Owner --------------------+-------------- information_schema | testuser pg_catalog | testuser pg_toast | testuser pg_toast_temp_1 | testuser public | testuser (5 rows) test1=# select count(*) from information_schema.tables where table_schema='public'; count ------- 100 (1 row) test1=# \dn List of schemas Name | Owner --------------------+-------------- information_schema | testuser pg_catalog | testuser pg_toast | testuser pg_toast_temp_1 | testuser public | testuser (5 rows) test2=# select count(*) from information_schema.tables where table_schema='public'; count ------- 84 (1 row) userpostgres=# select * from pg_catalog.pg_roles; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcatupdate | rolcanlogin | rolconnlimit | rolpassword | rolvaliduntil | rolconfig | oid --------------+----------+------------+---------------+-------------+--------------+-------------+--------------+-------------+---------------+-----------+------- testuser | t | t | t | t | t | t | -1 | ******** | | | 10 . . pg2mysql
PostgreSQL dump 파일을 MySQL 쿼리로 변환해주는 툴로 더이상 개발되지 않아 실사용 하기위해 몇가지 부분을 추가하였음
pg2mysql 이슈 및 수정사항
사용방법
$ php --version PHP 5.3.3 (cli) (built: Mar 22 2017 12:27:09)
$ ls -ltr total 44 -rw-r--r-- 1 irteam irteam 15145 May 26 2006 gpl.txt -rw-r--r-- 1 irteam irteam 2370 Jul 21 2011 pg2mysql.php -rw-r--r-- 1 irteam irteam 1534 Jul 21 2011 pg2mysql_cli.php -rw-r--r-- 1 irteam irteam 2985 Jul 21 2011 README -rw-rw-r-- 1 irteam irteam 13204 Aug 10 20:44 pg2mysql.inc.php.org -rw-r--r-- 1 irteam irteam 13235 Aug 10 20:44 pg2mysql.inc.php
### schema only pg_dump -p port -U username -S dbname --format p -f dbname_schema.sql ### data only, insert 구문으로 pg_dump -p port -U username -a dbname --inserts --format p -f dbname_data.sql ### schema+ data pg_dump -p port -U username dbname --inserts --format p -f dbname_full.sql
php pg2mysql_cli.php dbname_full.sql mysql_dbname.sql 데이터 검증 (count 확인)
#!/bin/bash database=database_name user=postgres echo "Database : $database" PGCOMMAND=" psql -U $user -d $database -At -c \" SELECT table_name FROM information_schema.tables WHERE table_type='BASE TABLE' AND table_schema='public' \"" TABLENAMES=$(export PGPASSWORD=패스워드; eval "$PGCOMMAND") for TABLENAME in $TABLENAMES; do PGCOMMAND=" psql -U $user -d $database -At -c \" SELECT '$TABLENAME', count(*) FROM $TABLENAME \"" eval "$PGCOMMAND" done
#!/bin/bash database=database_name for name in `mys $database -B -e "show tables"`; do mys -B --vertical $database -e "select count(*) as $name from $name" | grep -v '^\*' | replace ": " "|" done
# MySQL select table_name,count(distinct index_name) from information_schema.STATISTICS where index_schema='amon' group by 1 order by 1; # PostgreSQL select tablename,count(*) from pg_indexes where schemaname='public' group by 1 order by 1;
=> MySQL로 변환되면서 Auto-increment 컬럼이 PK 가 되기 때문에 MySQL 이 인덱스가 더 많을 수 있음
|