Postgres永远复制

时间:2017-11-06 16:19:15

标签: postgresql postgresql-9.6

我有一个程序会使用COPY FROM或多或少连续地通过stdin将大量数据复制到Postgres 9中。

这目前工作正常,但我正在缓冲数据块,然后批量运行COPY FROM操作。

我很想知道,在环顾四周之后无法找到,仅仅创建COPY FROM流并且在我的程序终止之前永远不会关闭它是不是一个坏主意。在我的程序正在运行并接受新数据时,我想打开COPY FROM并在其生命周期内不断地传输该数据。

我正在寻找Postgres结尾的内部机制:

  • COPY FROM操作是否在内部创建了一个事务?
  • 相关:我可以立即访问其他会话的数据流吗?
  • Postgres是否有任何内部机制会导致这种情况不起作用(即某些内部状态会在没有例行关闭COPY FROM流的情况下溢出)?

注意:我知道类似的注意事项也适用于我使用的客户端驱动程序,但我认为(可能不正确)客户端的选择不会改变我所做的事情。关于Postgres方面的问题。如果可能的话,我想特别关注Postgres。

1 个答案:

答案 0 :(得分:3)

  

COPY FROM操作是否在内部创建了一个事务?

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

  

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

-

  

相关:我可以立即访问其他会话的数据流吗?

不,永远不会出现未提交的数据对其他交易可见的情况。在SQL术语中,这将被称为"脏读",并且在Postgres ref中是不可能的。

  

Postgres是否有任何内部机制会导致这种情况不起作用(即某些内部状态会在没有常规关闭COPY FROM流的情况下溢出)?

没有什么会直接阻止你这样做。但总的来说,保持交易相对较短以与系统的其他部分合作被认为是一种好的做法。如果您让COPY FROM语句挂出数小时,您将对VACUUM能够完成其工作ref产生影响。

要考虑的另一个方面是锁定影响。如果您在表上建立了主键,唯一索引或其他约束(您应该!),Postgres将理解您COPY所在的行在提交之前保持行级锁定。我们假设您COPY连续使用unique_column =' abc123',您可以将此语句挂出数小时。如果其他人出现并尝试COPYINSERT一行也有unique_column =' abc123',他将被阻止,直到您的COPY FROM交易最终提交为止。这种行为可能会导致整个系统中阻塞事务的连锁效应,并在最坏的情况下使数据库停止运行,尤其是当您COPY进入的表被其他编写者严重争议时。