欢迎阅读关于将 Oracle 迁移到 Postgres 迁移的四部分博客系列的第 2 部分。我很高兴让您知道该系列的第一篇文章——宣布针对 Azure 的新 Oracle 到 Postgres 迁移指南——获得了 1000 次浏览,并出现在第 389 版 Postgres 周刊通讯中。我很高兴你们中的许多人亲自给我发消息,让我知道迁移指南正在帮助您的迁移项目。感谢您的所有反馈。
Oracle 到 Postgres 的迁移是困难的、多步骤的项目,尤其是对于复杂的应用程序。根据我与那些已经完成 Oracle 到 Postgres 迁移(特别是迁移到我们的 Azure Database for PostgreSQL 托管服务)的人合作的经验,你们中的许多人将整个迁移项目的 60% 以上用于转换(步骤 4)和迁移(步骤 6)阶段。在这个 Oracle 到 Postgres 迁移系列的第一篇文章中,我深入探讨了 Oracle 到 Postgres 迁移的不同步骤。本着同样的精神,让我们深入研究一些实际示例,了解我们的 Oracle 到 Postgres 迁移指南如何帮助您迁移数据库存储对象。

什么是数据库存储对象?
关系数据库中定义数据如何存储、表示和访问的任何对象都是数据库存储对象。数据库存储对象包括:模式、表、类型、约束、索引、序列、视图、同义词、数据库链接等。虽然这些对象中的每一个在 Postgres 中可能意味着不同的东西(与 Oracle 相比),但了解这些对象很重要将这些对象中的每一个从 Oracle 数据库迁移到 Postgres 的最佳实践。
在这篇文章中,您将了解:
1.移动其中一些数据库对象的最佳实践,摘自迁移指南
2.我最喜欢的一些需要注意的例子。在迁移其中一些数据库存储对象时,我已经多次烧伤手指。我不希望你也必须烧伤你的手指。 :笑脸:
好消息是,与更复杂的数据库对象(如包、函数、过程等)(通常称为数据库代码对象)相比,将数据库存储对象从 Oracle 转换/迁移到 Postgres 相对容易。我们在 Oracle 到 Postgres 迁移中使用的开源工具之一是出色的 Ora2Pg 实用程序。如果您还不熟悉,Ora2Pg 是一个免费的开源工具,用于将 Oracle 数据库迁移到与 PostgreSQL 兼容的模式。 Ora2pg 在自动转换 DB 存储对象方面做得很好,并且多年来已经改进了很多,以适应这些存储对象的不同组合。成功迁移的关键在于了解如何转换这些数据库存储对象,了解 Ora2pg 为什么以某种方式进行转换,并确保转换后的工作负载在 Postgres 中以最佳方式工作。
Oracle 与 Postgres 中的模式有何不同?
让我们马上来看一个例子。在 Oracle 中,用户和模式本质上是一回事。创建用户时(使用“create user”命令),Oracle 还会创建一个模式容器来保存用户创建的所有对象。而在 Postgres 中,用户创建的所有对象都需要在数据库中的模式中显式创建。所有 Postgres 用户本身对于整个服务器都是全局的。这篇关于 Oracle 与 Postgres 中模式的博文很好地描述了这种差异。
你基本上是从 –
|------------------------------------------|
| Oracle server |
|------------------------------------------|
| Database 1 | Database 2 | DATABASE
|---------------------|---------------------|
| User 1 | User 2 | User 1 | User 2 | USERS/SCHEMAS
|----------|----------|----------|----------|
| t1,t2,t3 | t1,t2,t3 | t1,t2,t3 | t1,t2,t3 | TABLES
到
|--------------------------------------------------|—|
| PostgreSQL instance | |
|--------------------------------------------------| U |
| Database 1 | Database 2 | S |
|-------------------------|------------------------ | E |
| Schema 1 | Schema 2 | Schema 1 | Schema 2 | R |
|------------|------------|------------|------------| S |
| t1,t2,t3 | t1,t2,t3 | t1,t2,t3 | t1,t2,t3 | |
进行数据库级别更改(例如上面的模式示例)时要考虑的首要事项是:
- 您的前端应用程序是否可以使用上述更改?如果没有,你需要改变什么?一些应用程序与 ORM 层接口,使这些数据库/模式级别的更改易于接受。您可能需要重新架构一些应用程序以适应这种范式转变。
- 通过这些类型的数据库级别更改,您是否要从应用程序中获得所需的性能并满足您的 SLA?这几乎总是在转换练习结束时通过彻底的测试来回答。最终,一旦数据迁移完成,测试整个堆栈也是有意义的。
归根结底,Oracle 和 Postgres 之间基于模式的语义完全不同。因此,您必须弄清楚您的应用程序是否会在不同的架构下按预期工作,或者您是否需要对应用程序进行一些调整。不过不要担心——一旦掌握了这些差异并加以实施,就非常容易。
鉴于模式和用户在 Oracle 中是相同的,有多个问题需要处理。在 Oracle 到 Postgres 迁移指南第 61 页的从 Oracle 安全模型迁移一章中给出了所有这些带有上述示例的问题。
关于数字与 BIGINT 的有趣故事
在迁移表时,Oracle 和 PostgreSQL 之间的数据类型差异占据了很大的份额。在我告诉您在哪里可以找到有关表分区、从 Oracle 迁移索引组织表等的详细信息之前,让我带您通过数据类型的实践经验来向您展示测试每个转换的重要性。
Oracle 拥有一组非常丰富的与数字相关的数据类型(例如 INT、DOUBLE、FLOAT 等),能够存储规模和精度。但是,当查询 Oracle 字典表以获取每个表列的数据类型的详细信息时,Oracle 将这些数字子类型中的每一个存储为具有适当比例和精度的 NUMBER。有时,无论子类型是什么,这些列都会在转换过程中转换为数字。
好吧,这是踢球者。在 Oracle 中,最大数字数据类型包含 38 位。在 Postgres 中,最大的数字数据类型可以容纳 131,072 位。如果您不遵循 Oracle 到 Postgres 迁移指南中的提示和最佳实践——并且如果 Oracle 中此数字列上的主键索引被转换为 Postgres 中的数字——您将在 Postgres 中付出性能损失。好消息是,我们的 Oracle 到 Postgres 迁移指南的“数据类型转换”部分中的数据类型迁移最佳实践将帮助您避免这样的陷阱。
试验数字类型
让我们做一个有趣的实验,看看在 Postgres 中为数字列创建索引与在 BIGINT 列上创建索引的影响。在下面的示例中,我创建了 2 个包含两列的表,一个 ID 设置为数字,另一个 ID 设置为 BIGINT。我在每个中插入 1M 行,并比较对两者进行自联接计数需要多长时间。
CREATE TABLE public.arthiaga_numeric(id numeric NOT NULL, name character varying(200));
#Insert 1M rows
INSERT INTO public.arthiaga_numeric(id, name)
SELECT generate_series(1,1000000), md5(random()::text);
INSERT 0 1000000
Query returned successfully in 3 secs 585 msec.
#Add primary key
ALTER TABLE public.arthiaga_numeric ADD PRIMARY KEY(id);
ALTER TABLE
Query returned successfully in 1 secs 262 msec.
#Do a self-join count
select count(*) from public.arthiaga_numeric a, public.arthiaga_numeric b where a.id=b.id;
Successfully run. Total query runtime: 1 secs 123 msec.
尝试 BIGINT
#Insert 1M rows
INSERT INTO public.arthiaga_bigint(id, name)
SELECT generate_series(1,1000000), md5(random()::text);
INSERT 0 1000000
Query returned successfully in 3 secs 710 msec.
#Add primary key
ALTER TABLE public.arthiaga_bigint ADD PRIMARY KEY(id);
ALTER TABLE
Query returned successfully in 1 secs 107 msec.
#Do a self-join count
select count(*) from public.arthiaga_bigint a, public.arthiaga_bigint b where a.id=b.id;
Successfully run. Total query runtime: 1 secs 3 msec.
对于具有两个基本列的百万行表,当我在 BIGINT 列而不是 PostgreSQL 中的数字列上创建索引时,您已经看到查询响应时间提高了 11%。 如你看到的 -
| 使用 BIGINT 对 1M 行表进行计数查询 | 在 1.003 秒内完成 |
|---|---|
| 对 1M 行表使用 NUMERIC 计数查询 | 在 1.123 秒内完成 |
想象一下,您需要为更大、更复杂的表结构支付性能损失。想象一下,当工作负载中的多个表的查询响应时间很长时,端到端的性能影响。我鼓励你在更大更复杂的表上尝试这个实验,以自己看到更大的性能提升。对于某些工作负载,我们仅通过在 Postgres 中切换到使用正确的数据类型,就可以测量到查询响应时间的非常高的改进(超过 80%)。
要知道的关键是,从表迁移的角度来看,从 Oracle 迁移到 Postgres 时,您应该关注数据类型、分区方案、索引、约束、LOB、临时表、序列等。您可以在 Oracle 到 Postgres 迁移指南中了解所有这些方面。
接下来,让我们根据我将 Oracle 中的数据库存储对象迁移到 Postgres 迁移的经验,再看一些我最喜欢的知识。
Postgres中的NULL,有人吗?
与 Oracle 相比,Postgres 以完全不同的方式处理字符串中的 NULL——句号!我强烈建议您注意并更新您的 SQL 查询,以适应 NULL 处理中的细微差别。为避免在切换阶段出现最后一分钟的问题,您肯定希望在流程的早期进行测试(并测试和测试)。如果您从典型的 Oracle 工作负载迁移,您很有可能会在 Oracle 处理字符串中的 NULL 与 Postgres 的方式中遇到这个问题。让我们看一个例子。
让我们使用上面为这个实验创建的同一张表。我将删除主键并向上面的其中一个表添加一个复合唯一约束,以保持解释简单。
#Add composite unique constraint across columns
alter table public.arthiaga_bigint add constraint uniq_bigint unique (id, name);
#Insert more rows
INSERT INTO public.arthiaga_bigint(id, name) VALUES (1, 'Arun');
INSERT INTO public.arthiaga_bigint(id) VALUES (2);
INSERT INTO public.arthiaga_bigint(id) VALUES (2);
INSERT INTO public.arthiaga_bigint(id) VALUES (3);
INSERT INTO public.arthiaga_bigint(id) VALUES (3);
#Table select
select * from public.arthiaga_bigint;

