我可以使用 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-这可能会导致性能问题的数据。
我们在生产中使用 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-这可能会导致性能问题的数据。