View a markdown version of this page

将 Oracle SERIALLY_可重复使用的 Pragma 包迁移到亚马逊 Aurora 或适用于 PostgreSQL 的亚马逊 RDS - AWS 规范指引

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

将 Oracle SERIALLY_可重复使用的 Pragma 包迁移到亚马逊 Aurora 或适用于 PostgreSQL 的亚马逊 RDS

Vinay Paladi,Amazon Web Services

Summary

此模式提供了一种分步方法,用于将使用 SERIALLY_REPLAGMA 的 Oracle 包迁移到亚马逊 Aurora Ed PostgreSQL-Compatible ition 或 Amazon RDS for PostgreSQL,同时保持 AWS原始功能。

PRAGMA SERIALLY_REPLIAGE 表示只有在一次调用服务器时才需要包状态(例如, PL/SQL 匿名块或通过数据库链接调用存储过程)。在此调用之后,可以重复使用包变量的存储空间,从而减少内存消耗。

PostgreSQL 本身不支持 SERIALLY_RESULATY Pragma 的概念。为了实现同等功能,此模式使用包装函数方法与 AWS Database Migration Service (AWS DMS) 架构转换 (AWS DMS SC) 功能相结合来迁移软件包结构。提供的示例脚本演示了如何在 PostgreSQL 中保留每次调用时重置的行为。

有关更多信息,请参阅 Oracle 文档中的 SERIALLY_REUSABLE Pragma

先决条件和限制

  • 活跃的 AWS 账户

  • 访问 AWS DMS 架构转换服务

  • 亚马逊 Aurora PostgreSQL-Compatible 版数据库或亚马逊 RDS for PostgreSQL 数据库

  • 甲骨文数据库版本 10g 或更高版本

架构

源技术堆栈

  • On-premises 甲骨文数据库

目标技术堆栈

迁移架构

将 Oracle SERIALLY_可重复使用的 Pragma 包迁移到亚马逊 Aurora 或适用于 PostgreSQL 的亚马逊 RDS

工具

AWS 服务

其他工具

  • pgAdmin 是一种适用于 PostgreSQL 的开源管理工具。它提供了一个图形界面,可帮助您创建、维护和使用数据库对象。

最佳实践

  • 始终reset_vars = 1用于顶级呼叫和reset_vars = 0内部子调用。

  • $init函数中的所有默认值保留为单一事实来源。

  • 匹配 PostgreSQL 中的 Oracle 变量名称以实现可追溯性。

  • 通过将 Oracle DBMS_OUTPUT 与 Po RAISE NOTICE stgreSQL 的输出进行比较来进行验证。

  • 在单独的 PostgreSQL 会话中进行测试,以确认在两次调用之间重置变量。

操作说明

Task说明所需技能

设置 AWS DMS SC。

配置与源数据库的 AWS DMS 连接。有关更多信息,请参阅使用 DMS 架构转换转换数据库架构

数据库管理员、开发人员

转换脚本。

使用 AWS DMS SC 通过选择目标数据库作为 Aurora 来转换 Oracle 软件包 PostgreSQL-Compatible。

数据库管理员、开发人员

保存 .sql 文件。

在保存.sql 文件之前,请将 S AWS DMS C 中的 “项目设置” 选项修改为 “每阶段单个文件”。这配置 AWS DMS 为根据对象类型将.sql 文件分成多个.sql 文件。

数据库管理员、开发人员

更改代码。

打开 AWS DMS SC 生成的init函数,然后按照 “其他信息” 部分的示例所示对其进行更改。它将添加一个变量来实现 reset_vars = 0 功能。

数据库管理员、开发人员

测试转换。

init函数部署到 Aurora PostgreSQL-Compatible 数据库,然后测试结果。

数据库管理员、开发人员

问题排查

问题解决方案

访问包变量时出现字段不存在错误。

确保$init函数条件使用的IF v_need_init变量始终是在会话中首次访问时创建的。reset_vars = 1

变量不会在顶级调用之间重置,也不会在内部子调用期间意外重置。

reset_vars = 1用于直接的顶级调用,reset_vars = 0用于内部函数到函数的调用。

相关资源

附加信息

