暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

关于用ora2pg工具实现 oracle to pg ddl的迁移

原创 lvzhengwei 2021-11-25
1946

电信这头telepg的迁移主要是用datax和oracle2pg 这两款开源软件,这两款软件的部署后续记录,现在先测试下迁移:


1.oracle2pg 这款软件主要是抽取oracle的各种表结构,包括表(包含索引)  视图 存过 函数 等等

有两点要注意,  一个是外键,一个是序号

外键的话要在所有对象都迁移过去之后再创建, 序号的话要手动创建,因为oracle的max值比pg的要大,用这个sql查

select case when MAX_VALUE > 999999999999999999 then

(case CACHE_SIZE

when 0 then

'create sequence ' || lower(SEQUENCE_NAME)

    || ' INCREMENT ' || INCREMENT_BY

    || ' MINVALUE ' || MIN_VALUE

    || ' MAXVALUE ' || '999999999999999999'

    || ' START ' || LAST_NUMBER || ';'

else

'create sequence ' || lower(SEQUENCE_NAME)

    || ' INCREMENT ' || INCREMENT_BY

    || ' MINVALUE ' || MIN_VALUE

    || ' MAXVALUE ' || '999999999999999999'

    || ' START ' || LAST_NUMBER

    || ' CACHE ' || CACHE_SIZE || ';'

end)

else

(case CACHE_SIZE

when 0 then

'create sequence ' || lower(SEQUENCE_NAME)

    || ' INCREMENT ' || INCREMENT_BY

    || ' MINVALUE ' || MIN_VALUE

    || ' MAXVALUE ' || MAX_VALUE

    || ' START ' || LAST_NUMBER || ';'

else

'create sequence ' || lower(SEQUENCE_NAME)

    || ' INCREMENT ' || INCREMENT_BY

    || ' MINVALUE ' || MIN_VALUE

    || ' MAXVALUE ' || MAX_VALUE

    || ' START ' || LAST_NUMBER

    || ' CACHE ' || CACHE_SIZE || ';'

end)

end sequence_ddl

