Postgres 事务中的 DROP TABLE 行为

Posted

技术标签:

【中文标题】Postgres 事务中的 DROP TABLE 行为【英文标题】:DROP TABLE behaviour in Postgres transactions 【发布时间】:2017-11-07 19:09:29 【问题描述】:

假设我正在开发一个 ETL,它会定期从 CSV 读取源数据并替换 Postgres (9.6) 中的表。

这是一种方法:

BEGIN
DROP TABLE IF EXISTS table
CREATE TABLE table (...)
COPY table FROM STDIN (FORMAT csv, HEADER true)
CREATE INDEX ON table (...)
COMMIT

这是另一个:

BEGIN
CREATE TABLE table_temp (...)
COPY table_temp FROM STDIN (FORMAT csv, HEADER true)
CREATE INDEX ON table_temp (...)
DROP TABLE IF EXISTS table
ALTER TABLE table_temp RENAME TO table
COMMIT

我对以下内容是否正确?

第一个事务将在DROP 命令处锁定表,因此并发的SELECT 查询将阻塞,直到事务完成。 在COPYCREATE INDEX 完成之前,第二个事务不会阻塞SELECT 查询。 两个事务都是原子的:在任何一种情况下,如果我发出 ROLLBACK 而不是 COMMIT,表将恢复所有原始数据和索引。

另外,除了索引的名称,还有其他功能上的区别吗?

【问题讨论】:

【参考方案1】:

为那些认为重命名表足以满足他们的用例的人们提供一些信息。谨防!有时,在 PostgreSQL 中重命名可能无法按预期工作。

更多信息在这里What could go wrong, when swapping table contents using table rename in Postgresql?

【讨论】:

【参考方案2】:

是的,你的三个假设都是正确的。

两个事务的最终结果是相同的,但第一个事务引起的阻塞会更长,并且取决于数据量和创建索引所需的时间。第二个事务需要一个非常简短的锁来重命名对象。

【讨论】:

以上是关于Postgres 事务中的 DROP TABLE 行为的主要内容,如果未能解决你的问题,请参考以下文章

Spring 事务和 postgres(VACUUM,在事务外部运行)

事务中的 Postgres 锁

deletetruncate和drop的区别

Hive Managed Table(内部表) 和 External Table(外部表)的区别

Postgres中的Schema.Table [重复]

循环中的PostgreSQL DROP TABLE失败,出现ERROR:共享内存