Postgres从COPY永久导入

3
我有一个程序会通过stdin不断地将大量数据复制到Postgres 9中,使用COPY FROM。目前这个方法运行良好,但是我正在缓冲数据块并批量运行COPY FROM操作。
我在想,看了一圈也没找到答案,是否让COPY FROM流一直保持打开状态直到程序终止是个坏主意。我的意思是,在我的程序运行并接受新数据时,我想打开一个COPY FROM并不断地流传这些数据。
我想知道Postgres的内部机制:
  • COPY FROM操作是否在内部创建一个事务?
  • 相关问题:我正在流传的数据是否可以立即被其他会话访问?
  • Postgres是否有任何内部机制会导致这种方式不起作用(例如某些内部状态会因为没有定期关闭COPY FROM流而溢出)?
注意:我知道类似的考虑也适用于我使用的客户端驱动程序,但我假设(可能不正确)客户端的选择不会改变我关于Postgres方面的问题。如果可能,我想把这个问题集中在Postgres上。
1个回答

3

COPY FROM操作会在内部创建一个事务吗?

在Postgres中,每个SQL语句,包括COPY FROM,都将成为更大的事务的一部分,或者将被自身包含在一个事务中。ref:

实际上,PostgreSQL将每个SQL语句视为在事务中执行。如果您不发出BEGIN命令,则每个单独的语句都有一个隐式的BEGIN和(如果成功)COMMIT包装。由BEGIN和COMMIT包围的一组语句有时称为事务块。

--

相关:我正在流式传输的数据是否会立即对其他会话可见?

不,未提交的数据永远不会对其他事务可见。在SQL术语中,这被称为“脏读取”,在Postgresref中不可能发生。

Postgres是否有任何内部机制会导致此操作无法正常工作(例如,一些内部状态会在不定期关闭COPY FROM流之前溢出)?

没有什么会直接阻止您这样做。但通常,将事务保持相对较短以与系统的其余部分合作被视为最佳实践。如果让一个COPY FROM语句挂起数小时,将会对VACUUM执行其工作产生影响ref

另一个需要考虑的方面是锁定影响。如果在表上建立了主键、唯一索引或其他约束(应该这样做!),Postgres 将知道您正在 COPY 的行保持行级锁定,直到它们提交。假设您正在 COPY 一行,并且 unique_column='abc123',并且您让此语句挂起数小时。如果有人试图 COPYINSERT 具有 unique_column='abc123' 的行,则他将被阻塞,直到您的 COPY FROM 事务最终提交。这种行为可能会在整个系统中产生阻塞事务的连锁反应,并在最坏的情况下使数据库停滞不前,特别是如果您要 COPY 的表被其他编写者大量争用。

好的,谢谢。我会继续缓冲我的块数据。很遗憾这个方法不可行,但是通过您的解释,我明白了原因。 - jssblck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接