from dba_sequences where SEQUENCE_OWNER=upper('&owner_name’);


首先研究下oracle2pg这款开源组件的使用:

ora2pg是一款提取oracle端的各种对象的工具,通过配置conf文件来指定连接oracle的信息,然后把oracle端的各项元数据提取成文本文件,后续可以在pg端执行,

1.安装部署ora2pg,以及oracle的客户端

2.编辑参数文件,参数文件没有固定位置,只要编写就行,例子如下:


PG_VERSION 12

ORACLE_HOME /usr/lib/oracle/12.2/client64/

ORACLE_DSN dbi:Oracle:host=10.62.8.14;service_name=crm3yz;port=11521

ORACLE_USER system

ORACLE_PWD ctbj_2014

SCHEMA cep

PREFIX_PARTITION 1

PREFIX_SUB_PARTITION 1

FILE_PER_CONSTRAINT 1

FILE_PER_INDEX 1

FILE_PER_FKEYS 1

USE_RESERVED_WORDS 1

TRANSACTION readonly

DISABLE_UNLOGGED 1


# FILE_PER_CONSTRAINT 将导出的约束单独放在一个文件中

# FILE_PER_INDEX 将导出的索引单独放在一个文件中

# FILE_PER_FKEYS 将导出的外键放在单独的文件中

# PREFIX_PARTITION 导出的分区表加上主表文件名前缀

# PREFIX_SUB_PARTITION 同上,针对的对象是子分区

# USE_RESERVED_WORDS 如果oracle中导出的表名或列名有关键字,则导出时自动为其加上双引号,尽量询问应用看能否更改PG中的表名或字段名

# TRANSACTION readonly 设置为只读事务,避免误操作Oracle端数据

# DISABLE_UNLOGGED 禁止转换unlogged表,避免出现unlogged表


# 调用方式:ora2pg -c ora2pg.conf -t <TYPE> -o <SQL_FILE_PATH>


编写好参数文件之后就可以执行了:

# table (46/46)

cd /home/shx/ora2pg/crm3db/cep/conf

ora2pg -c ora2pg.conf -t "TABLE" -b ../sql -o cep.sql

# procedure (5/5)

ora2pg -c ora2pg.conf -t "PROCEDURE" -b ../sql -o cep_procedure.sql

# SEQUENCE (6/6)

ora2pg -c ora2pg.conf -t "SEQUENCE" -b ../sql -o cep_sequence.sql

# PACKAGE (1/1)

ora2pg -c ora2pg.conf -t "PACKAGE" -b ../sql -o cep_package.sql


-c 指定参数文件   -t指定导出的对象类型, -b 导出的文件放在哪里, -o 导出的文件的名字


导出之后的文件如下:

 

所以在这之前要先确认好oracle端导出的对象类型和对应的数量,注意外键最后再执行

也可以单独制定导出一张表的ddl:  后面加 -a ,可以用 ora2pg -h 来看可以执行的命令



在pg端应用:


1.先设置出错之后不自动退出:

sed -i 's/ON_ERROR_STOP ON/ON_ERROR_STOP off/g' cep.sql

sed -i 's/ON_ERROR_STOP ON/ON_ERROR_STOP off/g' CONSTRAINTS_cep.sql

sed -i 's/ON_ERROR_STOP ON/ON_ERROR_STOP off/g' FKEYS_cep.sql

sed -i 's/ON_ERROR_STOP ON/ON_ERROR_STOP off/g' INDEXES_cep.sql

sed -i 's/ON_ERROR_STOP ON/ON_ERROR_STOP off/g' cep_package.sql

sed -i 's/ON_ERROR_STOP ON/ON_ERROR_STOP off/g' cep_procedure.sql

sed -i 's/ON_ERROR_STOP ON/ON_ERROR_STOP off/g' cep_sequence.sql


然后在pg端执行, -f是指定文件:

psql -h 10.62.8.156 -p 18801 -d crm3db -U cep -f cep.sql > ../log/cep.log 2>&1

psql -h 10.62.8.156 -p 18801 -d crm3db -U cep -f CONSTRAINTS_cep.sql > ../log/CONSTRAINTS_cep.log 2>&1

psql -h 10.62.8.156 -p 18801 -d crm3db -U cep -f INDEXES_cep.sql > ../log/INDEXES_cep.log 2>&1

psql -h 10.62.8.156 -p 18801 -d crm3db -U cep -f cep_package.sql > ../log/cep_package.log 2>&1

psql -h 10.62.8.156 -p 18801 -d crm3db -U cep -f cep_procedure.sql > ../log/cep_procedure.log 2>&1

psql -h 10.62.8.156 -p 18801 -d crm3db -U cep -f cep_sequence.sql > ../log/cep_sequence.log 2>&1


接下来实验:

首先确认迁移目标:

这次实验就用汇聚库的rule用户来测试,先在汇聚库查rule用户的对象类型:


可以看到就table 和 index, 分别是111 和 117 ,接下来配置参数文件:


然后执行:

ora2pg -c rule.conf -t "TABLE" -b sql -o rule_table.sql


发现多了一些表,查一下,发现不应该查dba_segments  应该查dba_objects:



这下对上了


index的话不用单独导出,在导出table的元数据的时候就会把index也导出来,不过index的话,导出完之后的文件列表如下:


其中indexes里面只有6条的原因是,对于主键索引,pg和oracle都是在添加主键的时候就会自动创建一个索引,所以pg把主键索引全部放到了 constraints里面去自动创建了.


接下来把文件传输到对应的pg端,然后应用文件,这里我用我的测试环境了:


首先把这4个sql的set ON_ERROR_STOP 调成off


然后执行:

cd /home/postgres

psql -h  10.37.129.4 -p 1921 -d lv -U rule -f rule_table.sql > log/rule_table.log 2>&1

psql -h  10.37.129.4 -p 1921 -d lv -U rule -f INDEXES_rule_table.sql > log/INDEXES_rule_table.log 2>&1

psql -h  10.37.129.4 -p 1921 -d lv -U rule -f CONSTRAINTS_rule_table.sql > log/CONSTRAINTS_rule_table.log 2>&1


命令可以成功执行,没有任何返回信息就是成功了,检查log的话有如下显示:



不过要注意一点,这个命令里面的 -U 是指定的连接pg的用户,如果pg库有对应的schema,那就创建在这个schema上,如果没有对应的schema,就创建在默认的schema下(public) 



然后索引和约束的日志也是类似,要注意如果有报错,会显示psql:  为开头的日志信息.




















最后修改时间:2021-11-25 17:29:35
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论