如何在 postgresql 中使用 postgres_fdw 从另一个数据库中获取记录

Posted

技术标签:

【中文标题】如何在 postgresql 中使用 postgres_fdw 从另一个数据库中获取记录【英文标题】:How to fetch records from another database using postgres_fdw in postgresql 【发布时间】:2019-07-08 14:05:28 【问题描述】:

我已经连接到另一个 GP DB 以将数据导入我的 PostgreSQL 表并编写 Java 调度程序以每天刷新它。但是当我每天尝试使用 SQL 函数获取记录时,它给了我一个错误Greenplum Database does not support REPEATABLE READ transactions。那么,任何人都可以建议我如何将数据从 GP 频繁加载到 postgres 而不会出现隔离问题。

我知道要执行刷新表

START TRANSACTION ISOLATION LEVEL SERIALIZABLE;

但是,由于交易阻塞,我无法在函数中使用相同的功能。

【问题讨论】:

如果您能提供更多详细信息,那将会很有趣。您是通过 jdbc 驱动程序连接到 greenplum 来导入数据吗?您是否尝试按照 java 文档中的描述设置 jdbc 事务隔离?错误发生在流程的哪个步骤? (docs.oracle.com/javase/8/docs/api/java/sql/…) 嗨@Filipe 以前我使用java JDBC connectionn 连接到GP DB 并获取数据并用于在postgres 中插入相同的数据。但是现在,我正在使用 postgres_fdw 建立连接来导入数据。但是在这里成功连接后,我可以一次读取数据。下次它给我“Greenplum 数据库不支持可重复读取事务”错误,因为 postgres_fdw 的隔离级别是重复读取但对于 GP 隔离级别是已提交的。我们可以通过 'START TRANSACTION ISOLATION LEVEL SERIALIZABLE' 实现一个,我不希望它是everytm 是否可以在 Greenplum 端使用“COPY INTO”,在 Postgres 端使用“COPY FROM”? postgresql.org/docs/9.2/sql-copy.htmlgpdb.docs.pivotal.io/530/admin_guide/load/topics/… 【参考方案1】:

与使用锁和闩锁进行并发控制的 Oracle 数据库不同,Greenplum 数据库(与 PostgreSQL 一样)通过使用多版本模型(Multiversion Concurrency Control,MVCC)来维护数据一致性。这意味着在查询数据库时,每个事务都会看到数据快照,从而保护事务不会查看可能由相同数据行上的(其他)并发更新引起的不一致数据。这为每个数据库会话提供了事务隔离。简而言之,读者不会阻止作者,作者也不会阻止读者。每个事务都会看到数据库的快照,而不是锁定表。 事务隔离级别

SQL 标准定义了四个事务隔离级别。在 Greenplum 数据库中,您可以请求四种标准事务隔离级别中的任何一种。但在内部,只有两种不同的隔离级别——读提交和可序列化:

    已提交读 — 当事务在此隔离级别上运行时,SELECT 查询只会看到查询开始之前已提交的数据。它永远不会看到未提交的数据或并发事务在查询执行期间提交的更改。但是,SELECT 确实会看到在其自己的事务中执行的先前更新的效果,即使它们尚未提交。实际上,SELECT 查询会在查询开始运行的那一刻看到数据库的快照。请注意,如果其他事务在第一个 SELECT 执行期间提交更改,则两个连续的 SELECT 命令可以看到不同的数据,即使它们在单个事务中也是如此。 UPDATE 和 DELETE 命令在搜索目标行方面的行为与 SELECT 相同。他们只会找到在命令开始时间提交的目标行。但是,这样的目标行在找到时可能已经被另一个并发事务更新(或删除或锁定)。读提交模式提供的部分事务隔离对于很多应用来说已经足够了,而且这种模式使用起来既快速又简单。但是,对于执行复杂查询和更新的应用程序,可能需要保证比读取提交模式提供的数据库视图更严格一致。

    serializable — 这是最严格的事务隔离。此级别模拟串行事务执行,就好像事务已一个接一个地连续执行,而不是同时执行。由于序列化失败,使用此级别的应用程序必须准备好重试事务。当事务处于可序列化级别时,SELECT 查询只会看到事务开始之前提交的数据。它永远不会看到未提交的数据或并发事务在事务执行期间提交的更改。但是,SELECT 确实会看到在其自己的事务中执行的先前更新的效果,即使它们尚未提交。单个事务中的连续 SELECT 命令总是看到相同的数据。 UPDATE 和 DELETE 命令在搜索目标行方面的行为与 SELECT 相同。他们只会找到在事务开始时提交的目标行。但是,这样的目标行在找到时可能已经被另一个并发事务更新(或删除或锁定)。在这种情况下,可序列化事务将等待第一个更新事务提交或回滚(如果它仍在进行中)。如果第一个更新程序回滚,则其影响被否定,可序列化事务可以继续更新最初找到的行。但是如果第一个更新程序提交(并且实际上更新或删除了该行,而不仅仅是锁定它),那么可序列化事务将被回滚。

    read uncommitted — 与 Greenplum 数据库中已提交的读取相同。

    可重复读取 — 在 Greenplum 数据库中被视为可序列化。

Greenplum 数据库中默认的事务隔离级别是读提交的。要更改事务的隔离级别,可以在开始事务时声明隔离级别,或者在事务启动后使用 SET TRANSACTION 命令。

enter link description here

【讨论】:

以上是关于如何在 postgresql 中使用 postgres_fdw 从另一个数据库中获取记录的主要内容,如果未能解决你的问题,请参考以下文章

如果我们重新启动 postgres,如何重新启动后台工作人员 postgresql?

如何在 PostgreSQL 11.1 中将现有列更改为身份

如何优化 Postgresql max_connections 和 node-postgres 连接池?

如何在Debian 8/7上安装PostgreSQL 9.6

从Postgres95到PostgreSQL9.5:新版亮眼特性

Docker - 如何在postgres容器中运行psql命令?