DROP TABLE Postgres 事务中的行为
DROP TABLE behaviour in Postgres transactions
假设我正在开发一个 ETL,它定期从 CSV 中读取源数据并替换 Postgres (9.6) 中的 table。
这是一种方法:
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
命令处锁定 table,因此并发 SELECT
查询将阻塞,直到事务完成。
- 在
COPY
和 CREATE INDEX
完成之前,第二个事务不会阻止 SELECT
查询。
- 两个事务都是原子的:在任何一种情况下,如果我发出
ROLLBACK
而不是 COMMIT
,table 将与所有原始数据和索引一起恢复。
此外,除了索引名称之外,还有其他功能上的差异吗?
是的,您的所有 3 个假设都是正确的。
两个事务的最终结果是相同的,但是第一个事务导致的阻塞时间会更长,并且取决于数据量和创建索引所需的时间。第二个事务需要一个非常简短的锁来重命名对象。
一些信息适用于那些认为重命名 table 就足以满足他们的用例的人。谨防!在 PostgreSQL 中重命名有时可能无法像您预期的那样工作。
这里有更多信息
假设我正在开发一个 ETL,它定期从 CSV 中读取源数据并替换 Postgres (9.6) 中的 table。
这是一种方法:
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
命令处锁定 table,因此并发SELECT
查询将阻塞,直到事务完成。 - 在
COPY
和CREATE INDEX
完成之前,第二个事务不会阻止SELECT
查询。 - 两个事务都是原子的:在任何一种情况下,如果我发出
ROLLBACK
而不是COMMIT
,table 将与所有原始数据和索引一起恢复。
此外,除了索引名称之外,还有其他功能上的差异吗?
是的,您的所有 3 个假设都是正确的。
两个事务的最终结果是相同的,但是第一个事务导致的阻塞时间会更长,并且取决于数据量和创建索引所需的时间。第二个事务需要一个非常简短的锁来重命名对象。
一些信息适用于那些认为重命名 table 就足以满足他们的用例的人。谨防!在 PostgreSQL 中重命名有时可能无法像您预期的那样工作。
这里有更多信息