Spring 如何在PostgreSQL中安全地截断和重新填充表?

Spring 如何在PostgreSQL中安全地截断和重新填充表?,spring,postgresql,Spring,Postgresql,必须每天更新数据库中的一个表。web服务器每5秒主动查询一次此表。由于一些限制,现在我不能简单地更新表行,因此我需要清除所有行并重新填充表。如何在不影响web服务器功能的情况下安全地执行此操作? 重新填充由与web服务器隔离的其他web服务完成。我使用的是Spring框架 该表约有170k行和5列 在单个事务中截断并重新填充表。对于继续查看旧数据的并发读者来说,截断不可见。根据@AlexanderEmelianov和: TRUNCATE不是MVCC安全的。截断后,如果并发事务使用在截断发生之前拍

必须每天更新数据库中的一个表。web服务器每5秒主动查询一次此表。由于一些限制,现在我不能简单地
更新
表行,因此我需要清除所有行并重新填充表。如何在不影响web服务器功能的情况下安全地执行此操作?
重新填充由与web服务器隔离的其他web服务完成。我使用的是Spring框架


该表约有170k行和5列

在单个事务中截断并重新填充表。对于继续查看旧数据的并发读者来说,截断不可见。根据@AlexanderEmelianov和:


TRUNCATE不是MVCC安全的。截断后,如果并发事务使用在截断发生之前拍摄的快照,则该表对于并发事务而言将显示为空。有关更多详细信息,请参阅

因此,在
TRUNCATE
ing txn提交之后,在
TRUNCATE
之前启动的并发txn将看到该表为空


任何试图在截断后写入表的事务都将等待执行截断的事务提交或回滚

BEGIN;

TRUNCATE TABLE my_table;

INSERT INTO my_table (blah) VALUES (blah), (blah), (blah);

COMMIT;
您可以
复制
而不是
插入
。正常交易中的任何东西


更好的是,PostgreSQL中有一个优化功能,可以使截断后填充表的速度比不截断时更快。

只是想知道,为什么要清除所有行并重新填充表??,需要如何重新填充数据??假设真的必须重新填充表(只是要求确认,因为这是一个非常奇怪的要求),
drop table;create table;
delete from table;
-快得多,所以在Web服务器的两个请求之间计划该操作可能是个好主意。为什么您不能更新行?有哪些约束阻止了这一点?为什么他们不阻止删除所有内容?该表具有IP范围的映射(从起始ip到结束ip)到国家/地区。我从多个源下载并解析此映射,解析它们并将其保存到数据库。没有可以更新行的主键。这是约束条件。我不明白…您需要截断表然后填充它。所以您可以只
截断表my_table;
然后填充它。或者我遗漏了什么?啊..完全忘记了交易。谢谢。这很好用。:)TRUNCATE不是MVCC安全的。在截断之后,如果并发事务使用在截断发生之前拍摄的快照,则该表对于并发事务将显示为空。您可以在此处看到:您可以在事务中执行删除操作。这是MVCC安全的方式。@AlexanderEmelianov您确定/测试了吗?我以为TRUNCATE很久以前就被设置为MVCC安全的…@CraigRi我肯定,当然。我发现了一些与截断行为相关的bug。此外,这一特性已在官方文档中记录。