Redshift 系统表是不可变且有序的吗?

Posted

技术标签:

【中文标题】Redshift 系统表是不可变且有序的吗?【英文标题】:Are Redshift system tables immutable and well ordered? 【发布时间】:2018-01-17 16:56:14 【问题描述】:

Redshift 系统表只记录了几天的记录数据 - 定期备份这些表中的行是收集和维护适当历史记录的常见做法。要查找添加到系统日志中的新行,我需要在查询(编号)或执行时间上检查我的备份表。

根据How do I keep more than 5 day's worth of query logs? 上的答案,我们可以简单地选择带有query > (select max(query) from log) 的所有行。答案是未引用的,并假设query 是按顺序插入的。

我的问题分为两部分 - 希望参考或代码作为证明 - 是

    query(标识符)预计将按顺序插入,并且 是系统表,例如stl_query,是不变的还是不变的?

假设我们无法验证或证明以上两者,那么备份系统表的正确策略是什么?


我对此持谨慎态度,因为我完全希望在许多其他查询开始并完成之后才能完成长时间运行的查询。

我知道query(标识符)是在查询提交时生成的,因为我可以监控正在进行的查询。因此,预计长时间运行的query=1 可能在query=2 之后完成。如果stl_query 表是不可变的,那么query=1 将被插入到query=2 之后,而max(query) 逻辑是有缺陷的。

或者,如果在运行时将query=1 插入stl_query,则必须在完成时更新行(包括结束时间、持续时间等)。这需要我对备份表进行更新插入。

【问题讨论】:

【参考方案1】:

我认为stl_query 表确实是不可变的,它似乎只是在查询完成后才写入。

这就是我这么认为的原因。首先,我在运行查询的集群上运行此查询

select count(*) from stl_query where endtime is null

这返回 0。我的预感是你可能会在你身边看到同样的东西。

为了确定,我也运行了这个查询:

select count(*) from stv_inflight i
inner join stl_query q on q.query = i.query

这也返回零(虽然我确实有正在进行的查询),这似乎证实了查询仅在完成执行且未更新时才记录在 stl_query 中。

也就是说,我会重写查询以插入到您的历史记录表中:

insert into admin.query_history (
    select * from stl_query
    where query not in (select query from admin.query_history)
)

这样,您将始终插入历史表中没有的任何记录。

【讨论】:

谢谢迈克尔。我对not in 持谨慎态度,因为这些表最终会变大,但我想这是过度优化。但现在我对那些有endtime 列的表使用where endtime > max(endtime) 如果您担心性能,我建议您在查询时创建一个 distkey 并在 endtime 上创建一个 sortkey。这样我怀疑如果你过滤 endtime > max(endtime) 并且查询 not in(...),查询仍然会非常高效。

以上是关于Redshift 系统表是不可变且有序的吗?的主要内容,如果未能解决你的问题,请参考以下文章

ReadonlyCollection,对象是不可变的吗?

临时表是线程安全的吗?

AWS Redshift:清除 STL 表的频率

根据定义,值类型是不可变的吗?

集合-跳表SkipList

集合-跳表SkipList