持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情
基于行的逻辑日志复制
另一种方法,复制和存储引擎使用不同的日志格式,这样复制日志就能从存储引擎内部分离。这种复制日志称为逻辑日志,以区分存储引擎的数据表示。
关系数据库的逻辑日志通常是指一系列以行的粒度描述对数据库表的写入的记录序列:
- 插入的行,日志包含所有相关列的新值
- 删除的行,日志有足够信息唯一标识已删除的行。通常靠主键,但若表上未定义主键,则需记录所有列的旧值
- 更新的行,日志有足够信息唯一标识更新的行,及所有列的新值(或至少包含所有已更新列的新值)
涉及多行修改的事务,会生成多个这样的日志记录,后面跟着一条记录指出事务已提交。 MySQL的二进制日志binlog(配置为行复制)就使用该方法。
由于逻辑日志和存储引擎逻辑解耦,因此更容易保持向后兼容,从而使领导者和跟随者能够运行不同版本的数据库软件甚至不同的存储引擎。 对外部应用程序,逻辑日志格式也更易解析。若要将DB内容发到外部系统,如:
- 复制到数仓进行离线分析
- 或构建自定义索引和缓存
这就是数据变更捕获技术。
基于触发器的复制
目前的复制方法都由DB系统实现,不涉及应用程序代码。这通常就是你期望的。但某些情况下,需要更高灵活性。如只想:
- 复制数据的一个子集
- 或想从一种DB复制到另一种
- 或需订制、管理冲突解决逻辑
则需将复制控制移交给应用程序层。
一些工具,如Oracle GoldenGate,可通过读取DB日志,使应用程序获取数据变更。另一种方法是使用许多关系DB自带功能:触发器和存储过程。
触发器支持注册自己的应用层代码,使得当数据库系统发生数据更改(写事务)时自动执行上述自定义代码。触发器支持注册在数据库系统中发生数据更改(写入事务)时自动执行的自定义应用程序代码。通过触发器,可将数据更改记录到一个单独表,然后外部处理逻辑访问该表,实施必要的自定义应用层逻辑,如将数据更改复制到另一个系统。
基于触发器的复制通常比其他复制方法具有更高的开销,并且比数据库的内置复制更容易出错,也有很多限制。然而由于其灵活性,仍然是很有用的。