我想替换表的全部内容,而不会影响SELECT
过程中的任何传入语句。
用例是拥有一个表,该表存储定期提取的邮箱信息,并且需要将其存储在PostgreSQL表中。有许多客户端正在使用不断查询同一张表的应用程序。
通常,我会做类似(伪代码传入)的操作...
BEGIN TRANSACTION
TRUNCATE TABLE
INSERT INTO
COMMIT
但不幸的是,在此过程中无法读取该表。由于需要花费时间INSERT INTO
。该表已锁定。
在MySQL中,我本可以使用其原子RENAME TABLE
命令来避免这些问题...
CREATE TABLE table_new LIKE table;
INSERT INTO table_new;
RENAME TABLE table TO table_old, table_new TO table; *atomic operation*
DROP TABLE table_old;
如何在PostgreSQL中实现呢?
出于这个问题的目的,您可以假设我没有使用外键。
您为什么认为在表中插入行时无法读取表?截断表将在所有会话中立即生效;但是,插入(如果在将它们全部包裹的事务中完成,如您的伪代码所建议的那样)在您提交之前对其他会话不可见。其他会话将能够从表中选择,并且将看到一个空表,直到您提交为止。
—
zgguy 2015年
@zgguy该
—
Josh Kupershmidt,2015年
TRUNCATE
命令将在表上获取一个AccessExclusive锁,因此在提交该事务或将其回滚之前,其他任何人都无法从该表读取。
如果使用
—
a_horse_with_no_name 2015年
delete
代替truncate
它会比较慢,但是不会阻塞读者。您需要删除多少行?
@a_horse_with_no_name通常在200-300k行之间,具有许多varchar列。的等待时间
—
克拉基2015年
DELETE
,并INSERT
会太长。