瀚高 与 oracle 区别
原文转自大兄弟:https://blog.csdn.net/weixin_39946767/article/details/113001179
由于某些非技术方面的原因,我们也在搞一些开源数据库引入,替换商业数据库,于是瞄上了PostgreSQL。
PostgreSQL本身的技术不在这里做介绍,虽然国内PostgreSQL没有Mysql那么流行,但是搜索一下,还是能够找到不少PostgreSQL中文的一些技术资料, 其中PG的官方文档是最详尽且最有助于学习PG的:
Oracle迁移到PostgreSQL:
大致原理:
该工具使用perl写的, 主要迁移功能都由ora2pg.conf 这个参数文件控制,该参数文件定义源库Oracle和目标库的DSN,通过DBD::Oracle Perl 、 DBD::Pg Perl 的module连接到源库和目标库, 按照用户制定的参数,导出源库Oracle的相关对象结构(也可以连数据一起导),导入到目标库PG。 导入可以是在线的(导出脚本不落地直接导入PG),也可以先生成导出脚本到本地,手动修改复核后,再手动使用psql导入PG。
ora2pg命令行各参数使用也比较清晰明了, 支持各种导出导入选项,比如你可以只导某些schema或者对象,或者排除某些schema或者对象不导, 也可以什么都不做,只对源库做一个迁移PG的分析,出具一份报告等等。
具体使用方法,还是自己去实际尝试会比较好。
使用Ora2pg的方案将Oracle迁移至PG, 遇到的问题多少与源Oracle数据库有多少与PG不兼容的东西成正比。下面是我们遇到的问题简单总结:
应用程序里面sqlmap.xml 人工REVIEW时的问题发现:
Oracle
PostgreSQL
dual表
没有dual表,可以直接select 1、select user、select xxx
时间函数(sysdate)
current_date
current_time
current_timestamp
trunc
trunc/date trunc(时间截断函数)
sys_guid()
有类似sys_guid的函数uuid_generate_v4,但需要安装,create extension “uuid-oosp”.
nvl
PG可以使用COALESCE
where rownum < ...
select row_number() over() , * from XXXX或者limit
PG导入ora2pg产生的迁移脚本时发现的问题:
tables
DEFAULT Sys_guid();
session# serial# 字段
DEFAULT uuid_generate_v4;
去掉#
partitions
父表在tables中已创建,创建子表时,由于大小写问题提示找不到父表。
表名称区分大小写,继承父表时,大小写改为与父表相同。增加或减少分区要修改触发器函数。
synonyms
转换过来的语句类似如下:
CREATE VIEW public.tablename AS SELECT * FROM owner.tablename SECURITY DEFINER;
PG中没有同义词,自动创建为视图,转换过来的视图名称与存在的表名相同,需要修改视图名称。
SECURITY DEFINER不能加到创建语句的后面,可通过授权来控制权限。
packages
1、PG中没有v$session.(oracle原来的packages里面大多有这个)
select sid, serial# into v_sid, v_serial# from v$session
2、有些转换过来的语句顺序不正确,需要重构。
3、packages自动转换为function,且function会创建到以原来packages命名的schema下
ora2pg会把Oracle里面的package header转换为同名的schema
procedures
1、dbms_output.put_line('成功插入数据!');-->RAISE NOTICE '%',('成功插入数据!');
2、 dbms_output.put_line(sqlerrm) --- RAISE NOTICE '%', sqlerrm;
3、表的子查询必须包围在圆括弧里并且必须赋予一个别名
4、start with connect by 递归查询在PG中WITH RECURSIVE
views
1、字符类型问题
2、递归查询没有转换成功
3、外连接中的“+”号没有转换
4、DECODE函数需要重构
5、COALESCE 函数返回值类型不匹配
1、字符类型需要调整。
2、start with connect by 递归查询在PG中WITH RECURSIVE
3、 (+)这样的外连接写法需要调整为SQL标准的 table1 [LEFT|RIGHT|FULL] OUTER JOIN table2 ON (…);
4、DECODE函数需要重构成(case when some_column = ‘some_value’ then ‘some_other_value’ when … then … else ‘some_default_value’ end ) as some_column;
5、COALESCE 函数返回值类型不匹配、需要类型转换。
等等。
可以看到直接将Oracle迁移到PostgreSQL,无论是应用层,还是数据库层面, 都还是有很多改写工作要做的。
由于有上述诸多问题,我们研究了一下号称为替换Oracle而生的EnterpriseDB(PostgreSQL的商业版):
http://www.enterprisedb.com/products-services-training/products/documentation/enterpriseedition
EnterpriseDB的安装指引:
http://www.enterprisedb.com/docs/en/9.4/instguide/toc.html
EnterpriseDB的官方文档:
EnterpriseDB的Oracle迁移PG的工具Migration Toolkit使用指引:
工具使用比较简单,简单配置一些参数接口, 迁移过程发现的问题相比ora2pg少了很多,但还是有一些:
例如EDB中没有function sys_connect_by_path函数、 oracle trigger语法里面的referencing new as new old as old等。
结论:
虽然EDB的Migration Toolkit这个迁移工具本身没有像ora2pg那么多灵活的迁移选项组合, 但是其功能基本满足迁移需求,而且重要的是由于EDB在PostgreSQL的基础上,外面包了一层,实现了很多Oracle的概念,例如前面提到的dual表、同义词、pkg、内建函数,甚至Oracle的分区表语法可以直接在EDB运行。所以,同样的源Oracle数据库,我们发现90%左右的都可以直接在目标EnterpriseDB运行了,只需要修改一少部分。
具体EnterpriseDB的兼容Oracle的清单,参考
所以,从节省成本与运维稳定两方面平衡考虑, 对于新建系统直接采用PostgreSQL,对于已有系统迁移到PostgreSQL,使用EnterpriseDB也不失为一个过渡期的较好选择。