-------Source Oracle Code: CREATE OR REPLACE PACKAGE test_pkg_var IS PRAGMA SERIALLY_REUSABLE; PROCEDURE function_1(test_id NUMBER); PROCEDURE function_2(test_id NUMBER); END; / CREATE OR REPLACE PACKAGE BODY test_pkg_var IS PRAGMA SERIALLY_REUSABLE; v_char VARCHAR2(20) := 'DEFAULT_VALUE'; v_num NUMBER := 123; PROCEDURE function_2(test_id NUMBER) IS BEGIN dbms_output.put_line('function_2 => v_char=' || v_char || ', v_num=' || v_num); END; PROCEDURE function_1(test_id NUMBER) IS BEGIN dbms_output.put_line('function_1 => v_char=' || v_char || ', v_num=' || v_num); v_char := 'MODIFIED_VALUE'; dbms_output.put_line('function_1 => v_char after update=' || v_char); function_2(0); END; END test_pkg_var; / SET SERVEROUTPUT ON EXEC test_pkg_var.function_1(1); EXEC test_pkg_var.function_2(1); ------Target PostgreSQL Code: CREATE SCHEMA IF NOT EXISTS testoracle; CREATE OR REPLACE FUNCTION testoracle.test_pkg_var$init(reset_vars IN INTEGER DEFAULT 0) RETURNS void AS $BODY$ DECLARE v_need_init BOOLEAN; BEGIN v_need_init := aws_oracle_ext.packageinitialize(proutinename => 'testoracle.test_pkg_var'); IF v_need_init OR reset_vars = 1 THEN PERFORM aws_oracle_ext.setglobalvariable(proutinename => 'testoracle.test_pkg_var', pvariable => 'v_char', pval => 'DEFAULT_VALUE'::CHARACTER VARYING(20)); PERFORM aws_oracle_ext.setglobalvariable(proutinename => 'testoracle.test_pkg_var', pvariable => 'v_num', pval => 123); END IF; END; $BODY$ LANGUAGE plpgsql; CREATE OR REPLACE PROCEDURE testoracle.test_pkg_var$function_1(reset_vars INT DEFAULT 1) AS $BODY$ BEGIN PERFORM testoracle.test_pkg_var$init(reset_vars); RAISE NOTICE 'function_1 => v_char=%, v_num=%', aws_oracle_ext.getglobalvariable(proutinename => 'testoracle.test_pkg_var', pvariable => 'v_char', ptp => NULL::CHARACTER VARYING(20)), aws_oracle_ext.getglobalvariable(proutinename => 'testoracle.test_pkg_var', pvariable => 'v_num', ptp => NULL::DOUBLE PRECISION); PERFORM aws_oracle_ext.setglobalvariable(proutinename => 'testoracle.test_pkg_var', pvariable => 'v_char', pval => 'MODIFIED_VALUE'::CHARACTER VARYING(20)); RAISE NOTICE 'function_1 => v_char after update=%', aws_oracle_ext.getglobalvariable(proutinename => 'testoracle.test_pkg_var', pvariable => 'v_char', ptp => NULL::CHARACTER VARYING(20)); CALL testoracle.test_pkg_var$function_2(0); END; $BODY$ LANGUAGE plpgsql; CREATE OR REPLACE PROCEDURE testoracle.test_pkg_var$function_2(reset_vars INT DEFAULT 1) AS $BODY$ BEGIN PERFORM testoracle.test_pkg_var$init(reset_vars); RAISE NOTICE 'function_2 => v_char=%, v_num=%', aws_oracle_ext.getglobalvariable(proutinename => 'testoracle.test_pkg_var', pvariable => 'v_char', ptp => NULL::CHARACTER VARYING(20)), aws_oracle_ext.getglobalvariable(proutinename => 'testoracle.test_pkg_var', pvariable => 'v_num', ptp => NULL::DOUBLE PRECISION); END; $BODY$ LANGUAGE plpgsql; CALL testoracle.test_pkg_var$function_1(1); -- loads defaults, sets v_char='MODIFIED_VALUE', function_2 sees 'MODIFIED_VALUE' CALL testoracle.test_pkg_var$function_2(1); -- new transcation: PRAGMA reset, sees 'DEFAULT_VALUE'