有没有办法在不读取数据的情况下创建约束(或附加分区)?

问题描述 投票:0回答:1

我们目前正在对数据库执行(早就该进行) 转换以使用分区。数据库保存了大量带时间戳的记录,其中时间戳有自己的索引。

对于此操作,我们将创建现有表的分区版本,然后将现有表附加为新表的分区。

为了防止在附加分区时锁定,我们将在数据上创建

NOT VALID
约束,然后验证它 - 正如文档中所建议的:

ALTER TABLE foo ADD CONSTRAINT partitioning_constraint 
CHECK (record_timestamp BETWEEN '2000-01-01' AND '2024-11-20') -- Last date is several in the future
NOT VALID;

COMMIT;

ALTER TABLE foo VALIDATE CONSTRAINT partitioning_constraint; -- This is taking a very long time reading the data.

奇怪的是,如果我只是简单地搜索与约束不匹配的行,结果几乎立即找不到行:

SELECT * from foo WHERE record_timestamp < '2000-01-01'; -- Instantly returns no rows
SELECT * from foo WHERE record_timestamp > '2000-11-20'; -- Instantly returns no rows
  • 我们知道检查约束是有效的,并且已经用简单的
    SELECT
    证明了它。
  • INVALID
    约束证明这不会改变。

但是我们需要找到一种方法来验证此约束(或附加为分区)而不读取几 TB 的数据。这是一个生产实例,猛击 IO 确实不是一个选择。

有什么方法可以绕过 postgres 像这样重新读取大量 TB 的数据吗?

postgresql postgresql-13
1个回答
0
投票

不,别无选择。 PostgreSQL 读取整个表并验证所有行。你可以通过操纵目录来作弊,但这既不值得赞扬也不支持。

如果您的系统无法处理大表的单次顺序扫描,那么一旦 autovacuum 开始处理它,您将做什么?

不过,这个约束看起来是错误的。 分区约束总是与下端的

>=
和上端的
<
进行比较,而对于
BETWEEN
,上端与
<=
进行比较。

© www.soinside.com 2019 - 2024. All rights reserved.