双写和回填是一种同时从您的应用程序写入两个数据库的方法,并提供工具和指导,以将您的现有数据从一个数据库移动到另一个数据库。 它专门为主要为仅附加时间序列数据的数据而定制和依赖。 因此,它带有一些在线迁移不具备的注意事项和先决条件(双写和回填不支持对您的数据执行 UPDATEDELETE 语句)。 此外,它要求您更改应用程序的摄取管道。

timescaledb-backfill 工具是一个命令行实用程序,旨在通过将历史数据从一个数据库复制到另一个数据库(“回填”),来支持从 Timescale 实例的迁移。 timescaledb-backfill 直接有效地复制超表和连续聚合块,而无需中间存储或解压缩压缩块。 它以事务方式运行,确保整个迁移过程中的数据完整性。 它旨在用于双写和回填迁移过程。

  • 该工具仅支持超表的回填。 在使用此工具之前,应单独处理模式迁移和非超表迁移。
  • 该工具针对仅附加工作负载进行了优化。 其他场景可能未完全支持。
  • 为防止连续聚合使用不完整的数据刷新,应关闭任何针对要回填的表的刷新和保留策略。

当在靠近目标数据库的实例中执行时,该工具性能最佳。 理想的情况是在与 Timescale 服务位于同一区域的 EC2 实例中执行。 使用基于 Linux 的 x86_64 发行版。

在准备好将运行 timescaledb-backfill 的实例后,登录并下载该工具的二进制文件

wget https://assets.timescale.com/releases/timescaledb-backfill-x86_64-linux.tar.gz
tar xf timescaledb-backfill-x86_64-linux.tar.gz
sudo mv timescaledb-backfill /usr/local/bin/

timescaledb-backfill 工具提供四个主要命令:stagecopyverifyclean。 工作流程包括创建任务、复制块、验证数据完整性以及在迁移后清理管理模式。

注意

