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

Oracle迁移PostgreSQL之开发篇

2819


简 述

因为各种原因有不少公司都有过数据库转换迁移的需求,如Access迁移到SQLServer, Oracle迁移到MySQL。但是因为应用系统的稳定性数据库转换迁移对于大部分开发人员来说却并不常见,笔者有幸参与了一个Java应用系统数据库由Oracle迁移PostgreSQL的项目,便从开发角度整理了一篇迁移过程分享给大家。如有遗漏或错误欢迎评论区补充指正。



一、PostgreSQL简介


1

  简介


PostgreSQL(PGSQL)是一种特性非常齐全的自由软件的对象-关系型数据库管理系统(ORDBMS),是以加州大学计算机系开发的POSTGRES。PostgreSQL支持大部分的SQL标准并且提供了很多其他现代特性,如复杂查询、外键、触发器、视图、事务完整性、多版本并发控制等。



2

  优点


•    支持主流操作系统(Windows、Linux、Unix、Mac OS X、BSD);

•    负载接近极限后,性能会保持在顶峰不会下降;

•    拥有丰富的数据类型(大量字典、数组、几何类型、bitmap等);

•    拥有强悍的SQL编程能力(支持丰富的统计函数和统计语法、支持递归、内置正则等);

•    “无锁定”特性突出;

•    多版本并发控制;

•    数据库性能调优灵活(可使用函数和条件索引);

•    拥有多种集群框架可选择(Plproxy、Slony、Stand-by等);

•    支持异步、半同步、同步复制(基于Wal);



3

  对比




4

  安装


PostgreSQL官网:https://www.postgresql.org

或直接访问下载地址:https://www.enterprisedb.com/downloads/postgres-postgresql-downloads



PostgreSQL数据库可视化操作工具pgAdmin4,支持主流操作系统,如Linux、Windows、Mac OS X等。数据库自带的为网页版,也可以自行安装PC客户端。

pgAdmin4客户端下载地址:https://www.pgadmin.org/download



二、Oracle迁移PostgreSQL


迁移宗旨:将数据库从Oracle迁移至PostgreSQL数据库,需要考虑的有很多。但是有一点是不变的,即:要保证数据库迁移后,系统功能能够正常使用,且对业务逻辑尽可能少的修改,因为修改业务逻辑可能会出现意想不到的连锁问题




1

  前期系统梳理



因为Oralce和PostgreSQL语法的不同,所以我们需要调整建表语句脚本,包括索引、函数、存储过程等。但是在整理脚本前,需要统计好系统中的表信息



1.1  统计系统表及表功能


简述:统计系统的使用的表和表功能,主要是为了明确需要迁移的表,以及表所负责的功能(方便数据迁移时,确定数据导入的先后顺序)。好能够一起统计表使用到的序列和索引等,方便之后的迁移操作。部分系统的表,在测试环境和生产环境的字段可能有所不同,也需要统计进来。并注意表结构、约束条件、主外键设置均以生产为准

操作:提供系统使用的表清单、字段差异清单、表解耦清单、剔除系统未使用的表等。

注意:无难点,但耗费时间,需要足够耐心、细心。



1.2  公共表解耦


简述:若本系统有提供公共表给其他系统使用,则迁移到PostgreSQL数据库,那么其他使用该表的系统就无法正常使用;或本系统有使用其他系统的公共表,本系统迁移后则也无法正常使用。

操作:表属主的系统提供对外的表接口,即由原来的直接查询其他系统的表,转为调用其他系统提供的接口来查询需要的数据;反之,若其他系统有用到本系统的表,改为调用本系统提供的接口完成业务操作。

注意:在进行表解耦之前,需要先统计该系统使用的外部表,包括本系统使用外部表的哪些关联字段、外部表在本系统中的作用等信息。然后根据这些信息,与其他系统负责人沟通并开发接口、联调接口等。



1.3  编写执行脚本


简述:Oralce和PostgreSQL的语法不同,所以会先在本地自己搭建的数据库环境中做模拟测试,等脚本无误后才会在SIT环境执行。

操作:统计系统中的存储过程、函数、索引等信息,然后更改语法并写成脚本,最后在本地进行验证。

注意:PostgreSQL的语法与Oracle细节差异还是很多的。



特别分享

