Compression show_chunks()与DELETE抱怨的内容不一致
这实在令人费解。我需要从timescaleDB 1.7的超表格中删除日期:Compression show_chunks()与DELETE抱怨的内容不一致,compression,timescaledb,Compression,Timescaledb,这实在令人费解。我需要从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: "
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中看到的情况来看,这个区块是空的。知道发生了什么吗?看起来像个虫子,但也许我做错了什么
谢谢
编辑:
以下是@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的具体版本是什么?这上面有一个bug,但是应该从1.7.3开始修复 如果您使用的是1.7.3或更高版本,并且仍然看到这一点,那么最好在timescaledb GitHub repo上打开一个问题
您可以通过连接psql并运行\dx来检查您的版本谢谢您提供的解释。解释表明,DELETE语句计划触及hypertable的所有区块,只有在运行时,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在计划删除压缩数据块时返回错误
不获取错误的唯一方法是使用选择条件在计划时触发区块排除。在问题中,选择条件是tm::date='2020-11-06'
,它首先从列tm
中提取日期,然后与常量进行比较。因此,计划者无法决定是否对块进行过滤,而是在每个块上按下过滤器以在运行时执行
要解决这个问题,最好有一个选择条件,将时间维度列与常量或值进行比较,后者可以在计划时计算。假设tm
是超表格raw
中的时间维度列,我建议将固定日期转换为时间戳,例如,'2020-11-06'::timestamp
,并保留该列。您需要指定时间戳的范围,以覆盖属于目标日期的所有行
例如,DELETE语句可以是:
从原始数据中删除'2020-11-06 00:00'和'2020-11-06 23:59'之间的tm
对问题的答复:
show_chunks()与DELETE抱怨的内容不一致
show\u chunk
语句和DELETE
语句具有不同的条件,因此无法直接进行比较show_chunk
仅显示块,其覆盖的时间比给定常量新。而DELETE
计划检查每个块,因此它可以对hypertable的任何块进行投诉
顺便说一句,就我在pgAdmin中看到的情况来看,这个区块是空的。知道发生了什么吗?看起来像个虫子,但也许我做错了什么
压缩块将数据存储在不同的内部块中,因此在
\u hyper\u 1\u 1\u块中看不到数据。TimescaleDB假定数据是通过超表读取的,而不是直接从数据块读取的。Hypertable是一种抽象,它隐藏了TimescaleDB的实现细节。Hi@TDF,它显示了1.7.4在运行\dx顺便说一句,整个实例都是从docker运行的:docker run-d--name TimescaleDB-p 5432:5432-e LANG=C timescale/TimescaleDB:1.7.4-pg12您能在DELETE语句上运行EXPLAIN并显示结果吗?Hi@k\rus,问题是这样的:既然回答问题很关键,你能把解释贴到你的问题里吗?你可以省略重复的部分,只显示计划中的几个部分。太棒了,非常感谢!这确实有道理。因此,我理解计划者不能通过::date(并且可能不会在timestamp字段上使用任何修饰符或函数),因此它决定使用核心选项来通过所有块,这是可以理解的。最重要的是,建议与作品之间,所以这绝对是答案!谢谢你!