说明
该文档为简单的Ora2Pg安装配置使用说明文档,主要涵盖安装前其它组件的安装、Ora2Pg安装、配置以及利用Ora2Pg从Oracle生成sql脚本,利用sql脚本导入Postgresql数据库中。
Ora2Pg是以perl开发的perl模块工具,为使安装能够顺利通过,在安装Ora2Pg之前必须先确保系统已经安装了perl模块以及DBI、DBD::Oracle模块。若需要直接导入到Postgresql则还需要安装DBD::Pg模块。并且在Ora2Pg的使用过程中要求数据库为正常运行状态。
本次实验是将Oracle、Postgresql和Ora2Pg安装在不同的PC上,最终搭建一个用于迁移数据的Ora2Pg终端,通过远程一端连接Oracle,另一端连接Postgresql。
Ora2Pg简介
Ora2Pg是一个免费的工具,用于将Oracle数据库迁移到Postgresql兼容的模式里。它连接Oracle数据库,扫描并自动抽取其结构或数据,然后生成用于实现迁移的sql脚本,利用该脚本你可以将数据库结构或数据加载到Postgresql数据库中。
我们可以使用Ora2Pg实现逆向工程Oracle数据库到大型企业级数据库的迁移或者简单地复制一些Oracle数据库到Postgresql数据库中。你只需要提供连接Oracle数据库时所需的连接参数,无需了解任何Oracle数据库的知识。
工作过程
Ora2Pg中包括一个Perl脚本(Ora2Pg)和一个Perl模块(Ora2Pg.pm),你只需要修改配置文件Ora2Pg.conf中连接Oracle数据库的DSN设置和任意的一个模式名称。做完了这些然后你只需要设置一下你想要输出的对象类型,它提供的类型有:约束表、视图、表空间、序列、索引、触发器、授权、函数、存储过程、包封装、分区和数据。
默认情况下Ora2Pg会导出一个文件,你可以通过psql客户端将其导入到Postgresql数据库中,不过你也可以通过设置Postgresql数据库的DSN直接导入。你可以通过配置ora2pg.conf的配置选项来完全控制导出什么以及如何去导出。
特性
导出整个数据库模式(表、视图、序列、索引),以及唯一性,主键、外键和检查约束。
导出用户和组的授权/权限。
导出筛选的表(通过制定表明)。
导出Oracle模式到一个Postgresql(7.3以后)模式中。
导出预定义函数、触发器、程序、包和包体。
导出范围和列表分区。
导出所有的数据或跟随一个WHERE子句。
充分支持Oracle BLOB对象作为PG的BYTEA。
导出Oracle视图作为PG表。
导出定义的Oracle用户格式。
提供关于转换PLsql码为PLPGsql的基本帮助(仍然需要手工完成)。
可在任何平台上工作。
Ora2Pg尽力将Oracle数据库转换到Postgresql中,但是仍需一部分的手动工作。Oracle特定的PL/sql代码生成函数、过程和触发器时必须进行审查,以便匹配Postgresql的语法。你会发现一些有用的不利因素在将Oracle PL/sql移植到Postgresql的PL/PGsql。
支持的导出对象
这是允许导出的不同的格式,默认是TABLE:
TABLE:提取所有包括索引、主键、唯一键、外键和检查约束的表。
VIEW:提取视图。
GRANT:提取在所有对象中转换为Pg组、用户和权限的用户。
SEQUENCE:提取所有的序列以及上一个位置。
TABLESPACE:提取表空间。
TRIGGER:提取通过动作触发的被指定的触发器。
PROCEDUERS:提取存储过程。
PACKAGE:提取包和包主体。
PARTITION:提取范围和列表分区。
(以下两条是10.0新加的)
FDW:提取外部数据封装表
PARTITION:提取作为快照刷新视图所建立的视图
数据类型转换对照
DATE timestamp
LONG text
LONG RAW bytea
CLOB text
NCLOB text
BLOB bytea
BFILE bytea
RAW bytea
ROWID oid
FLOAT double precision
DEC decimal
DECIMAL decimal
DOUBLE PRECISION double precision
INT integer
INTEGER integer
REAL real
SMALLINT smallint
BINARY_FLOAT double precision
BINARY_DOUBLE double precision
TINESTAMP timestamp
XMLTYPE xml
BINARY_INTEGER integer
PLS_INTEGER integer
(以下两条是10.0新加的)
TIMESTAMP WITH TIME ZONE timestamp with time zone
TIMESTAMP WITH LOCAL TIME ZONE timestamp with time zone
这些数据类型的转换可根据实际情况用户自己指定,通过ora2pg.conf中的DATA_TYPE指定。如果未指定,默认转换类型如上表。
10.0 changelog
整体上有了更多的改进以及bug的修复,出现了一个新的输出类型:SHOW_REPORT,它将输出一份关于您Oracle数据库中含有的所有对象的汇总报告及其导出建议。 通过该报告你可以使用一个新的指令ESTIMATE_COST使Ora2Pg来评估数据库的迁移成本(按人天计算)。 还有另一个新的配置指令EXTERNAL_TO_FDW,它允许所有Oracle外部表作为file_fdw外部表输出,默认是关闭的。
下面是具体的说明:
- Fix quote escaping on table comments.
- Fix some other issues with 8i databases,added database version auto-detection to avoid printinf warning.
- Allow null value in BFILE to the oar2pg_get_bfilename().
- Update documentation about BFILE export.
- Add drop function ora2pg_get_bfilename() when necessary.
- Add support to BFILE external path export by creating a function ora2pg_get_bfilename( p_bfile IN BFILE ) to retrieve path from BFILE. BFILE will be
exported as text field with the full path to the file as value. Note that this is the first time that Ora2Pg need write access to the Oracle database,
if you do not have BFILE or you have set the corresponding Postgresql type asd bytea (the default) the function will not be created.
- Fix a performance issue when extracting BLOB with a LongReadLen upper than 1MB.
- Fix priviledge on schema created from Oracle package body.
- Add object type in comment before priviledge extraction.
- Order output of grant to groups grants by object types. This is useful to quickly disable some sql orders corresponding of not already loaded objects.
- Fix progress bar output.
- Fix priviledge on sequence,tablespace and schema.
- Fix backward compatibility with Oracle 8i,remove query with JOIN.
- Postgresql client_encoding is now forced to UTF8 when BINMODE is set to utf8.
- Replace DISABLE TRIGGER ALL by DISABLE TRIGGER USER following the value if USER_GRANTS to avoid permission denied on constraint trigger when data are load
under a non PG superuser.
- Rename DISABLE_TABLE_TRIGGERS to DISABLE_TRIGGERS and set default value to 0. Other values are USER or ALL following the connected user.
- Fix missing newline after comment in PL/sql code.
- Fix report message on external table export.
- The export TYPE have been entirely rewritten to only export supported user defined types. Exported are: Nested Tables,Object type,Type in herited and
Subtype,Varrays. Associative Arrays,Type Body and type with member method are not supported.
- When FILE_PER_INDEX is enable,sql order to move indexes in their respective tablespace will be written into a dedicated file prefixed by TBSP_INDEXES_.
- Fix location on external table export. Thanks to Thomas Reiss for the help.
- PG_SUPPORTS_INSTEADOF is now activated by default,that mean that migration should be done on PG >= 9.1.
- Remove obsolete --xtable commande line option,should be replaced by --allow,backward compatibility is preserved.
- Add EXTERNAL_TO_FDW configuration directive,disable by default,to export all Oracle external tables as file_fdw foreign tables.
- Fix an other case where user defined type were not exported with an ending semi-colon. Thank to Dominique Legrendre for the report.
- Fix export of user defined type with extra ");" at end of the type definition and remove system types from export.
- Add PLsql replacemement of currval.
- Add PLsql replacement of PIPELINED and PIPE ROW by SETOF and RETURN NEXT.
- Add rewrite of Oracle DETERMINISTIC function into Postgresql IMMUTABLE function.
- Fix copy during install on MacOSx and add /Y option to windows install copy to force overwrite existing files.
- Fix issue exporting rows with perl ARRAYS ref.
- Fix replacement of IS SELECT wrongly replaced by IS PERFORM in some case.
实验系统环境
系统版本
[root@ora~]#cat/etc/issue CentOSrelease5.5(Final) Kernel\ronan\m
内核版本
[root@ora~]#uname-a Linuxora2.6.18-194.el5#1SMPFriApr214:58:14EDT2010x86_64x86_64x86_64GNU/Linux
perl安装
系统一般会自带一个已安装的perl版本,可在安装前进行检测:
[root@ora~]#rpm-qperl perl-5.8.8-27.el5
Ora2Pg要求perl版本为5.6或更高。
如果没有或者是想要安装更高版本的请按照下面的方法编译安装:
perl下载地址:http://www.perl.org/get.html#unix_like
安装步骤:
1、解压安装包,进入解压目录
2、运行 sh Configure –de (使用默认配置安装)
3、make
4、make test
5、make install
利用CPAN来安装DBI、DBD::Oracle和DBD::Pg
由于此实验是将Ora2Pg与Oracle分别安装,因此在通过CPAN在线安装模块之前,首先需要确保在该PC上已经存在了Oracle和Postgresql的客户端,并且必要的环境变量已经配置完成。
该实验通过CPAN来安装,当然也可使用源码安装。
安装Oracle客户端
要成功配置DBD::Oracle则需要Basic、sql*Plus、SDK这三个配置,我们需要将这三个包放到同一个目录中。
所需包下载地址:http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html
将下载的三个包在同一个目录下解压,解压后生成一个目录(instantclient_11_1),结果如下:
[root@ora~]#ll/tmp/InstallClient/ total47564 -rw-r--r--1rootroot47149968Nov272011basic-11.1.0.70-linux-x86_64.zip drwxr-xr-x3rootroot4096Jul2821:31instantclient_11_1 -rw-r--r--1rootroot607351Nov272011sdk-11.1.0.7.0-linux-x86_64.zip -rw-r--r--1rootroot857863Nov272011sqlplus-11.1.0.7.0-linux-x86_64.zip
安装Postgresql客户端
要成功配置DBD::Pg则需要首先配置好Postgresql的客户端,我们可以通过安装Postgresql的方式来安装配置客户端。(Postgresql的安装过程 略)
注:如果我们不需要自动导入到Postgresql中,只需要生成一个sql脚本,那么不需要进行该步。
配置环境变量
环境变量配置结果如下:
[root@ora~]#cat.bash_profile #.bash_profile   #Getthealiasesandfunctions   if[-f~/.bashrc];then .~/.bashrc fi   #Userspecificenvironmentandstartupprograms   PATH=/usr/local/pgsql/bin:$PATH:$HOME/bin exportORACLE_HOME=/tmp/InstallClient/instantclient_11_1 exportLD_LIBRARY_PATH=/tmp/InstallClient/instantclient_11_1 exportPATH unsetUSERNAME
安装模块
yuminstallperl-CPANgcc
以root用户进入cpan shell
[root@ora~]#perl–MCPAN–eshell ………… cpan>installDBI ………… cpan>installDBD::Oracle ………… cpan>installDBD::Pg …………
注意:
执行perl –MCPAN时如果报Can't locate CPAN.pm in @INC ,那么需要首先安装CPAN
yuminstallperl-CPAN
并且需要安装gcc,避免安装模块时无法编译。
perl模块简单检测
使用perl语言制作一个检测脚本test.pl,内容如下:
[root@ora~]#cattest.pl #!/usr/bin/perl useExtUtils::Installed; my$inst=ExtUtils::Installed->new(); printjoin"\n",$inst->modules();
运行检测:
[root@ora~]#perltest.pl DBD::Oracle DBD::Pg DBI ExtUtils::MakeMaker Ora2Pg Perl Test::Simple
安装Ora2Pg
下载地址:https://sourceforge.net/projects/ora2pg/
安装方式跟perl类似:
tar–xvfora2pg-9.0.tar.bz2 cdora2pg-9.0/ perlMakefile.PL make&&makeinstall
安装完成后默认的配置文件路径:/etc/ora2pg/ora2pg.conf
Ora2Pg简单配置
修改配置文件/etc/ora2pg/ora2pg.conf,结果如下:
ORACLE_DSN dbi:Oracle:host=192.168.0.153;sid=orcl
ORACLE_USER system
ORACLE_PWD highgo
SCHEMA TEST (注意要大写,否则匹配不到)
TYPE TABLE DATA VIEW
如果需要让数据自动导入到Postgresql中,则需要同时配置关于连接Postgresql的相关信息,配置类似上面Oracle的配置,如下:
PG_DSN dbi:Pg:dbname=test_db;host=192.168.100.106;port=5432
PG_USER test
PG_PWD highgo
测试
创建测试数据
在Oracle中首先创建用户test并赋权,然后以test用户创建相关对象,如下:
sql>CREATETABLEt1( 2idNUMBER(5)NOTNULLPRIMARYKEY,3namevarchar2(10) 4); TABLEcreated. sql>DESCt1; NameNULL?TYPE ----------------------------------------------------------------------------- IDNOTNULLNUMBER(5) NAMEVARCHAR2(10) sql>CREATETABLEt2( 2idNUMBER(5)NOTNULL,3ageINT,4FOREIGNKEY(id)referencest1(id) 5); TABLEcreated. sql>DESCt2; NameNULL?TYPE ----------------------------------------------------------------------------- IDNOTNULLNUMBER(5) AGENUMBER(38) sql>INSERTINTOt2VALUES(1,20); 1ROWcreated. sql>INSERTINTOt2VALUES(2,18); 1ROWcreated. sql>INSERTINTOt2VALUES(3,23); 1ROWcreated. sql>CREATEINDEXt2_index_ageONt2(age); INDEXcreated. sql>CREATEVIEWt1_t2_v1 2AS 3SELECTt1.id,t1.name,t2.ageFROMt1,t2 4WHEREt1.id=t2.id; VIEWcreated.
导出脚本
执行成功后将会在当前目录下生成一个sql脚本(默认是output.sql)
[root@ora~]#ora2pg Tryingtoconnecttodatabase:dbi:Oracle:host=192.168.100.138;sid=orcl Isolationlevel:SETTRANSACTIONISOLATIONLEVELSERIALIZABLE ForceOracletocompileschemabeforecodeextraction Retrievingtableinformation... [1]ScanningT1(TESTT1TABLE)... ID=>type:NUMBER,length:22(char_length:0),precision:5,scale:0,nullable:N,default: NAME=>type:VARCHAR2,length:10(char_length:10),precision:,scale:,nullable:Y,default: [2]ScanningT2(TESTT2TABLE)... ID=>type:NUMBER,default: AGE=>type:NUMBER,default: Retrievingtableinformation... [1]ScanningT1(TESTT1TABLE)... WarningduplicatetableT1,SYNONYME ?Skipped. [1]ScanningT2(TESTT2TABLE)... WarningduplicatetableT2,SYNONYME ?Skipped. Retrievingviewsinformation... ID=>columnid:1 NAME=>columnid:2 AGE=>columnid:3 [1]ScanningT1_T2_V1... WARNING:can'tusedirectimportintoPostgresqlwiththistypeofexport. OnlyDATAorCOPYexporttypecanbeusewithdirectimport,fileoutputwillbeused. DumpingtableT1... DumpingtableT2... DumpingRIT2... WARNING:orderingtableexporttorespectforeignkeysisnotpossible. PleaseconsiderusingDEFER_FKEYorDROP_FKEYconfigurationdirectives. DumpingtableT1... DEBUG:Preparingbulkof10000dataforoutput DEBUG:Creatingoutputfor10000tuples   3recordsin0secs TotalextractedrecordsfromtableT1:3 in0secs DumpingtableT2... DEBUG:Preparingbulkof10000dataforoutput DEBUG:Creatingoutputfor10000tuples   3recordsin0secs TotalextractedrecordsfromtableT2:3 in0secs Restartingsequences Addviewsdefinition... AddingviewT1_T2_V1...
根据实际需求可以制定不同的参数 参数说明:
-d|--debug:启用详细输出。 -h|--help:打印出简单的帮助信息。 -v|--version:显示Ora2Pg的版本。 -c|--conffile:使用另一个替代的配置文件,默认是/etc/ora2pg/ora2pg.conf。 -l|--logfile:使用一个日志文件,默认是标准输出。 -o|--outfile:指定导出的sql脚本文件的路径,默认是当前目录下。 -t|--typeexport:指定导出格式。覆盖配置文件中指定的TYPE。 -p|--plsql:启用PLsql到PLPsql码的转换。 -s|--sourcedsn:设置OracleDBI数据源。 -u|--useruser:设置连接Oracle的用户名。 -w|--passwordpass:设置Oracle用户密码。 -n|--namespaceschema:设置用于提取的Oracle模式名称。 -b|--basedirdir:设置默认的输出文件目录,输出的文件将被保存到该目录。 -x|--xtablerelname:用于显示给定表的列名,仅在TYPE为SHOW_COLUMN时使用。 -f|--forceowner:如果设置为1将促使Ora2Pg设置表和序列的所有者。如果将其值设置为一个用户名会被设定为对象的所有者。 --nls_langcode:设置OracleNLS_LANG客户端编码。 --client_encodingcode:设置Postgresql客户端编码。 -i|--input_filefile:文件包含在没有Oracle数据库连接发起时OraclePL/sql代码的转换。
--GeneratedbyOra2Pg,theOracledatabaseSchemaconverter,version9.0 --Copyright2000-2012GillesDAROLD.Allrightsreserved. --DATASOURCE:dbi:Oracle:host=192.168.100.138;sid=orcl \SETON_ERROR_STOPON CREATETABLE"t1"( "id"INTEGERNOTNULL,"name"VARCHAR(10) ); ALTERTABLE"t1"ADDPRIMARYKEY("id"); CREATETABLE"t2"( "id"INTEGERNOTNULL,"age"BIGINT ); CREATEINDEXt2_index_ageON"t2"("age"); ALTERTABLE"t2"ADDCONSTRAINT"sys_c0011825"FOREIGNKEY("id")REFERENCES"t1"("id")ONDELETENOACTIONNOTDEFERRABLEINITIALLYIMMEDIATE; --GeneratedbyOra2Pg,version9.0 --Copyright2000-2012GillesDAROLD.Allrightsreserved. --DATASOURCE:dbi:Oracle:host=192.168.100.138;sid=orcl \SETON_ERROR_STOPON SETsearch_path=test,pg_catalog; BEGIN; ALTERTABLEt1DISABLETRIGGERALL; INSERTINTO"t1"("id","name")VALUES(1,E'jony'); INSERTINTO"t1"("id","name")VALUES(2,E'lucy'); INSERTINTO"t1"("id","name")VALUES(3,E'jack'); ALTERTABLEt1ENABLETRIGGERALL; COMMIT; SETsearch_path=test,pg_catalog; BEGIN; ALTERTABLEt2DISABLETRIGGERALL; INSERTINTO"t2"("id","age")VALUES(1,20); INSERTINTO"t2"("id","age")VALUES(2,18); INSERTINTO"t2"("id","age")VALUES(3,23); ALTERTABLEt2ENABLETRIGGERALL; COMMIT; CREATEORREPLACEVIEW"t1_t2_v1"("id","name","age")ASSELECTt1.id,t2 WHEREt1.id=t2.id;
在Postgresql中恢复数据
首先创建一个test_db数据库,再创建一个test用户,在test_db数据库下以超级用户创建一个schema,并将该schema的权限者设为test,最后以test用户在test_db数据库下导入数据脚本:
$psql postgres=#CREATEDATABASEtest_db; postgres=#CREATEUSERtestpassword‘highgo’; postgres=#\ctest_db test_db=#CREATEschematestauthorizationtest; test_db=#\ctest_dbtest test_db=>\i/root/output.sql ...
错误解决
安装DBD::Oracle
错误现象:
cpan>installDBD::Oracle TryingtofindanORACLE_HOME YourLD_LIBRARY_PATHenvvarissetto TheORACLE_HOMEenvironmentvariableisnotsetandIcouldn'tguessit. ItmustbesettoholdthepathtoanOracleinstallationdirectory onthismachine(oramachinewithacompatiblearchitecture). SeetheappropriateREADMEfileforyourOSformoreinformation. ABORTED! Runningmaketest Makehadsomeproblems,maybeinterrupted?Won'ttest Runningmakeinstall Makehadsomeproblems,maybeinterrupted?Won'tinstall
解决方式:修改.bash_profile,添加几个关于Oracle的环境变量,结果如下:
PATH=$PATH:$HOME/bin:/u01/app/oracle/oracle/product/10.2.0/db_1/bin/ exportORACLE_SID=orcl exportORACLE_HOME=/u01/app/oracle/oracle/product/10.2.0/db_1 exportLD_LIBRARY_PATH=/u01/app/oracle/oracle/product/10.2.0/db_1/lib/ exportPATH unsetUSERNAME
安装DBD::Pg
错误现象:
cpan>installDBD::Pg ConfiguringDBD::Pg2.18.1 Pathtopg_config? USEOfuninitializedvalueinconcatenation(.)orstringatMakefile.PLline99,<STDIN>line1. USEOfuninitializedvalueinconcatenation(.)orstringatMakefile.PLline101,<STDIN>line1. Postgresqlversion:0(defaultport:0) POSTGRES_HOME:(notset) POSTGRES_INCLUDE:/include POSTGRES_LIB:/lib OS:linux ThevalueofPOSTGRES_INCLUDEpointstoanon-existentdirectory:/include Cannotbuildunlessthedirectoriesexist,exiting. make:***Notargetsspecifiedandnomakefilefound.Stop. /usr/bin/make--NOTOK Runningmaketest Can'ttestwithoutsuccessfulmake Runningmakeinstall makehadreturnedbadstatus,installseemsimpossible
解决方式:
修改.bash_profile,添加几个关于Postgresql的环境变量,结果如下:
PATH=$PATH:$HOME/bin:/u01/app/oracle/oracle/product/10.2.0/db_1/bin/ exportORACLE_SID=orcl exportORACLE_HOME=/u01/app/oracle/oracle/product/10.2.0/db_1 exportLD_LIBRARY_PATH=/u01/app/oracle/oracle/product/10.2.0/db_1/lib/ exportPOSTGRES_HOME=/pg/pgsql/ exportPOSTGRES_INCLUDE=$POSTGRES_HOME/include exportPOSTGRES_LIB=$POSTGRES_HOME/lib unsetUSERNAME
运行Ora2Pg
错误现象:
[root@ora~]#ora2pg Can'tlocateCompress/Zlib.pmin@INC(@INCcontains:/usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8/usr/lib/perl5/site_perl/usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8/usr/lib/perl5/vendor_perl/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/usr/lib/perl5/5.8.8.)at /usr/lib/perl5/site_perl/5.8.8/Ora2Pg.pmline541. BEGINFailed--compilationabortedat/usr/lib/perl5/site_perl/5.8.8/Ora2Pg.pmline541. CompilationFailedinrequireat/usr/local/bin/ora2pgline27. BEGINFailed--compilationabortedat/usr/local/bin/ora2pgline27.
解决方式:
yuminstallperl-Compress-Zlib