常规的SQL脚本改造可以分成两部分:SQL语法和函数。下面是以学生课程表为模型分享一些常用的例子:

    -- 不仅可以指定WHERE条件中的子类类型,还可以指定SELECT查询字段的类型
    SELECT T.STUDENT_ID::VARCHAR
     FROM T_STUDENT T
    WHERE T.STUDENT_ID <> 1 ]]>
      AND T.STATUS = 1
      AND T.CLASS_CODE::VARCHAR    
       <iterate prepend="in" conjunction="," open="(" close=")">
           #classCodeList[]#
       </iterate>
    -- INSERT语句用的最为频繁
    INSERT INTO T_STUDENT ( CREATED_BY,
                           CREATED_DATE,
                           UPDATED_BY,
                           WEEK)
    VALUES( #createdBy:VARCHAR#,
           now(),
           #updatedBy:VARCHAR#,
           to_char(#calendarDate#::timestamp,'ww'));
    -- 特殊的时间加减法运算
    select CURRENT_TIMESTAMP::TIMESTAMP + INTERVAL '5 day';
    -- 分页查询语法
    SELECT * FROM T_STUDENT LIMIT 20 OFFSET 0;
    -- 左右连接查询 需要使用LEFT OUTER JOIN 或 RIGHT OUTER JOIN
    SELECT * FROM T_STUDENT a LEFT OUTER JOIN T_CLASS_INFO b WHERE a.CLASS_ID=b.CLASS_ID;
    复制



    2

      本地代码调整


    2.1  建立本地数据库


    各环境的数据库正式迁移之前,需要先在本地的PostgreSQL数据库,建立一个新的系统数据库用于本地系统功能和业务测试。当本地测试的差不多了,就可以把脚本提供给DBA,交由DBA去创建各环境的 PostgreSQL数据库


    特别分享

    PostgreSQL重置密码步骤:

    1.  停服务(pg_ctl stop -D

    D:/app/pgsql/12/data -m immediate)

    2.  修改 pg_hba.conf 修改 加密方法

    3. sql alert 修改 postgre 的密码 (alter user postgres with password 'Password@123';)

    4.  pg_hba.conf 加密方法改回去

    5.  重新登录



    2.2  应用系统集成PostgreSQL


    数据库依赖:

      <dependency>
          <groupId>org.postgresql</groupId>
      <artifactId>postgresql</artifactId>
      <version>42.2.18</version>
      </dependency>
      复制



      系统中数据源配置参考:

        dataSourceClassName=驱动
        url=PostgreSQL数据库地址
        username=用户名
        password=密码
        minimumIdle=空闲连接最小数
        maximumPoolSize=最大允许线程数
        maxLifetime=存活时间
        leakDetectionThreshold=泄露检测
        connectionTimeout=连接超时时间
        复制



        2.3  迁移表结构


        首先需要将Oracle的所有表,索引,序列导出创建脚本,而后手动修改为PostgreSQL的创建脚本并在PostgreSQL中执行。有条件的小伙伴可以使用navicat premium的表结构和数据库同步功能完成自动迁移


        特别分享

        需要注意Oracle与PostgreSQL类型不同而导致脚本执行失败,这里举一些常用的差别。


        1.varchar类型和character varying类型


        Oracle中,定长的char类型大长度是2000,变长的varchar类型长度大是2000、 varchar2类型大长度是4000。



        PostgreSQL中,定长的char类型和变长的varchar类型的大长度都是1G(10485760),变 长的text类型则没有长度限制。



        总结:

        1.  在PostgreSQL中,text、char和varcahr的性能是没有区别的,大多数情况下使用text和varchar比较好;

        2.  character是全称,char是别名(简称);

        3.  character varying是全称,varchar是别名(简称);

        4. Oracle中较长的字段,可以用PostgreSQL中的character varying替代,长度是没问题的。



        2.number类型和numeric类型


        Oracle中,使用number类型来保存对精度要求高的数值,比如货币、金额等,对精度要求不高或没有要求的尽量不要用numeric类型,因为它的效率很低



        PostgreSQL中,与number类型对应的是numeric类型




        3.date类型和timestamp类型


        Oracle中,使用date类型来保存时间数据,如创建时间、修改时间



        PostgreSQL中,与date类型对应的是timestamp类型


        其他数据类型不再一一赘述,需要的同学可以自行深入学习。



        2.4  导入原有的表数据


        操作:首先将Oracle的数据导出excel等格式的数据文件,再手动导入PostgreSQL已创建好的表中。手动操作的方法需注意客户端字符集编码问题,避免引发数据乱码情况。不过,有条件的小伙伴可以使用navicat premium的表结构和数据库同步功能完成自动迁移。

        注意:数据导入的先后顺序,因为有的表数据通过逻辑外键关联,这些逻辑外键不允许为空。



        2.5  验证数据完整性


        为了数据的完整性,需要注意的是:

        1.  一开始系统使用表统计,是否统计的足够完整;

        2.  导入数据的时候顺序;

        3.  数据库迁移过程中,尽量避免使用系统服务,建议停机等到迁移完成后再启动系统服务;


        验证导入后的数据是否完整也比较简单:

        1.  观察数据导入时是否有日志异常;

        2.  将业务流程完整走一遍,看看数据是否查不到或者流程走不通;



        3

          测试环境验证



        验证流程:

        1.  系统整体功能回归测试;

        2.  代码性能监测;

        3.  系统性能测试;

        4.  申请测试环境数据库;

        5.  通知DBA、报表、运维,协调各方时间;


        输出:调整后的脚本



        4

          预生产验证



        验证流程:

        1.  UAT输出的表、序列等脚本创建数据库;

        2.  DBA导入生产数据,估算数据迁移时间;

        3.  PGSQL版本代码发布预生产验证功能;

        4.  通知业务用户禁止使用预生产操作;

        5.  验证后清理PGSQL;


        输出:

        1.  确认数据库迁移可行性

        2.  估算PG库数据迁移时间

        3.  与DBA、运维、业务用户确定数据库切换时间点



        5

          生产库切换



        因实际生产库切换操作主要由DBA人员完成,开发主要协助验证,故在此仅简单介绍下协助流程


        切换流程:

        1.  通知业务用户禁止使用生产环境、预生产环境;

        2.  DBA导入数据、创建序列,设置序列值等;

        3.  确认源数据库与目标数据库数据量、序列值是否一致;

        4.  正常发布PGSQL版应用系统程序,验证基本功能;

        5.  观察生产运行数据。



        结束语

        本篇简略描述了Oracle迁移PostgreSQL数据库的流程,希望可以给有需要的小伙伴带来帮助。笔者也正在整理Oracle与PostgreSQL在数据类型,关键字,存储过程,函数,触发器等方面的差异,后续会继续分享给大家,谢谢关注。



        文 | 李明亮

        编辑 | 阿斗、西林阿门

        设计 | 橙子、Linda、玉米



        //   END 



        往期文章

        健康险的前世今生

        基于ZooKeeper的应用主备切换方案

        Flink车险定价运用实践

        保险的起源

        【Vlog剪辑】记录不一样的你

        电销接触方式的演变



        文章转载自保险技术黑板报,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论