```
作者:IT邦德
中国DBA联盟(ACDU)成员,10余年DBA工作经验
擅长主流数据Oracle、MySQL、PG、openGauss运维
备份恢复,安装迁移,性能优化、故障应急处理等
可提供技术业务:
1.DB故障处理/疑难杂症远程支援
2.Mysql/PG/Oracle/openGauss
数据库部署及数仓搭建
•••
微信:jem_db
QQ交流群:587159446
公众号:IT邦德
```
@[TOC](文章目录)
# 前言
>本文详细介绍了我的旅程、从Oracle迁移到PostgreSQL遇到的挑战,我希望分享这些经验将使你的PostgreSQL之旅更加顺利.
## 1.Ora2Pg介绍
```
Ora2Pg是我的第一个盟友。
它是一个开源工具,可将Oracle数据库模式转换为PostgreSQL格式。
可以处理大量的甲骨文对象
可通过配置文件进行配置
https://ora2pg.darold.net/
```

## 2.ora2pg安装
### 2.1 安装依赖包
```
yum install -y gcc perl-DBD-Pg perl perl-devel perl-DBI perl-CPAN bzip2 \
perl-ExtUtils-eBuilder perl-ExtUtils-MakeMaker perl-Time-HiRes perl-tests perf cpan
```
### 2.2 正式安装
```
perl -MCPAN -e 'install DBI'
perl -MCPAN -e 'install DBD::Oracle'
perl -MCPAN -e 'install DBD::Pg'
```

## 3.相关配置
### 3.1 表结构配置
```
cat > /etc/ora2pg/ora2pg_table_ddl.conf <<"EOF"
ORACLE_HOME /usr/lib/oracle/21/client64
ORACLE_DSN dbi:Oracle:host=172.18.12.90;sid=oradb;port=1521
#ORACLE_DSN dbi:Oracle:host=192.168.1.29;service_name=pdb1;port=1521
#ORACLE_DSN dbi:Oracle:tns_ora19c
ORACLE_USER system
ORACLE_PWD oracle
SCHEMA STEST
EXPORT_SCHEMA 1
CREATE_SCHEMA 1
TYPE TABLE
PG_NUMERIC_TYPE 0
PG_INTEGER_TYPE 1
DEFAULT_NUMERIC float
SKIP fkeys checks
#SKIP keys pkeys ukeys indexes checks
NLS_LANG AMERICAN_AMERICA.UTF8
OUTPUT_DIR /tmp
OUTPUT ora2pg_table_ddl.sql
PG_VERSION 14
EOF
```
### 3.2 表数据的配置文件
```
cat > /etc/ora2pg/ora2pg_table_data.conf <<"EOF"
ORACLE_HOME /usr/lib/oracle/21/client64
ORACLE_DSN dbi:Oracle:host=172.18.12.90;sid=oradb;port=1521
#ORACLE_DSN dbi:Oracle:tns_ora19c
ORACLE_USER system
ORACLE_PWD oracle
SCHEMA STEST
TYPE COPY
PG_NUMERIC_TYPE 0
PG_INTEGER_TYPE 1
DEFAULT_NUMERIC float
SKIP fkeys checks
#SKIP fkeys pkeys ukeys indexes checks
NLS_LANG AMERICAN_AMERICA.UTF8
OUTPUT_DIR /tmp
OUTPUT ora2pg_table_data.sql
PG_DSN dbi:Pg:dbname=jemdb;host=172.18.12.50;port=5432
PG_USER postgres
PG_PWD jeames
PG_SCHEMA stest
PG_VERSION 14
EOF
```
## 4.ora2pg迁移数据
### 4.1 迁移全部表结构
```
mkdir -p /ora2pg
ora2pg -c /etc/ora2pg/ora2pg_table_ddl.conf -t table -b /ora2pg
```

### 4.2 PG中创建数据
```
su - postgres
psql
CREATE USER STEST WITH password 'post' CREATEDB SUPERUSER replication createrole login;
create database jemdb;
alter database jemdb owner to STEST;
\c jemdb
-- 跑脚本
\i /ora2pg/ora2pg_table_ddl.sql
jemdb=# \d
```