在迁移的上下文中,您现有的生产数据库称为“源”数据库,而您打算将数据迁移到的新 Timescale 数据库称为“目标”数据库。

  • Stage 命令: 用于基于指定的完成点 (--until) 为超表块创建复制任务。 如果未指定起始点 (--from),则将从时间开始到完成点 (--until) 复制数据。 可选的过滤器 (--filter) 可用于优化用于暂存的超表和连续聚合。

    timescaledb-backfill stage --source $SOURCE --target $TARGET --until '2016-01-02T00:00:00'

    可以通过提供过滤选项来控制要包含在暂存中的表

    --filter:此选项接受 POSIX 正则表达式,以匹配模式限定的超表名称或连续聚合视图名称。 仅暂存与过滤器匹配的超表和/或连续聚合。

    默认情况下,过滤器仅包含匹配的对象,而不关心对象之间的依赖关系。 根据预期用途,这对于连续聚合可能会有问题,因为它们形成依赖关系层次结构。 此行为可以通过级联选项进行修改。

    例如,假设在名为 raw_data 的底层超表(全部在 public 模式中)中,数据按小时、天和周汇总的连续聚合层次结构。 这可能如下所示

    raw_data -> hourly_agg -> daily_agg -> monthly_agg

    如果应用过滤器 --filter='^public\.raw_data$',则不会暂存来自连续聚合的数据。 如果应用过滤器 --filter='^public\.daily_agg$',则仅暂存连续聚合 daily_agg 中的物化数据。

    --cascade-up:激活后,此选项确保将依赖于过滤对象的任何连续聚合包含在暂存过程中。 它被称为“向上级联”,因为它在层次结构中向上级联。 使用之前的示例,如果应用过滤器 --filter='^public\.raw_data$' --cascade up,则会暂存 raw_datahourly_aggdaily_aggmonthly_agg 中的数据。

    --cascade-down:激活后,此选项确保将过滤对象依赖的任何对象包含在暂存过程中。 它被称为“向下级联”,因为它在层次结构中向下级联。 使用之前的示例,如果应用过滤器 --filter='^public\.daily_agg$' --cascade-down,则会暂存 daily_agghourly_aggraw_data 中的数据。

    --cascade-up--cascade-down 选项可以组合使用。 使用之前的示例,如果应用过滤器 --filter='^public\.daily_agg$' --cascade-up --cascade-down,则会暂存示例场景中所有对象的数据。

    timescaledb-backfill stage --source $SOURCE --target $TARGET \
    --until '2016-01-02T00:00:00' \
    --filter '^public\.daily_agg$' \
    --cascade-up \
    --cascade-down
  • Copy 命令: 处理在暂存阶段创建的任务,并将相应的超表块复制到目标 Timescale 服务。

    timescaledb-backfill copy --source $SOURCE --target $TARGET

    除了 --source--target 参数之外,copy 命令还接受一个可选参数

    --parallelism 指定将并行运行的 COPY 作业数,默认值为 8。 理想情况下,应将其设置为源数据库和目标数据库拥有的内核数,并且是决定源数据库负载量以及数据从源数据库传输到目标数据库的速度的最重要参数。

  • Verify 命令: 检查源块和目标块的数据之间是否存在差异。 它比较每个块的表的计数结果,以及每列的计数、最大值、最小值和总和值(如果适用,取决于列数据类型)。

    timescaledb-backfill verify --source $SOURCE --target $TARGET

    除了 --source--target 参数之外,verify 命令还接受一个可选参数

    --parallelism 指定将并行运行的验证作业数,默认值为 8。 理想情况下,应将其设置为源数据库和目标数据库拥有的内核数,并且是决定验证期间源数据库和目标数据库的负载量以及验证完成所需时间的最重要参数。

  • Refresh Continuous Aggregates 命令: 刷新目标系统的连续聚合。 它涵盖从目标中上次刷新到源中上次刷新的期间,解决了连续聚合超出刷新策略范围而过时的问题。

    timescaledb-backfill refresh-caggs --source $SOURCE --target $TARGET

    要刷新连续聚合,该命令将为所有匹配的连续聚合执行以下 SQL 语句

    CALL refresh_continuous_aggregate({CAGG NAME}, {TARGET_WATERMARK}, {SOURCE_WATERMARK})

    可以通过提供过滤选项来控制要刷新的连续聚合

    --filter:此选项接受 POSIX 正则表达式,以匹配模式限定的超表连续聚合视图名称。

    默认情况下,过滤器仅包含匹配的对象,而不关心对象之间的依赖关系。 根据预期用途,这可能会有问题,因为连续聚合形成依赖关系层次结构。 此行为可以通过级联选项进行修改。

    例如,假设在名为 raw_data 的底层超表(全部在 public 模式中)中,数据按小时、天和周汇总的连续聚合层次结构。 这可能如下所示

    raw_data -> hourly_agg -> daily_agg -> monthly_agg

    如果应用过滤器 --filter='^public\.daily_agg$',则只会更新连续聚合 daily_agg 中的物化数据。 但是,这种方法可能会导致潜在问题。 例如,如果 hourly_agg 不是最新的,那么 daily_agg 也不会是最新的,因为它需要来自 hourly_agg 的缺失数据。 此外,重要的是要记住在某个时候刷新 monthly_agg,以确保其数据保持最新。 在这两种情况下,如果策略未涵盖整个所需期间,则仅依靠刷新策略可能会导致数据 gaps。

    --cascade-up:激活后,此选项确保刷新依赖于过滤对象的任何连续聚合。 它被称为“向上级联”,因为它在层次结构中向上级联。 使用之前的示例,如果应用过滤器 --filter='^public\.daily_agg$' --cascade up,则将刷新 hourly_aggdaily_aggmonthly_agg

    --cascade-down:激活后,此选项确保刷新过滤对象依赖的任何连续聚合。 它被称为“向下级联”,因为它在层次结构中向下级联。 使用之前的示例,如果应用过滤器 --filter='^public\.daily_agg$' --cascade-down,则将刷新 daily_agghourly_agg 中的数据。

    --cascade-up--cascade-down 选项可以组合使用。 使用之前的示例,如果应用过滤器 --filter='^public\.daily_agg$' --cascade-up --cascade-down,则将刷新所有连续聚合。

  • Clean 命令: 在迁移成功完成后,删除用于存储任务的管理模式 (__backfill)。

    timescaledb-backfill clean --target $TARGET
  • 使用过滤器和截止日期进行回填

    timescaledb-backfill stage --source $SOURCE_DB --target $TARGET_DB \
    --filter '.*\.my_table.*' \
    --until '2016-01-02T00:00:00'
    timescaledb-backfill copy --source $SOURCE --target $TARGET
    timescaledb-backfill refresh-caggs --source $SOURCE --target $TARGET
    timescaledb-backfill verify --source $SOURCE --target $TARGET
    timescaledb-backfill clean --target $TARGET
  • 使用不同的过滤器和截止日期运行多个阶段

    timescaledb-backfill stage --source $SOURCE --target $TARGET \
    --filter '^schema1\.table_with_time_as_timestampz$' \
    --until '2015-01-01T00:00:00'
    timescaledb-backfill stage --source $SOURCE --target $TARGET \
    --filter '^schema1\.table_with_time_as_bigint$' \
    --until '91827364'
    timescaledb-backfill stage --source $SOURCE --target $TARGET \
    --filter '^schema2\..*' \
    --until '2017-01-01T00:00:00'
    timescaledb-backfill copy --source $SOURCE --target $TARGET
    timescaledb-backfill refresh-caggs --source $SOURCE --target $TARGET
    timescaledb-backfill verify --source $SOURCE --target $TARGET
    timescaledb-backfill clean --target $TARGET
  • 使用起始时间和截止时间回填特定时间段

timescaledb-backfill stage --source $SOURCE_DB --target $TARGET_DB \
--from '2015-01-02T00:00:00' \
--until '2016-01-02T00:00:00'
timescaledb-backfill copy --source $SOURCE --target $TARGET
timescaledb-backfill clean --target $TARGET
  • 刷新连续聚合层次结构
timescaledb-backfill refresh-caggs --source $SOURCE --target $TARGET \
--filter='^public\.daily_agg$' --cascade-up --cascade-down

可以通过向进程发送中断信号 (SIGINT) 来安全停止 copy 命令。 这可以通过在当前正在运行该工具的终端中使用 Ctrl-C 键盘快捷键来实现。

当该工具收到第一个信号时,它会将其解释为优雅关闭的请求。 然后,它会通知复制工作程序,一旦他们完成复制当前正在处理的块,他们应该退出。 根据块大小,这可能需要几分钟才能完成。

当收到第二个信号时,它会强制该工具立即关闭,中断所有正在进行的工作。 由于该工具使用了事务,因此在使用强制关闭时,不会有数据不一致的风险。

虽然优雅关闭会等待正在进行的块完成复制,但强制关闭会回滚正在进行的复制事务。 复制到这些块中的任何数据都将丢失,但数据库将保持事务一致状态,并且可以安全地恢复回填过程。

每个要回填的超表块在目标数据库的 __backfill.task 表中都有一个对应的任务。 您可以使用此信息来检查回填的进度

select
hypertable_schema,
hypertable_name,
count(*) as total_chunks,
count(worked) as finished_chunks,
count(worked is null) pending_chunks
from __backfill.task
group by
1,
2

在此页面上发现问题?报告问题 或 在 GitHub 上编辑此页面