Postgres COPY FROM 永远

Postgres COPY FROM forever

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

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

我想知道,并且在环顾四周后找不到,是否只创建 COPY FROM 流并且在我的程序终止之前永远不关闭它对我来说是个坏主意。就像,当我的程序是 运行 并接受新数据时,我想打开一个 COPY FROM 并在其生命周期内不断流式传输该数据。

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

注意:我知道类似的考虑也适用于我正在使用的客户端驱动程序,但我假设(可能是错误的)客户端的选择不会改变我对Postgres 方面的事情。如果可能的话,我想把这个问题集中在 Postgres 上。

Does the COPY FROM operation create a transaction internally?

Postgres 中的每个 SQL 语句,包括 COPY FROM,要么是较大事务的一部分,要么本身包含在事务中。 ref:

PostgreSQL actually treats every SQL statement as being executed within a transaction. If you do not issue a BEGIN command, then each individual statement has an implicit BEGIN and (if successful) COMMIT wrapped around it. A group of statements surrounded by BEGIN and COMMIT is sometimes called a transaction block.

--

Related: Will the data I'm streaming be immediately accessible to other sessions?

不,未提交的数据永远不会对其他事务可见。在 SQL 术语中,这将被称为 "dirty read",而在 Postgres ref.

中是不可能的

Does Postgres have any internal mechanics that would cause this to not work (i.e. some internal state that would overflow without routine closing of the COPY FROM stream)?

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

要考虑的另一个方面是锁定影响。如果您在 table 上建立了主键、唯一索引或其他约束(您应该!),Postgres 将理解您 COPY 所在的行持有行级锁,直到它们承诺。假设您与 unique_column='abc123' 连续 COPYing,并且您让此语句闲置了几个小时。如果其他人出现并尝试 COPYINSERT 也有 unique_column='abc123' 的行,他将被阻止,直到您的 COPY FROM 事务最终提交.这种行为可能会在整个系统中导致事务阻塞的连锁反应,并在最坏的情况下使您的数据库停止运行,尤其是当您 COPY 进入的 table 被其他人激烈竞争时作家。