图 1:由于 NULL 在 PostgreSQL 中的非唯一性。
猜猜选择返回什么,尽管有唯一的约束?
- 鉴于 Oracle 支持空比较,Oracle 中的重复插入将失败。
- 在 Postgres 中,两个空值不相同,因此尽管有唯一约束,但重复插入没有问题。
因此,当您迁移到 Postgres 时,您需要在应用程序中处理此类异常。如果你不在你的应用程序中处理这些异常,你会遇到很多惊喜。
同一点也适用于字符串中的 NULL:Postgres 不支持字符串中的 NULL,而 Oracle 支持。
Postgres 与 Oracle 中的序列缓存
Oracle 在数据库中的多个用户会话之间共享一个序列缓存。在 PostgreSQL 中,序列缓存不跨会话共享,而是在每个会话级别。
这篇关于解释 Oracle 与 Postgres 中的序列缓存行为差异的博文在通过示例展示这种行为方面做得很好。在示例中,Postgres 中的任何新会话都将获得其自己的一组特定序列范围的缓存值。而在 Oracle 中,序列是跨会话共享的。如果您的应用程序依赖于序列的共享缓存值,考虑到这种差异,最好考虑更改应用程序本身的设计。
虽然这些只是基于我的经验的几个示例,但 Oracle 到 Azure Database for PostgreSQL 迁移指南深入介绍了数据库存储对象转换主题。
备忘单:在迁移指南中哪里可以找到有关数据库存储对象的信息
这份关于在我们的 Oracle 到 Postgres 迁移指南中哪里可以找到有关数据库存储对象的详细信息的备忘单应该很有用:
- 具有最佳实践的数据类型转换——从第 241 页开始。
- 分区方案 - 从第 198 页开始。
- 索引 – 从第 294 页开始。
- 约束——从第 184 页开始。
- LOB – 从第 223 页开始。
- 临时表 – 从第 171 页开始。
- 序列——从第 252 页开始。
- 表空间——从第 76 页开始。
- 用户定义的类型——从第 270 页开始。
如您所见,本指南有很多内容并且经常改进。虽然这些页码在本指南的未来版本中可能会发生变化,但您仍然可以搜索上面列出的章节。
如果您希望从 Oracle 迁移到 Postgres,这里有一些链接和资源
现在你有:
- 在这个 Oracle 到 Postgres 博客系列的第 1 部分中看到了迁移过程的样子,以及
- 在第 2 部分博客文章中获得了将数据库存储对象迁移到 Postgres 的概要
您可能还想查看 Oracle 到 Azure Database for PostgreSQL 迁移指南。让我知道它是否有用。特别是让我知道您是否找到了使其更加有用的方法。
如果您想讨论迁移到 PostgreSQL 的一般情况,或者对我们在 Azure 上的 PostgreSQL 托管服务有疑问,您可以随时通过 Ask AzureDB for PostgreSQL 的电子邮件联系我们的产品团队。我也喜欢我们 Twitter 句柄 (@AzureDBPostgres) 上的所有更新,并建议关注我们以获取更多 Postgres 新闻和更新。我们很想听到您的声音。
学的开心!
原文标题:Migrating database storage objects from Oracle to Postgres
原文作者:Arun Kumar Thiagarajan
原文地址:https://techcommunity.microsoft.com/t5/azure-database-for-postgresql/migrating-database-storage-objects-from-oracle-to-postgres/ba-p/2117312




