警告
这是一个历史文档,概述了 Timescale 之间的主要区别 1 和 Timescale 2.0。Timescale 2.0 于 2021 年 2 月发布。有关最新版本的 Timescale 的发行说明,有关最新版本的详细信息,请参阅 变更日志。
TimescaleDB 2.0 为其用于时序数据的高级关系数据库引入了新的特性和功能。受用户反馈的推动,2.0 是一个重要的里程碑,并引入了用于时序的第一个多节点 PB 级关系数据库。除了多节点功能外,此版本还包括新特性和现有特性的改进,重点在于为您提供更大的灵活性、对数据进行控制以及根据您的需求定制行为的能力。
为了促进 TimescaleDB 2.0 的许多改进,已经修改了几个现有的 API 和函数定义,这可能需要更新您的现有代码。
最值得注意的是,以下 API 和 PostgreSQL 兼容性更改可能会影响使用这些接口的现有代码。如果您的工作负载使用任何特性,本文件将详细介绍每个特性,以帮助您了解您需要采取的操作。
- 不再支持 PostgreSQL 版本 9.6 和 10: 如 我们的升级文档 中所述,TimescaleDB 2.0 不再支持较旧的 PostgreSQL 版本。您需要运行 PostgreSQL 版本 11 或 12 才能将您的 TimescaleDB 安装升级到 2.0。
- 连续聚合: 我们对连续聚合的创建和管理进行了重大更改,以解决用户的反馈。
- 数据保留和压缩策略: 现在通过统一的 API 和一组合并的视图来管理所有策略。
- 信息视图: 根据用户反馈和我们希望使 TimescaleDB 易于管理的愿望,已合并了多个信息视图以提高清晰度。
以下迁移文档提供了更多有关这些 API 更改的信息以及它们对 TimescaleDB 1.x 用户的影响。我们还包含了一些有关这些更改的动机以及我们的设计决策的信息。有关 API 的更深入介绍,以及对 2.0 中包含的新功能的详细说明(例如,分布式 hypertable 和运行用户定义操作(自定义后台作业)的能力),请查看我们更新的文档(导航到感兴趣的特定功能)。
阅读本指南了解升级到最新版本的影响,并评估对应用程序和基础架构的影响。然后,有关升级说明和建议,请参阅有关升级到 TimescaleDB 2.0 的说明。
自 2018 年 10 月发布 TimescaleDB 1.0 以便轻松扩展 PostgreSQL 以满足时间序列工作负载以来,已经过去两年。自首次发布以来,我们添加了许多新功能:对压缩、连续聚合、数据生命周期管理的支持以及许多优化,以及两个新的底层 PostgreSQL 版本(11 和 12)。与此同时,TimescaleDB 的核心并没有发生重大变化:我们仍然保留 hypertable、自动分区、查询优化以及许多人逐渐欣赏的基本用户体验,因为“一切正常”。
不过,与任何技术解决方案一样,我们第一次发布时有些事情并非百分之百正确。特别是,随着 TimescaleDB 使用量的激增,许多用户告诉我们,我们的信息视图并不总是清晰一致,也没有提供有关后台发生的事情的足够详细信息。同样地,虽然创建连续聚合“容易”,但有时很难明确聚合为什么不返回数据,或者为什么新原始数据物化速度很慢。作为创建连续聚合的副作用,hypertable 上的数据保留可能会被阻止,并且了解如何重新启用它是一个常见支持问题。
虽然我们提供“一切正常”解决方案的雄心依然不变,但 hypertable、压缩和连续聚合等功能背后太多“魔术”和自动化可能会导致与用户期望或意图不一致的结果。此外,对于像 PostgreSQL 这样的通用数据库,预期行为因用例(和用户的专业知识)而异。这促使我们重新致力于用户体验:简化 API 并使其更一致,同时赋予用户更多控制权,以便在需要时自定义行为。
例如,在 TimescaleDB 2.0 中,我们已将刷新连续汇总数据的自动化功能从核心功能中分离开,让用户可以选择手动刷新数据,并且可以在需要时通过策略来添加自动化功能。这也使得该功能与 TimescaleDB 的其他策略驱动型功能(例如保留、重新排序和压缩)保持一致性,后者可提供手动控制和使用策略进行的自动化操作。我们还开放了作业调度框架,以便能够执行用户自定义操作。用户自定义操作是您可自行定义的自定义后台作业。
在本文件的其余部分,我们将详细了解各项功能和 API 的变更,以及从早期版本的 TimescaleDB 迁移的用户在更新至 TimescaleDB 2.0 之前应该考虑的内容。
在 TimescaleDB 2.0 中,我们对用于使用超表的现有 API 进行了变更,并改进了相关的信息视图和大小函数。这些视图和函数提供有关基本配置、分区、数据块和磁盘大小的信息,并且它们也已更新为可用于分布式超表中。
用于创建和配置超表的以下 API 已发生更改
create_hypertable
:main_table
参数已重命名为relation
,并且已添加针对分布式超表的其他参数。set_chunk_time_interval
、set_number_of_partitions
、add_dimension
:main_table
参数已重命名为hypertable
。
为了改善对 TimescaleDB 的各个配置方面的可见性,以下有关超表信息的视图和函数已得到更新或添加
timescaledb_information.hypertables
- 有关超表的详细信息视图已从单数形式的“超表”更名。
- 为了与其他视图保持一致性,某些列已采用新的名称。
- 表大小信息已被移除并可通过稍后讨论的新尺寸函数获得。
- 已添加与分布式 Hypertable 相关的其他列。
- 该视图不再显示连续聚合和压缩的内部 Hypertable。
- 对于连续聚合,内部已实现的 Hypertable 名称可从
timescaledb_information.continuous_aggregates
视图中获得。
timescaledb_information.dimensions
:此新视图允许用户查看不同维度的分区信息和设置,例如块时间间隔或 Hypertable 中使用的空间分区数量。timescaledb_information.chunks
:此新视图允许用户查看所有 Hypertable 的各个数据块的信息,包括存储每个块的表空间或数据节点。show_chunks(relation)
:此函数现在要求将 Hypertable 或连续聚合标识符作为第一个参数提供,这与drop_chunks(relation)
一致。以前,可以通过忽略 Hypertable 参数来查看所有 Hypertable 的块。相反,为了查看数据库中的所有块,我们建议使用上面描述的新块视图。
这些视图可以结合使用来回答特定问题。例如
问:获取在过去的一个月内写入到表空间“ts1”的所有块
SELECT * FROM timescaledb_information.chunksWHERE hypertable_name = 'conditions'AND chunk_tablespace = 'ts1'AND range_start > now() - INTERVAL '1 month';
问:获取已启用压缩的超表的全部块的压缩状态
SELECT h.hypertable_schema, h.hypertable_name,chunk_schema, chunk_name,range_start, range_end, is_compressedFROM timescaledb_information.chunks cINNER JOIN timescaledb_information.hypertables hON (c.hypertable_schema = h.hypertable_schemaAND c.hypertable_name = h.hypertable_name)WHERE h.compression_enabled = true;
信息视图不再显示有关超表及其他对象的尺寸信息。相反,尺寸信息通过一系列函数获取,这些函数均以字节数的形式返回尺寸。移除尺寸信息使视图更快,因为这些信息通常是从磁盘动态读取的,或者,在分布式超表的情况下,从网络中读取。
尺寸函数还被分为基本函数和详细函数。基本函数仅返回一个聚合值,可在查询中轻松应用,而详细函数则返回多列,甚至多行信息。
hypertable_detailed_size(hypertable)
:此函数已从hypertable_relation_size(hypertable)
重命名。此外,如果分布式超表,则返回多行,每行对应超表的一个数据节点。hypertable_size(hypertable)
:返回一个单一值,提供聚合的超表尺寸,包括表(块)和索引。chunks_detailed_size(hypertable)
:返回超表中每个块的尺寸信息。在分布式超表上,此函数为保存块副本的每个数据节点返回一行。hypertable_index_size(index)
:返回所有块中与超表索引对应的聚合字节数。approximate_row_count(relation)
:此函数已从hypertable_approximate_row_count
重命名。现在它还可在常规 SQL 表上调用。
在 TimescaleDB 的先前版本中,你可以在 hypertable
视图中获取所有超表的尺寸信息。在 TimescaleDB 2.0 中,你现在可以将新的 hypertables
视图与尺寸函数结合使用以实现类似的结果
SELECT hypertable_name, hypertable_size(hypertable_name::regclass) FROM timescaledb_information.hypertables;hypertable_name | hypertable_size-----------------+-----------------devices | 360448conditions | 253952
为了更好地阐明此功能,已对 TimescaleDB 2.0 中的连续聚合进行了重大更改。
首先,连续聚合始终与 PostgreSQL 中的物化视图更紧密地关联。因此,创建连续聚合现在使用 CREATE MATERIALIZED VIEW
,而不是 CREATE VIEW
。
其次,连续聚合 API 现在将更新连续聚合的显式机制与用于自动执行保持连续聚合最新的流程的策略分离开来。这一变更既简化了 TimescaleDB 2.0 中的连续聚合 API,也为用户提供了更大的灵活性(尤其是在与用户定义的动作及用于直接计划作业的新公开 API 结合使用时),并且与 TimescaleDB 2.0 中的其他策略自动化保持一致
动作 API | 自动化策略 API |
---|---|
drop_chunks | add_retention_policy |
reorder_chunk | add_reorder_policy |
compress_chunk | add_compression_policy |
refresh_continuous_aggregate | add_continuous_aggregate_policy |
在实践中,这意味着在 TimescaleDB 2.0 中创建连续聚合现在是一个两步流程
- 通过
CREATE MATERIALIZED VIEW
语句创建 - 通过单独的 API 函数调用为连续聚合添加(自动化)策略
CREATE MATERIALIZED VIEW conditions_by_2hWITH (timescaledb.continuous,timescaledb.materialized_only=false)ASSELECT time_bucket('2 hours', time) as bin,COUNT(device) as valueFROM conditionsGROUP BY binWITH NO DATA;SELECT add_continuous_aggregate_policy(continuous_aggregate => 'conditions_by_2h',start_offset => '4 weeks',end_offset => '2 hours',schedule_interval => '1 hour');
在上面的示例中,CREATE MATERIALIZED VIEW
创建了连续聚合,但尚未与其相关联任何自动化。还要注意,最终指定了 WITH NO DATA
。这将防止视图在创建时物化数据,而是推迟填充聚合数据,直到策略作为后台作业或手动刷新的组成部分运行为止。因此,我们建议用户使用 WITH NO DATA
选项创建连续聚合,尤其是当可以物化大量历史数据时。
创建连续聚合后,调用 add_continuous_aggregate_policy
将创建连续聚合策略,该策略将根据提供的计划和规则自动物化或刷新数据。策略函数的输入包括连续聚合名称、刷新窗口和计划间隔。刷新窗口由起始偏移和结束偏移指定,这些偏移用于通过从当前时间(通常由函数 now()
返回)中减去偏移来计算每次运行策略时的新刷新窗口。
值得注意的是 start_offset
和 end_offset
在新数据到达并添加到源超表时起作用的方式。
此示例将刷新间隔设置为四星期至两小时前(使用 start_offset
和 end_offset
)。因此,如果任何延迟数据在过去四星期内的时间戳范围内到达并回填到源超表中,则连续聚合视图将在策略下次执行时使用旧数据进行更新。
在最坏的情况下,此策略可能会在每次运行时物化整个窗口,条件是至少四星期前的数据继续到达并插入到源超表中。然而,由于连续聚合会跟踪自上次刷新以来的更改,因此它在大多数情况下可以物化与实际更改的数据相对应的窗口子集。
在此示例中,超过 4 周前填补的数据不予重新生成,连续聚合也不包含不足 2 小时的新数据。但是,查询连续聚合视图仍然可以不基于对 实时聚合 的支持,返回有关最新数据的聚合(而不仅仅是超过 2 小时前聚合的数据),此前如使用 timescaledb.materialized_only=false 参数指定。实时聚合仍然是默认设置,除非另行指定。
最后,建议 end_offset 落后于当前时间至少一个 time_bucket(在聚合 SQL 中定义),否则插入新数据(通常写入最新存储段)可能会影响性能。在 TimescaleDB 1.x 中,refresh_lag 参数用于类似目的,但我们发现正确理解它的用法会更困难。
为了延续新而更灵活的函数,TimescaleDB 2.0 移除对 REFRESH MATERIALIZED VIEW 的支持,refresh_continuous_aggregate 使用户能够刷新连续聚合中的特定窗口
CALL refresh_continuous_aggregate(continuous_aggregate => 'conditions_by_2h',window_start => '2020-05-01',window_end => '2020-05-03');
用户可以使用此命令明确地;通常此命令用来在创建连续聚合策略以聚合新数据时手动刷新历史数据。甚至可以在新的用户自定义操作框架中使用此函数构建自定义连续聚合策略,然后再通过 add_job 计划这些策略。
请注意,refresh_continuous_aggregate 仅重新计算完全落在给定刷新窗口内并且位于原始超表发生过更改的区域中的聚合时间存储段。因此,如果原始源数据没有发生更改(即没有数据填补到此区域,或者没有对现有数据进行更新),则不会对此区域执行生成操作。此行为与连续聚合策略类似,并确保更有效率的操作。
权力和灵活性越大,理解特性之间如何交互的责任也就越大。具体来说,用户应该理解数据保留策略设置和连续聚合设置之间的交互。
在开始升级到 TimescaleDB 2.0 之前,我们强烈建议检查数据库日志,了解 TimescaleDB 1.x 中发生过的与失败的保留策略相关联的错误,然后将其删除或更新为与现有的连续聚合兼容。任何与 ignore_invalidation_older_than 设置仍然不兼容的剩余的保留策略都会在升级期间禁用,并会显示通知。
例如,如果在数据表上设置了数据保留策略,以进行 drop_after => '4 weeks'
,则与该相同数据表上的连续聚合关联的策略的 start_offset
应该小于或等于 4 周。类似地,对 refresh_continuous_aggregate
的任何手动调用都应该指定一个 window_start
,该 window_start
也小于 4 周前的日期。
如果未理解正确,用户可能会通过重新计算数据(该数据现已从时间窗口中删除)来用空数据覆盖连续聚合中的现有聚合数据,这可能不是用户期望的结果。相反,希望仅保留一段特定时间窗口的数据在其连续聚合视图中的用户应该对连续聚合本身创建数据保留策略。
这与 TimescaleDB 1.x 处理保留策略和连续聚合之间的冲突的方式有很大不同。
以前,如果连续聚合设置 ignore_invalidation_older_than
与将由保留策略删除的数据重叠,则保留策略将静默失败。让保留策略再次生效需要用户修改保留策略或连续聚合中的设置,即便如此,某些数据也不总是按预期实现的。
升级到 TimescaleDB 2.0 后,保留策略不再因与连续聚合不兼容而失败,用户必须确保保留和连续聚合策略具有所需交互。
2.0 中的另一个更改是,drop_chunks
和保留策略不再自动刷新连续聚合以解决最后一次刷新后原始数据表中的更改。以前,目标是确保在原始数据表中删除块之前处理所有更新。实际上,它通常并不能按预期工作。
在 TimescaleDB 2.0 中,用户可以通过将以下实验函数(它刷新给定块中的更新)与 drop_chunks
相结合,以确保在删除数据之前处理所有更新。
_timescaledb_internal.refresh_continuous_aggregate(continuous_aggregate REGCLASS, chunk REGCLASS)
以下示例演示了如何使用基于块的刷新函数定义保留策略,该策略可确保在删除超过 2 周的块之前,将对原始数据表中的所有数据更新刷新到所有连续聚合中
CREATE OR REPLACE PROCEDURE refresh_and_drop_policy(job_id int, config jsonb) LANGUAGE PLPGSQL AS$$DECLAREdrop_after interval;hypertable text;BEGINSELECT jsonb_object_field_text(config, 'drop_after')::intervalINTO STRICT drop_after;SELECT jsonb_object_field_text(config, 'hypertable')::regclassINTO STRICT hypertable;BEGIN;SELECT _timescaledb_internal.refresh_continuous_aggregate(cagg,show_chunks(older_than => drop_after))FROM timescaledb_information.continuous_aggregatesWHERE format('%I.%I', hypertable_schema, hypertable_name)::regclass = hypertable;SELECT drop_chunks(hypertable, older_than => drop_after);COMMIT;END$$;SELECT add_job('refresh_and_drop_policy', '2 weeks',config => '{"hypertable":"public.conditions", "drop_after":"2 weeks"}');
在 TimescaleDB 1.x 中,回填到超表中的数据没有得到最佳处理。无论多老,任何超表数据的修改都会导致连续聚合数据处理程序作业从最早回填的点重新启动,然后从该点开始处理数据。不幸的是,这也可能会导致数据处理程序“卡住”,因为后台作业每次运行只处理有限数量的数据,而这由 max_interval_per_job
设置控制。当这种情况发生时,一次作业运行可能会迫使下一份作业重新启动。
为防止这种情况,ignore_invalidation_older_than
设置可用于忽略早于指定时间间隔的回填数据(例如,忽略早于 1 周的回填),从而防止在超表数据在此时间间隔边界之外被修改时数据处理程序重新启动。但是,这也将阻止 TimescaleDB 1.x 跟踪 ignore_invalidation_older_than
阈值之外基础数据中的更改。这意味着稍后无法将此设置还原为较大的时间间隔(例如 1 个月),而不会使得连续聚合中的原始数据和聚合数据之间存在不匹配。
相比之下,TimescaleDB 2.0 永远不会停止跟踪回填,为避免处理过多历史数据,只需使用不包含该数据区域的刷新窗口即可。回填区域始终可以在以后的时间手动刷新或通过策略刷新。
为确保先前忽略的回填可以在升级到 TimescaleDB 2.0 之后刷新,升级过程将早于 ignore_invalidation_older_than
阈值的区域标记为“需要刷新”。这允许进行手动刷新,使连续聚合与基础源数据保持最新状态。如果 ignore_invalidation_older_than
阈值在某个时间点被修改为较长时间间隔,我们建议在升级之前将其设置回较小的时间间隔,以确保可以刷新所有回填(如果需要)。
但是,请再次注意,如果由于基础超表的数据保留策略而先前忽略了回填,则当超表块由于数据保留策略而被删除(如前一节所述)时,对较旧数据的手动刷新可能会删除数据。
在 TimescaleDB 2.0 中,围绕连续聚合(和其他策略)的视图已经得到简化和概括。
timescaledb_information.continuous_aggregates
:现在提供与物化视图相关的信息,包括视图名称和所有者、实时聚合标志、数据处理和视图定义(定义该视图的选择语句)。timescaledb_information.jobs
:显示包括连续聚合在内的所有策略的信息。timescaledb_information.job_stats
:显示与所有作业相关的作业统计信息。
timescaledb_information.continuous_aggregate_stats
:已移出,有利于上述job_stats
视图。
如果你有现有的持续聚合并且你将数据库更新为 TimescaleDB 2.0,更新脚本会自动重新配置你的持续聚合以使用新框架。
尤其,更新流程应该
- 保留与之前相同的视图架构、名称、所有者和视图定义,以及
materialized_only
的设置。 - 安排刷新在相同间隔运行,如前所述(尽管该参数现在名为
schedule_interval
,而不是refresh_interval
)。 - 自动配置
start_offset
到与旧设置ignore_invalidation_older_than
指定的相同偏移量。 - 自动配置
end_offset
以从now()
偏移,相当于旧refresh_lag
设置。 - 将早于
ignore_invalidation_older_than
间隔的所有数据标记为已过时,以便可以刷新。 - 禁用任何保留策略,原因是它们与持续聚合中
ignore_invalidation_older_than
的当前设置不兼容(如上所述)。禁用策略在升级后仍然存在,但未安排运行(timescaledb_information.jobs
中的scheduled=false
)。如果要将失败的策略迁移到 2.0,它们将重新开始工作,但可能会产生意外后果。因此,任何在更新后被禁用的保留策略都应该在重新启用之前仔细审查它们的设置。
你可以在上面给出的正确信息视图中验证这些信息。
对各种 API 进行了其他小更改,以提高可理解性和一致性,包括在以下领域。
drop_chunks
:此功能现在需要将超表或连续聚合指定为第一个参数,并且不允许在数据库中的所有超表中删除块。此外,已删除参数cascade
和cascade_to_materializations
(在旧版本中,其行为就如同将参数设置为false
)。在 TimescaleDB 2.0 中,我们建议对每个连续聚合创建一个单独的保留策略。add_retention_policy
,remove_retention_policy
:现在,创建(或移除)数据保留策略具有明确的功能。此外,已删除参数cascade
和cascade_to_materializations
(在旧版本中,其行为就如同将参数设置为false
)。timescaledb_information.jobs
:有关数据保留策略的常规信息现在可在主作业视图中查看。
add_drop_chunks_policy
:已移除,而采用上面明确的功能。timescaledb_information.drop_chunks_policies
:已移除视图,而采用更通用的作业视图。
add_compression_policy
,remove_compression_policy
:现在,创建(或移除)压缩策略具有明确的功能。hypertable_compression_stats(hypertable)
:该函数仅返回已启用压缩的超表的统计信息。chunk_compression_stats(hypertable)
:该函数返回有关当前已压缩块的信息。timescaledb_information.compression_settings
:此新视图提供有关超表压缩设置的信息。timescaledb_information.jobs
:有关压缩策略的常规信息现在可在主作业视图中查看。
add_compress_chunk_policy
:已移除,而采用上面明确的功能。timescaledb_information.compressed_hypertable_stats
:已移除,而采用上面链接的hypertable_compression_stats(hypertable)
函数。timescaledb_information.compressed_chunk_stats
:已移除,而采用上面链接的chunk_compression_stats(hypertable)
函数。
TimescaleDB 2.0 引入了用户定义的操作,并创建了更统一的作业 API。现在,可通过单一 API 管理和查看 TimescaleDB 策略创建的作业以及用户定义操作。
add_job
:将新的用户定义操作添加到作业调度框架。alter_job
:更改现有作业的设置。与旧版本中重命名的alter_job_schedule
相比,它引入了更多设置,包括用于暂停和恢复作业的scheduled
以及用于更改策略或特定于操作的设置的config
run_job
:立即在后台手动执行作业。delete_job
:从调度程序中删除作业。这等同于删除内置操作策略的函数(例如,remove_retention_policy
)。timescaledb_information.jobs
:新视图提供所有可用的作业设置,它会替换所有特定于策略的视图。timescaledb_information.jobs_stats
:此视图显示策略和操作执行作业的统计信息。
在 TimescaleDB 2.0 中,所有以前归类为“企业版”的功能都已成为“社区版”功能,并可在 Timescale 许可下免费使用。因此,已不再需要“企业版许可”即可解锁任何功能。所有功能均可在社区版 Timescale 许可或开源 Apache-2 许可下使用。 这篇博文 解释了这些更改。已对许可 API 进行如下更改
timescaledb_information.license
:此视图已被删除,因为它主要提供企业版许可密钥的到期日期信息,而此信息不再适用。相反,扩展程序使用的当前许可证可以在以下 GUC 中查看。timescaledb.license
:此 GUC 值(替换之前的timescaledb.license_key
GUC)可以取值timescale
或apache
。它只能在启动时设置(在 postgresql.conf 配置文件中或在服务器命令行中),并允许根据许可证限制对某些功能的访问。例如,将许可证设置为apache
允许仅访问具有 Apache-2 许可证的功能。
关键词