### 4.3 迁移数据
```
ora2pg -d -t copy -c /etc/ora2pg/ora2pg_table_data.conf -P 12 -L 100000 -j 12
此过程执行完成后,数据就已经插入到PG数据库中了:
```
## 5.数据验证
```
su - postgres
psql
\c jemdb
emdb=# show search_path;
search_path
-----------------
"$user", public
(1 row)
jemdb=# set search_path=stest,public;
SET
jemdb=# \dt
List of relations
Schema | Name | Type | Owner
--------+----------------------+-------+----------
stest | addresses | table | postgres
stest | card_details | table | postgres
stest | customers | table | postgres
stest | inventories | table | postgres
stest | logon | table | postgres
stest | order_items | table | postgres
stest | orderentry_metadata | table | postgres
stest | orders | table | postgres
stest | product_descriptions | table | postgres
stest | product_information | table | postgres
stest | warehouses | table | postgres
(11 rows)
jemdb=# select nspname AS schemaname,
jemdb-# relname,
jemdb-# reltuples::numeric as rowcount,
jemdb-# pg_size_pretty (
jemdb(# pg_total_relation_size ( '"' || nspname || '"."' || relname || '"' )) AS SIZE
jemdb-# from pg_class C LEFT JOIN pg_namespace N ON ( N.oid = C.relnamespace )
jemdb-# where nspname NOT IN ( 'pg_catalog', 'information_schema' )
jemdb-# AND relkind = 'r'
jemdb-# ORDER by reltuples DESC
jemdb-# LIMIT 20;
schemaname | relname | rowcount | size
------------+----------------------+----------+------------
stest | inventories | 899441 | 433 MB
stest | order_items | 7341 | 1072 kB
stest | logon | 2383 | 160 kB
stest | card_details | 1500 | 264 kB
stest | addresses | 1500 | 264 kB
stest | orders | 1430 | 376 kB
stest | warehouses | 1000 | 192 kB
stest | customers | 1000 | 440 kB
stest | product_descriptions | 1000 | 288 kB
stest | product_information | 1000 | 400 kB
stest | orderentry_metadata | -1 | 8192 bytes
(11 rows)
jemdb=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
jemdb | stest | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)
jemdb=# \dn
List of schemas
Name | Owner
--------+----------
public | postgres
stest | stest
(2 rows)
jemdb=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
stest | Superuser, Create role, Create DB, Replication | {}
```
```
作者:IT邦德
中国DBA联盟(ACDU)成员,10余年DBA工作经验
擅长主流数据Oracle、MySQL、PG、openGauss运维
备份恢复,安装迁移,性能优化、故障应急处理等
可提供技术业务:
1.DB故障处理/疑难杂症远程支援
2.Mysql/PG/Oracle/openGauss
数据库部署及数仓搭建
•••
微信:jem_db
QQ交流群:587159446
公众号:IT邦德
```
@[TOC](文章目录)
# 前言
>本文详细介绍了我的旅程、从Oracle迁移到PostgreSQL遇到的挑战,我希望分享这些经验将使你的PostgreSQL之旅更加顺利.
## 1.Ora2Pg介绍
```
Ora2Pg是我的第一个盟友。
它是一个开源工具,可将Oracle数据库模式转换为PostgreSQL格式。
可以处理大量的甲骨文对象
可通过配置文件进行配置
https://ora2pg.darold.net/
```

## 2.ora2pg安装
### 2.1 安装依赖包
```
yum install -y gcc perl-DBD-Pg perl perl-devel perl-DBI perl-CPAN bzip2 \
perl-ExtUtils-eBuilder perl-ExtUtils-MakeMaker perl-Time-HiRes perl-tests perf cpan
```
### 2.2 正式安装
```
perl -MCPAN -e 'install DBI'
perl -MCPAN -e 'install DBD::Oracle'
perl -MCPAN -e 'install DBD::Pg'
```

