【问题标题】:AWS DMS - Microsecond precision for CDC on MYSQL as source EndPointAWS DMS - MYSQL 上的 CDC 作为源端点的微秒精度
【发布时间】:2020-01-08 01:21:59
【问题描述】:

我正在使用 AWS DMS 从 MYSQL 作为源端点迁移数据,并将 S3 作为目标端点。
我想从源跟踪更新,所以在配置过程中,我启用了 TimestampColumnName 属性(列名:event_timestamp)。
在结果(如下所列)中,我得到了记录/事件的时间戳,但 NOT 是微秒精度。

我希望微秒级精度在此基础上构建序列逻辑。
我已经调查了源端点和目标的属性,但没有得到想要的结果。这是示例输出:

如果我缺少任何属性,有人可以看看并提出建议。
输出格式:因为我在 S3 中的文件是镶木地板。

【问题讨论】:

  • 某些 AWS DMS 能否解决这个问题?
  • 你用什么工具从s3查询数据?
  • 让我们看看存储/加载/传输时间戳的架构、代码等。
  • @ChrisPollard:我在 S3 中输出 parquet 文件,并在本地机器上使用 spark 读取数据。问题中的屏幕截图是我得到的输出。
  • ParquetTimestampInMillisecond 参数是否未设置或为 false?

标签: mysql database amazon-web-services amazon-s3 aws-dms


【解决方案1】:

这个问题已经有一年多了,但我遇到了同样/类似的问题,我想我会解释一下我是如何解决它的,以防它可以帮助其他人。

我在 RDS 中有表,并且正在使用 DMS 将它们从 RDS 迁移到 S3。在 DMS 任务设置中,我启用了时间戳列和 parquet 文件格式。我想使用存储在 S3 中的 CDC 文件将其插入到我的数据湖中。因此,为了做到这一点,我需要通过获取对 RDS 表中特定记录的最新操作来对行进行重复数据删除。但就像您面临的问题一样,我注意到时间戳列的精度不高,因此选择具有最大时间戳的行不起作用,因为它会返回多行。所以我添加了一个新的 row_number 列,按时间戳列排序,按 id 分组,并选择了 MAX(row_number)。这为我提供了应用于我的表的 CDC 行的最新操作。

table.withColumn("row_number", row_number().over(Window.partitionBy("table_id").orderBy("dms_timestamp")))

以上是 pyspark 代码,因为那是我用来处理镶木地板文件的框架,但您可以在 SQL 中执行相同的操作。我注意到,当记录按时间戳列排序时,即使时间戳相同,它们也会保持原来的顺序。

希望这可能对您要实现的顺序逻辑有所帮助。

【讨论】:

  • 感谢您的解决方案,这对我有用!
【解决方案2】:

不幸的是,AWS DMS S3 TimestampColumnName从 MySQL 源加载更改数据捕获 (CDC) 添加的 DATETIME 列只有秒精度.

因为MySQL 二进制日志中的事务时间戳只有几秒


最简单的解决方案是在 MySQL 表中添加新列 - timestamp with microsecond precision,并在插入或 / 时设置默认值并更新 automatically 并将此列用作 event_timestamp

ts TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

另外,检查 AWS DMS 中到 S3 的 setting ParquetTimestampInMillisecond 是否为 False(或不存在/未设置,默认为 false)。


AWS DMS S3 TimestampColumnName 设置将带有时间戳的列添加到输出中。

在“静态”读取中 - 它将生成当前时间戳:

对于完全加载,此时间戳列的每一行都包含一个时间戳,用于指示 DMS 将数据从源传输到目标的时间。

对于 CDC,它将从数据库事务日志中读取事务时间:

对于变更数据捕获 (CDC) 负载,时间戳列的每一行都包含在源数据库中提交该行的时间戳。

其精度将是数据库事务日志中的时间戳之一:

...精度的四舍五入取决于 DMS 对源数据库支持的提交时间戳。

CDC 模式本质上是replication。应适当配置源数据库以写入此类事务日志。数据库写入此日志事务信息以及事务/提交时间戳。

对于 MySQL,这是the binary log。而 MySQL binlog timestamp 只有 32 位 - 只需几秒钟。


此外,此事务时间戳可能并不总是与事务的实际顺序一致,或者顺序更改实际上是在 (link 1, link 2) 提交的。

【讨论】:

  • 这就是我关心的问题:Because transaction timestamp in MySQL binary log has only seconds. 在满载期间,当支持微秒的时间戳时,甚至数据库也支持微秒时间戳(如您建议的时间戳(6)),然后在 CDC 期间,为什么没有以高精度写入提交日志。
  • timestamp(6) - 如果 MySQL 表中的时间戳字段具有微秒精度。因此,该字段已经存在于原始数据库中,并且包含存储的微秒值。
  • TimestampColumnName - 将新列添加到导出的 /synced 文件(或其他目标)。此列及其值不存在于原始表中。如果这是满载(不是 cdc)- 值是动态生成的,这是 transfer time,当此行被复制到目标时。该值由 AWS DMS 而非原始数据库生成,精度为微秒。
  • 使用 CDC TimestampColumnName 从原始数据库事务日志中获取时间值,而不是在传输/同步时生成它。在 CDC 模式下,不会读取表并复制行,而是读取并同步数据库事务日志(mysql binlog)。数据库如何写入其事务日志 - 取决于 db 引擎。在 MySQL 的情况下 - binlog 有每个事务的时间戳,它只有几秒钟。
  • 简而言之——这是 MySQL 的特性——事务时间戳被添加到二进制日志中,它只有第二个精度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-25
  • 2021-03-12
  • 2011-02-04
  • 2016-07-25
  • 1970-01-01
相关资源
最近更新 更多