show_chunks() 与 DELETE 抱怨的内容不符

show_chunks() does not correspond to what DELETE complains about

这真是百思不得其解。我需要从 timescaleDB 1.7 的超表中删除日期:

DELETE FROM raw WHERE tm::date = '2020-11-06' -- the local date style is YYYY-MM-DD

在此之前,我检查需要解压缩哪些块,给它一天余量,并接收两个块:

SELECT show_chunks('raw', newer_than => '2020-11-05 00:00'::timestamp)
---
Result:
"_timescaledb_internal._hyper_1_19_chunk"
"_timescaledb_internal._hyper_1_21_chunk"

所以我解压了这两个。但是,当我 运行 上面的 DELETE 命令时,我仍然收到关于完全不同的块的错误:

ERROR:  cannot update/delete rows from chunk "_hyper_1_1_chunk" as it
is compressed SQL state: XX000

顺便说一句,据我在 pgAdmin 中查看它所见,这个块是空的。知道发生了什么事吗?对我来说看起来像是一个错误,但也许我做错了什么?

谢谢!

编辑: 以下是 EXPLAIN DELETE 结果的摘录,应 @k_rus:

的要求
EXPLAIN DELETE FROM raw WHERE tm::date = '2020-11-06'
Result:

"Delete on raw  (cost=0.00..719.63 rows=147 width=6)"
"  Delete on raw"
"  Delete on _hyper_1_1_chunk"
"  Delete on _hyper_1_2_chunk"

...

"  Delete on _hyper_1_22_chunk"
"  ->  Seq Scan on raw  (cost=0.00..0.00 rows=1 width=6)"
"        Filter: ((tm)::date = '2020-11-06'::date)"
"  ->  Custom Scan (CompressChunkDml) on _hyper_1_1_chunk  (cost=0.00..27.40 rows=6 width=6)"
"        ->  Seq Scan on _hyper_1_1_chunk  (cost=0.00..27.40 rows=6 width=6)"
"              Filter: ((tm)::date = '2020-11-06'::date)"
"  ->  Custom Scan (CompressChunkDml) on _hyper_1_2_chunk  (cost=0.00..27.40 rows=6 width=6)"
"        ->  Seq Scan on _hyper_1_2_chunk  (cost=0.00..27.40 rows=6 width=6)"
"              Filter: ((tm)::date = '2020-11-06'::date)"

...

"  ->  Custom Scan (CompressChunkDml) on _hyper_1_22_chunk  (cost=0.00..27.40 rows=6 width=6)"
"        ->  Seq Scan on _hyper_1_22_chunk  (cost=0.00..27.40 rows=6 width=6)"
"              Filter: ((tm)::date = '2020-11-06'::date)"

1.7具体是什么版本?这有一个错误,但应该从 1.7.3 开始修复。 https://github.com/timescale/timescaledb/pull/2092

如果您使用的是 1.7.3 或更高版本并且仍然看到这个,最好在 timescaledb GitHub 存储库上打开一个问题。

您可以通过连接 psql 和 运行 \dx

来检查您的版本

感谢您提供说明。解释表明,DELETE 语句计划触及超表的所有块,只有在运行时执行 DELETE 语句才会意识到在许多块中没有什么可删除的:

EXPLAIN DELETE FROM raw WHERE tm::date = '2020-11-06'
Result:

"Delete on raw  (cost=0.00..719.63 rows=147 width=6)"
"  Delete on raw"
"  Delete on _hyper_1_1_chunk"
"  Delete on _hyper_1_2_chunk"

...

"  Delete on _hyper_1_22_chunk"
"  ->  Seq Scan on raw  (cost=0.00..0.00 rows=1 width=6)"
"        Filter: ((tm)::date = '2020-11-06'::date)"
"  ->  Custom Scan (CompressChunkDml) on _hyper_1_1_chunk  (cost=0.00..27.40 rows=6 width=6)"
"        ->  Seq Scan on _hyper_1_1_chunk  (cost=0.00..27.40 rows=6 width=6)"
"              Filter: ((tm)::date = '2020-11-06'::date)"
"  ->  Custom Scan (CompressChunkDml) on _hyper_1_2_chunk  (cost=0.00..27.40 rows=6 width=6)"
"        ->  Seq Scan on _hyper_1_2_chunk  (cost=0.00..27.40 rows=6 width=6)"
"              Filter: ((tm)::date = '2020-11-06'::date)"

...

"  ->  Custom Scan (CompressChunkDml) on _hyper_1_22_chunk  (cost=0.00..27.40 rows=6 width=6)"
"        ->  Seq Scan on _hyper_1_22_chunk  (cost=0.00..27.40 rows=6 width=6)"
"              Filter: ((tm)::date = '2020-11-06'::date)"

由于一些块被压缩,TimescaleDB returns 为压缩块计划的删除错误。

唯一不报错的方法就是在planning的时候有触发chunk排除的选择条件。题中选择条件为tm::date = '2020-11-06',先从tm列中提取日期,然后与常量进行比较。因此,规划器无法决定块是否被过滤,而是将过滤器下推以在每个块上运行时执行。

要解决这个问题最好有一个选择条件,它将时间维度列与常量或值进行比较,可以在计划时计算。假设tm是超表raw中的时间维度列,我建议将常量日期转换为时间戳,例如'2020-11-06'::timestamp并保留该列。您将需要指定时间戳范围以涵盖属于目标日期的所有行。

例如,DELETE 语句可以是:

DELETE FROM raw WHERE tm BETWEEN '2020-11-06 00:00' AND '2020-11-06 23:59'

问题的答案:

show_chunks() does not correspond to what DELETE complains about

show_chunk语句和DELETE语句条件不同,不能直接比较。 show_chunk 只显示块,它涵盖了比给定常量更新的时间。虽然 DELETE 计划检查每个块,因此它可以抱怨超表的任何块。

BTW this chunk is empty as far as I can see by looking at it in the pgAdmin. Any idea what's going on? Looks like a bug to me, but maybe I'm doing something wrong?

压缩块将数据存储在不同的内部块中,因此在_hyper_1_1_chunk中看不到数据。 TimescaleDB 假设数据是通过超表读取的,而不是直接从块中读取的。 Hypertable 是一种抽象,它隐藏了 TimescaleDB 的实现细节。