## 3.相关配置
### 3.1 表结构配置
```
cat > /etc/ora2pg/ora2pg_table_ddl.conf <<"EOF"
ORACLE_HOME /usr/lib/oracle/21/client64
ORACLE_DSN dbi:Oracle:host=172.18.12.90;sid=oradb;port=1521
#ORACLE_DSN dbi:Oracle:host=192.168.1.29;service_name=pdb1;port=1521
#ORACLE_DSN dbi:Oracle:tns_ora19c
ORACLE_USER system
ORACLE_PWD oracle
SCHEMA STEST
EXPORT_SCHEMA 1
CREATE_SCHEMA 1
TYPE TABLE
PG_NUMERIC_TYPE 0
PG_INTEGER_TYPE 1
DEFAULT_NUMERIC float
SKIP fkeys checks
#SKIP keys pkeys ukeys indexes checks
NLS_LANG AMERICAN_AMERICA.UTF8
OUTPUT_DIR /tmp
OUTPUT ora2pg_table_ddl.sql
PG_VERSION 14
EOF
```
### 3.2 表数据的配置文件
```
cat > /etc/ora2pg/ora2pg_table_data.conf <<"EOF"
ORACLE_HOME /usr/lib/oracle/21/client64
ORACLE_DSN dbi:Oracle:host=172.18.12.90;sid=oradb;port=1521
#ORACLE_DSN dbi:Oracle:tns_ora19c
ORACLE_USER system
ORACLE_PWD oracle
SCHEMA STEST
TYPE COPY
PG_NUMERIC_TYPE 0
PG_INTEGER_TYPE 1
DEFAULT_NUMERIC float
SKIP fkeys checks
#SKIP fkeys pkeys ukeys indexes checks
NLS_LANG AMERICAN_AMERICA.UTF8
OUTPUT_DIR /tmp
OUTPUT ora2pg_table_data.sql
PG_DSN dbi:Pg:dbname=jemdb;host=172.18.12.50;port=5432
PG_USER postgres
PG_PWD jeames
PG_SCHEMA stest
PG_VERSION 14
EOF
```
## 4.ora2pg迁移数据
### 4.1 迁移全部表结构
```
mkdir -p /ora2pg
ora2pg -c /etc/ora2pg/ora2pg_table_ddl.conf -t table -b /ora2pg
```

### 4.2 PG中创建数据
```
su - postgres
psql
CREATE USER STEST WITH password 'post' CREATEDB SUPERUSER replication createrole login;
create database jemdb;
alter database jemdb owner to STEST;
\c jemdb
-- 跑脚本
\i /ora2pg/ora2pg_table_ddl.sql
jemdb=# \d
```

### 4.3 迁移数据
```
ora2pg -d -t copy -c /etc/ora2pg/ora2pg_table_data.conf -P 12 -L 100000 -j 12
此过程执行完成后,数据就已经插入到PG数据库中了:
```
## 5.数据验证
```
su - postgres
psql
\c jemdb
emdb=# show search_path;
search_path
-----------------
"$user", public
(1 row)
jemdb=# set search_path=stest,public;
SET
jemdb=# \dt
List of relations
Schema | Name | Type | Owner
--------+----------------------+-------+----------
stest | addresses | table | postgres
stest | card_details | table | postgres
stest | customers | table | postgres
stest | inventories | table | postgres
stest | logon | table | postgres
stest | order_items | table | postgres
stest | orderentry_metadata | table | postgres
stest | orders | table | postgres
stest | product_descriptions | table | postgres
stest | product_information | table | postgres
stest | warehouses | table | postgres
(11 rows)
jemdb=# select nspname AS schemaname,
jemdb-# relname,
jemdb-# reltuples::numeric as rowcount,
jemdb-# pg_size_pretty (
jemdb(# pg_total_relation_size ( '"' || nspname || '"."' || relname || '"' )) AS SIZE
jemdb-# from pg_class C LEFT JOIN pg_namespace N ON ( N.oid = C.relnamespace )
jemdb-# where nspname NOT IN ( 'pg_catalog', 'information_schema' )
jemdb-# AND relkind = 'r'
jemdb-# ORDER by reltuples DESC
jemdb-# LIMIT 20;
schemaname | relname | rowcount | size
------------+----------------------+----------+------------
stest | inventories | 899441 | 433 MB
stest | order_items | 7341 | 1072 kB
stest | logon | 2383 | 160 kB
stest | card_details | 1500 | 264 kB
stest | addresses | 1500 | 264 kB
stest | orders | 1430 | 376 kB
stest | warehouses | 1000 | 192 kB
stest | customers | 1000 | 440 kB
stest | product_descriptions | 1000 | 288 kB
stest | product_information | 1000 | 400 kB
stest | orderentry_metadata | -1 | 8192 bytes
(11 rows)
jemdb=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
jemdb | stest | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)
jemdb=# \dn
List of schemas
Name | Owner
--------+----------
public | postgres
stest | stest
(2 rows)
jemdb=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
stest | Superuser, Create role, Create DB, Replication | {}
```