我有一个程序会使用COPY FROM
或多或少连续地通过stdin将大量数据复制到Postgres 9中。
这目前工作正常,但我正在缓冲数据块,然后批量运行COPY FROM
操作。
我很想知道,在环顾四周之后无法找到,仅仅创建COPY FROM
流并且在我的程序终止之前永远不会关闭它是不是一个坏主意。在我的程序正在运行并接受新数据时,我想打开COPY FROM
并在其生命周期内不断地传输该数据。
我正在寻找Postgres结尾的内部机制:
COPY FROM
操作是否在内部创建了一个事务?COPY FROM
流的情况下溢出)?注意:我知道类似的注意事项也适用于我使用的客户端驱动程序,但我认为(可能不正确)客户端的选择不会改变我所做的事情。关于Postgres方面的问题。如果可能的话,我想特别关注Postgres。
答案 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',您可以将此语句挂出数小时。如果其他人出现并尝试COPY
或INSERT
一行也有unique_column =' abc123',他将被阻止,直到您的COPY FROM
交易最终提交为止。这种行为可能会导致整个系统中阻塞事务的连锁效应,并在最坏的情况下使数据库停止运行,尤其是当您COPY
进入的表被其他编写者严重争议时。