本文档提供详细的说明,使用 实时迁移 策略,将数据从您的 TimescaleDB 数据库(自托管或在 TimescaleDB 托管服务 上)迁移到 Timescale 实例,使生产应用程序的停机时间最短(大约几分钟)。为了简化迁移,我们为您提供了一个包含执行实时迁移所需的所有工具和脚本的 Docker 镜像。
您应该预配一个专用实例来运行迁移步骤。此实例应该有足够的空间来容纳数据复制期间发生的缓冲更改。这与在此期间写入数据库的新数据量(未压缩)大致成正比。一般来说,100 GB 到 500 GB 就足够了。
注意
在迁移上下文中,您的现有生产数据库称为“源”数据库,而您打算将数据迁移到的新 Timescale 数据库称为“目标”数据库。
详细来说,迁移过程包括以下步骤
- 在 Timescale 中设置目标数据库实例。
- 准备源数据库以进行实时迁移。
- 运行实时迁移 Docker 镜像。
- 验证目标数据库中的数据并将其用作新的主数据库。
提示
如果您遇到问题,可以通过打开支持请求或将问题提交到 社区 Slack 中的 #migration
频道来寻求帮助,该频道有此迁移方法的开发者提供帮助。
您可以直接从 Timescale 控制台 或通过电子邮件发送至 support@timescale.com 打开支持请求。
如果您打算迁移超过 400 GB 的数据,请打开支持请求以确保在您的 Timescale 实例上预配了足够的磁盘空间。
您可以直接从 Timescale 控制台 或通过电子邮件发送至 support@timescale.com 打开支持请求。
注意
为了方便起见,在本指南中,源数据库和目标数据库的连接字符串分别称为 $SOURCE
和 $TARGET
。这可以在您的 shell 中设置,例如
export SOURCE=postgres://<user>:<password>@<source host>:<source port>/<db_name>export TARGET=postgres://<user>:<password>@<target host>:<target port>/<db_name>
重要
不要使用 Timescale 连接池连接进行实时迁移。使用连接池可能会出现一些问题,并且没有任何优势。非常小的实例可能默认没有配置足够的连接,在这种情况下,您应该在实例中修改 max_connections
的值,如 配置数据库参数 中所示。
确保在您的源数据库中,old_snapshot_threshold
的值设置为默认值 -1
非常重要。这可以防止 PostgreSQL 将快照中的数据视为过时数据。如果此值设置为除 -1
之外的值,则可能会影响现有数据迁移步骤。
要检查 old_snapshot_threshold
的当前值,请运行以下命令
psql -X -d $SOURCE -c 'show old_snapshot_threshold'
如果查询返回的值不是 -1
,则必须更改它。
如果您在自托管数据库上有超级用户,请运行以下命令
psql -X -d $SOURCE -c 'alter system set old_snapshot_threshold=-1'
否则,如果您使用的是托管服务,请使用您的云提供商的配置机制将 old_snapshot_threshold
设置为 -1
。
接下来,您应该将 wal_level
设置为 logical
,以便预写日志 (WAL) 记录逻辑解码所需的信息。
要检查 wal_level
的当前值,请运行以下命令
psql -X -d $SOURCE -c 'show wal_level'
如果查询返回的值不是 logical
,则必须更改它。
如果您在自托管数据库上有超级用户,请运行以下命令
psql -X -d $SOURCE -c 'alter system set wal_level=logical'
否则,如果您使用的是托管服务,请使用您的云提供商的配置机制将 wal_level
设置为 logical
。
重新启动您的数据库以使更改生效,并验证设置是否反映在您的数据库中。
接下来,您需要确保您的源表和超表具有主键或已设置 REPLICA IDENTITY
。这很重要,因为它是复制 DELETE
和 UPDATE
操作的必要条件。副本标识帮助复制过程识别正在修改的行。它默认使用表的 primary key。
如果表没有主键,您需要手动设置副本标识。一种选择是使用仅包含标记为 NOT NULL
的列的唯一、非部分、非延迟索引。这可以设置为副本标识
ALTER TABLE {table_name} REPLICA IDENTITY USING INDEX {_index_name}
如果没有主键或可用的唯一索引可用,则必须将 REPLICA IDENTITY
设置为 FULL
。如果您预计在表上进行大量的 UPDATE
或 DELETE
操作,则不建议使用 FULL
。对于每个 UPDATE
或 DELETE
语句,PostgreSQL 会读取整个表以查找所有匹配的行,这会导致复制速度明显变慢。
ALTER TABLE {table_name} REPLICA IDENTITY FULL
重要
TimescaleDB 2.12 及更高版本允许在超表上设置 REPLICA IDENTITY
。但是,如果您使用的是低于 2.12 的版本,则您的超表必须具有主键。如果没有,您需要升级您的 TimescaleDB 实例。这是因为,如果没有主键或 REPLICA IDENTITY
,DELETE
和 UPDATE
等操作将不会被复制,这会影响迁移后数据的一致性。
接下来,下载实时迁移 Docker 镜像
docker run --rm -it --name live-migration \-e PGCOPYDB_SOURCE_PGURI=$SOURCE \-e PGCOPYDB_TARGET_PGURI=$TARGET \--pid=host \-v ~/live-migration:/opt/timescale/ts_cdc \timescale/live-migration:v0.0.23 --helpLive migration moves your PostgreSQL/TimescaleDB to Timescale Cloud with minimal downtime.options:-h, --help Show this help message and exit-v, --version Show the version of live-migration toolSubcommands:{snapshot,clean,migrate}Subcommand helpsnapshot Create a snapshotclean Clean up resourcesmigrate Start the migration
实时迁移包含 3 个子命令
- 快照
- 清理
- 迁移
总体来说,
snapshot
子命令会创建到源数据库的 Postgres 快照连接以及复制槽。这是运行 migrate
子命令的先决条件。
migrate
子命令通过借助 snapshot
子命令创建的快照和复制槽来执行实时迁移过程。
clean
子命令旨在删除与实时迁移相关的资源。它应该在迁移成功完成或如果您需要从头开始重新启动迁移过程时运行。如果您想恢复上次中断的实时迁移,则不应运行 clean
。
执行此命令以建立快照连接;不要中断该过程。为了方便起见,请考虑使用终端多路复用器(如 tmux
或 screen
),这使该命令能够在后台运行。
docker run --rm -it --name live-migration-snapshot \-e PGCOPYDB_SOURCE_PGURI=$SOURCE \-e PGCOPYDB_TARGET_PGURI=$TARGET \--pid=host \-v ~/live-migration:/opt/timescale/ts_cdc \timescale/live-migration:v0.0.23 snapshot
除了创建快照外,此过程还会验证源和目标上的先决条件,以确保数据库实例已准备好进行复制。
例如,它会检查源上所有表是否都具有 PRIMARY KEY 或 REPLICA IDENTITY。如果没有,它会显示一条警告消息,列出没有 REPLICA IDENTITY 的表,并在继续创建快照之前等待用户确认。
2024-03-25T12:40:40.884 WARNING: The following tables in the Source DB have neither a primary key nor a REPLICA IDENTITY (FULL/INDEX)2024-03-25T12:40:40.884 WARNING: UPDATE and DELETE statements on these tables will not be replicated to the Target DB2024-03-25T12:40:40.884 WARNING: - public.metricsPress 'c' and ENTER to continue
migrate
子命令支持以下标志
docker run --rm -it --name live-migration-migrate \-e PGCOPYDB_SOURCE_PGURI=$SOURCE \-e PGCOPYDB_TARGET_PGURI=$TARGET \--pid=host \-v ~/live-migration:/opt/timescale/ts_cdc \timescale/live-migration:v0.0.23 migrate --helpusage: main.py migrate [-h] [--dir DIR] [--resume] [--skip-roles] [--table-jobs TABLE_JOBS] [--index-jobs INDEX_JOBS][--skip-extensions [SKIP_EXTENSIONS ...]] [--skip-table-data SKIP_TABLE_DATA [SKIP_TABLE_DATA ...]]options:-h, --help Show this help message and exit--resume Resume the migration--skip-roles Skip roles migration--table-jobs TABLE_JOBSNumber of parallel jobs to copy "existing data" from source db to target db (Default: 8)--index-jobs INDEX_JOBSNumber of parallel jobs to create indexes in target db (Default: 8)--skip-extensions [SKIP_EXTENSIONS ...]Skips the given extensions during migration. Empty list skips all extensions.--skip-table-data SKIP_TABLE_DATA [SKIP_TABLE_DATA ...]Skips data from the given table during migration. However, the table schema will be migrated. To skip data from aHypertable, you will need to specify a list of schema qualified chunks belonging to the Hypertable. Currently, thisflag does not skip data during live replay from the specified table. Values for this flag must be schema qualified. Eg:--skip-table-data public.exclude_table_1 public.exclude_table_2
接下来,我们将开始迁移过程。打开一个新的终端并启动实时迁移,并让它持续运行。
docker run --rm -it --name live-migration-migrate \-e PGCOPYDB_SOURCE_PGURI=$SOURCE \-e PGCOPYDB_TARGET_PGURI=$TARGET \--pid=host \-v ~/live-migration:/opt/timescale/ts_cdc \timescale/live-migration:v0.0.23 migrate
注意
如果迁移命令在执行过程中因任何原因停止,您可以通过添加 --resume
标志从停止的位置恢复迁移。只有在 snapshot
命令完好无损且使用了卷挂载(如 ~/live-migration
)的情况下才有可能。
migrate
命令使用在先前步骤中创建的快照,并将现有数据迁移到目标。然后,它会将事务从源流式传输到目标。在此过程中,您会看到回放过程状态
Live-replay will complete in 1 minute 38.631 seconds (source_wal_rate: 106.0B/s, target_replay_rate: 589.0KiB/s, replay_lag: 56MiB)
如果实时回放无法跟上源数据库上的负载,您会看到类似以下的错误消息
WARN live-replay not keeping up with source load (source_wal_rate: 3.0MiB/s, target_replay_rate: 462.0KiB/s, replay_lag: 73MiB)
实时回放追赶上后,实时迁移会显示以下内容
Target has caught up with source (source_wal_rate: 751.0B/s, target_replay_rate: 0B/s, replay_lag: 7KiB)To stop replication, hit 'c' and then ENTER
重要
应用程序停机时间从此处开始。请确保您有一个策略来验证目标数据库中的数据,然后再将应用程序下线,以将总体停机时间降至最低。
实时回放追赶上后,并且您已准备好将应用程序下线,请停止所有写入源数据库的应用程序。这标志着停机时间的开始,它会持续到您 验证 了目标数据库中的数据为止。
停止写入源数据库可以让实时迁移过程完成将数据复制到目标数据库。
当您看到 目标已追赶上源
消息并且您的应用程序没有写入数据库时,请按 c
键,然后按 ENTER 键停止复制。
Target has caught up with source (source_wal_rate: 46.0B/s, target_replay_rate: 0B/s, replay_lag: 221KiB)To stop replication, hit 'c' and then ENTER
实时迁移工具会继续完成剩余的工作,包括复制 TimescaleDB 元数据、序列和运行策略。迁移完成后,您会看到以下消息
Migration successfully completed
现在所有数据都已迁移,两个数据库的内容应该相同。如何验证这一点取决于您的应用程序。您可以比较行数或列的聚合来验证目标数据库是否与源匹配。
重要
应用程序停机时间从此处结束。
一旦您对数据验证有信心,最后一步就是配置您的应用程序以使用目标数据库。
要清理与实时迁移相关的资源,请使用以下命令
docker run --rm -it --name live-migration-clean \-e PGCOPYDB_SOURCE_PGURI=$SOURCE \-e PGCOPYDB_TARGET_PGURI=$TARGET \--pid=host \-v ~/live-migration:/opt/timescale/ts_cdc \timescale/live-migration:v0.0.23 clean --prune
--prune
标志用于删除迁移过程中在 ~/live-migration
目录中所需的临时文件。请务必注意,执行 clean
命令意味着您无法恢复中断的实时迁移。
关键词
在这页上发现问题了吗?报告问题 或 在GitHub上编辑此页面。