我可以使用 MariaDb 的自动数据版本控制来捕获变更数据吗

Can I do Change Data Capture with MariaDb's Automatic Data Versioning

我们在生产中使用 MariaDb,并且添加了一个 MariaDb 从站,这样我们的数据团队就可以从这个从站到我们的数据仓库执行一些 ETL 任务。但是,他们缺少适当的更改数据捕获功能(即他们想知道生产 table 中的哪些行自昨天以来发生了更改,以便查询实际更改的行)。

我看到 MariaDb 的 10.3 有一个有趣的 feature 允许在旧版本的 table 上执行 SELECT。但是,我还没有找到支持它可用于 CDC 的想法的资源,对此功能有任何反馈吗?

如果没有,我们可能会求助于将从站的二进制日志流式传输到我们的数据仓库,但这看起来很有挑战性..

感谢您的帮助!

version 10.3.4 以来,MariaDB 支持 System-Versioned 表。系统版本 table 在 SQL:2011 标准中指定。它们可用于自动捕获以前版本的行。然后可以查询这些版本以检索它们在特定时间点设置的值。

以下文字和代码示例来自official MariaDB documentation

With system-versioned tables, MariaDB Server tracks the points in time when rows change. When you update a row on these tables, it creates a new row to display as current without removing the old data. This tracking remains transparent to the application. When querying a system-versioned table, you can retrieve either the most current values for every row or the historic values available at a given point in time.

You may find this feature useful in efficiently tracking the time of changes to continuously-monitored values that do not change frequently, such as changes in temperature over the course of a year. System versioning is often useful for auditing.

通过将 SYSTEM VERSIONING 添加到新创建的或已经存在的 table(使用 ALTER),table 将扩展 row_start 并且row_end 允许检索在开始和结束时间戳之间的时间内有效的记录的时间戳列。

CREATE TABLE accounts (
       id INT PRIMARY KEY AUTO_INCREMENT,
       name VARCHAR(255),
       amount INT
) WITH SYSTEM VERSIONING;

然后可以检索特定时间(SELECT * FROM accounts FOR SYSTEM_TIME AS OF '2019-06-18 11:00';)的数据,特定时间范围内的所有版本

SELECT * FROM accounts
FOR SYSTEM_TIME
   BETWEEN (NOW() - INTERVAL 1 YEAR)
   AND NOW();

或一次所有版本:

SELECT * FROM accounts
FOR SYSTEM_TIME ALL;

(作为 Stefans 回答的补充)

是的,System-Versioning 可用于 CDC,因为 ROW_START(对象开始有效)和 ROW_END(对象现在无效)中的有效期可以解释为发生了插入、更新或删除查询。但与其他 CDC 变体相比,它更麻烦。

插入:

  • 第一次找到对象
  • ROW_START是插入时间

更新:

  • 第一次找不到对象
  • ROW_START为更新时间

删除:

  • ROW_END过去
  • 在接下来的几行中没有该对象的新条目

我会添加一张图片来说明这一点。

您可以看到此版本控制 space 节省,因为您可以在一行中组合有关对象的 INSERT 和 DELETE 的信息,但检查 DELETE 的成本很高。

在上面的示例中,我使用了带有明确主键的 Table。因此检查同一对象很容易:只需查看 id。如果你想用组合键捕捉表格的变化,这也会让整个过程变得更烦人。

编辑:另一点是协议数据保存在与“真实”数据相同的 table 中。对于 INSERT 来说,这可能比已知的替代解决方案(例如每个 TRIGGER 的跟踪(like here)更快),但是如果 table 上的更改非常频繁并且您想 process/analyse CDC-这可能会导致性能问题的数据。