【问题标题】:Synchronize data from Oracle to PostgreSQL将数据从 Oracle 同步到 PostgreSQL
【发布时间】:2018-11-29 15:41:53
【问题描述】:

我们希望将数据(插入、更新)从 Oracle (11g) 同步到 PostgreSQL (10)。我们的方法如下:

  • Oracle 中表的触发器在插入和更新之前使用序列中的 nextval 更新列。
  • PostgreSQL 知道最后处理的序列号并从 Oracle > lastSequenceNumberFetched 获取行。

我们现在有以下问题:

  • Oracle 中的会话 1 插入一行,写入序列号(比如 45),但在 Oracle 中未执行任何 COMMIT。
  • Oracle 中的会话 2 插入一行,写入序列号(假设为 49(因为 Oracle 中的序列可能有间隙))并在 Oracle 中完成 COMMIT。
  • PostgreSQL 中的会话从 Oracle 中获取 sequenceNumber > 44 的行(因为 lastSequenceNumberFetched 为 44)并获取 sequenceNumber 为 49 的行。所以这是新的 lastSequenceNumberFetched。
  • Oracle 中的会话 1 进行提交。
  • PostgreSQL 中的会话从 Oracle 获取序列号 > 49 的行。问题是序列号为 45 的行永远不会被获取。

对于我们的用例是否有更好的方法来避免我们的数据丢失问题?

【问题讨论】:

标签: database oracle postgresql data-synchronization


【解决方案1】:
  1. 如果您的表中没有删除操作并且表不是很大,那么我建议在伪列 @987654322 返回的行级别上使用 Oracle 系统更改号 (SCN) @ (link)。这是由数字表示的提交时间。默认情况下跟踪数据块的 SCN,但您可以在行级别启用跟踪(关键字 rowdependencies)。所以你必须用这个关键字重新创建你的表。在同步过程启动时,您通过函数调用dbms_flashback.get_system_change_number 获取当前scn,然后扫描所有表where ora_rowscn between _last_scn_value_ and _current_scn_value_。缺点是这个伪列没有索引,所以你会进行全表扫描,这对于大表来说很慢。

  2. 如果您使用删除语句,那么您必须跟踪被删除的记录。为此,您可以使用一个具有以下列的日志表:table_name、table_id_value、操作(插入/更新/删除)。表由基表上的触发器填充。因此,对于您的情况,当会话 1 提交基表中的数据时,您就可以处理日志表中的记录。在会话提交之前您不会看到它。所以你描述的序列号没有问题。

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    这纯粹是一个数据项目还是你有一些客户在这里。如果你确实有一个中间层,你可以使用 ORM 来抽象其中的一些并对两者进行写入。你关心序列是否相同吗?可以做一些事情,比如收集所有数据以从特定时间戳开始同步(每个表都必须有一个 UTC 时间戳),然后对所有数据进行哈希处理并与 Postgres 中的内容进行比较。

    如果您有更多关于数据同步的要求及其背后的原因,可能会很有用,例如

    两种环境的密钥是否需要相同?为什么? 查看数据的人是查看两个数据源的同一消费者。 为什么不只使用 ORM 只针对一个 db 为什么需要 oracle 和 postgres?

    【讨论】:

      【解决方案3】:

      我见过类似的设置。 Postgres 上的应用程序主要用于报告和其他次要任务,而主要应用程序在 Oracle 上。

      为方便起见,一些主要的应用程序表被缓存在 Postgres 中。但是这种设置会带来同步问题。

      折衷的解决方案是白天基于增量序列的同步和夜间全表复制的混合

      关于这里提出的其他解决方案:

      • 对于复杂的查询,Postgres fdw 速度很慢,并且会给外部数据库带来额外的负载,尤其是当 where 子句同时引用本地和外部表时。
        如果外部表缓存在 postgres 中,相同的查询将运行得更快。

      • 使用序列号的增量/差分同步 - 尝试过这个方法并且适用于小表,但噩梦从子关系开始,也许 orm 可以在这里提供帮助

      • 在我看来,理想的解决方案可能是将 Oracle 更改流式传输到 Postgres 或将更改复制到 Postgres 的中间进程

      我不知道如何执行此操作,因为我知道它需要 Oracle Golden Gate 应用程序(+ 许可证)

      【讨论】:

        猜你喜欢
        • 2012-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多