文档章节

DBus数据库表结构变更处理方案

宜信技术学院
 宜信技术学院
发布于 07/10 14:15
字数 2222
阅读 109
收藏 4

导读:DBus是我们要介绍的在敏捷大数据(Agile BigData)背景下的第一个平台。企业中大量业务数据保存在各个业务系统数据库中,为同时解决数据同步的一致性和实时性问题,DBus(数据总线)平台应运而生。

DBus专注于数据的实时采集和实时分发,是一种基于日志的解决方案,同时能够提供消息订阅的方式给下游系统使用。本篇文章主要介绍在DBus的设计中,它是如何处理表结构变更及其带来的各种问题的。

数据库表结构变更在软件产品快速迭代过程中是普遍存在的现象,抽取数据库中的数据是DBus最重要的功能之一,那么对于数据库中表结构变更及其带来的各种问题,DBus是如何处理的呢? (本文仅讨论DBus for Oracle的实现方案)

贴源输出是DBus的基本设计原则之一,通过解析后的数据库日志获取数据转换成UMS输出到Kafka,当表结构发生变更时DBus必须能够及时的调整输出UMS的结构,以确保和数据库中表结构保持一致,这里有两个问题需要解决:

1)如何感知表结构变更?

2)表结构变更后,新的表结构要如何与OGG输出的二进制数据关联?

一、感知表结构变更

对于感知表结构变更,Oracle已经通过DDL trigger为我们提供了很好的支持,接下来我们要考虑的是如何让DBus感知到表结构变更? 我们讨论出以下两种方案:

1.1 RPC方案

在DDL trigger中调用DBus提供的REST服务,将表结构变更事件发送给DBus。

该方案思路简单容易实现,但也有一些明显的弊端,比如DBus需要提供高可用、低延时的REST服务,否则可能会使数据库中的DDL操作变得缓慢甚至执行出现错误; DBus 的REST服务器对有数据实时同步需求的所有数据库都必须开通防火墙策略,这将给DBus的部署带来很大的麻烦。

1.2 OGG实时同步方案

在DDL trigger中将表结构变更事件存储到一张Event表里,然后通过OGG实时的从日志中将数据同步到Kafka,从而感知表结构变更事件。

该方案实现相对复杂但具有很多优点,比如对数据库的侵入性相对较小,DDL执行时只是将数据写入到Event表中,相对网络通信来说,其延时更低、可靠性更高;更明显的优势是这种方案基于数据库日志实现,能够使用Event表的数据,严格的将表结构变更前后的数据区分开。

举例来说,对于表:test来说,依次执行insert → alter → insert 三个操作,因为OGG读取数据库日志存在延时,如果利用RPC方案,可能出现这样的一种情况:DBus REST服务接收到alter事件之后,第一个insert的记录才被OGG捕获并发送给DBus,此时DBus会认为这条数据中包含alter变化后的数据。这是一个很严重的问题,而OGG实时同步方案无论数据还是时间均通过OGG读取日志的方案实现,可以完美的避免这种问题的发生。

对比两种方案OGG实时同步方案优势明显,最终我们采用此方案。

然而,采用这种方案也并非一帆风顺,按照该方案的总体思路实现以后,我们遇到了一个很奇怪的问题:通过DDL trigger写到Event表中的数据无法被OGG读取,在经历多番尝试无解之后,我们试图到OGG的文档中寻找答案,而最终的结果却是:DML or DDL operations performed from within a DDL trigger are not captured.

这个答案让问题变得更棘手,但这是最佳方案,我们没有理由放弃。于是我们开始尝试在DDL trigger中调用存储过程,在存储过程中执行Event表的insert操作,但由于存储过程和DDL trigger仍然属于同一个事务,因此Event表的数据依然不能被OGG捕获,但通过这个尝试我们觉得只要在另外一个事务中写Event表就能解决我们面临的问题,于是我们又想到了RPC,但RPC缺点太过明显。那么有没有其他可以替代的方案呢?

实际上oracle数据库里可以使用多种语言来编写存储过程,Oracle 8i开始支持java编写存储过程,于是我们立即开始实现java存储过程,通过JDBC连接数据库实现Event表的写入并提交事务,最终通过实践验证了这种办法的可行性,OGG成功的获取到了DDL trigger调用java存储过程写入到Event表的数据。

然而,这种实现并不算完美。当我们在生产环境部署DDL trigger的时候,发现数据库服务器中并没有安装执行java所需要的组件,每次部署都需要DBA同学安装执行java存储过程所需要的组件,我们试图找到一个不使用java存储过程的方案。这里要感谢韩锋老师对我们的帮助,韩老师在听了我 们的实现原理之后,启发我们自治事务应该可以解决这个问题,我们即刻动手开始改造DDL trigger,使之支持自治事务,经过改造之后该方案才算完美,最终实现逻辑如图1所示:

二、处理表结构变更事件

DBus已经具备通过事件方式感知表结构变更的能力,接下来详细说明一下表结构变更事件该如何处理。

下图描述了Event的完整处理流程:

Event中描述了发生结构变更的表名、该表所属的schema以及元数据版本号,DBus接受并解析Event之后,根据表名、schema以及版本号调用元数据抓取模块获取该表的元数据(包括表的字段类型、长度以及注释等)信息,实际上DDL trigger和alter语句在一个事务中执行,这样在trigger执行过程中无法从oracle的数据字典里获取到修改之后表结构元数据,我们写入到meta_history表中的元数据只是执行alter语句之前的元数据信息(因此我们给这个表取名为table_meta_his),要得到完整的元数据信息需要联合table_meta_his和数据字典进行查询,示意SQL如下:

这个SQL的结果有两种可能:

1)只包含all_tab_cols视图中的数据

2)既包含all_tab_cols视图中的数据又包含table_meta_his表的数据(is_current字段的作用是区别该字段的来源)

结果A表明在table_meta_his表中没有找到数据,这说明在生成表结构变更Event至元数据抓取程序成功获取元数据期间没有再次发生表结构变更,结果B则说明在此期间又发生过一次或多次表结构变更。

为什么要使用union all?

单独使用上图中的两个SQL可能导致元数据获取程序获取到错误的结果,例如:接到表结构变更Event 1后,我们调用SQL 1 查询table_meta_his结果集为空,在调用SQL 2之前表结构再次发生变更(命名为Event 2),这种情况下我们通过SQL 2 查询到的结果实际上是再次变更后的结果,使用这个结果产生的元数据去解析Event 1和Event 2之间的数据,如果两次表结构变更是不兼容的,那么必然会导致解析失败。

感知表结构变更以及处理表结构变更事件的最终目的是能够生成正确的输出结果,其中的更多细节以及实现可以参考:

https://github.com/BriData/DBus

作者:张玉峰

来源:宜信技术学院

© 著作权归作者所有

宜信技术学院

宜信技术学院

粉丝 239
博文 140
码字总数 465067
作品 5
东城
私信 提问
实时数据平台设计:技术选型与应用场景适配模式

实时数据平台(RTDP,Real-time Data Platform)是一个重要且常见的大数据基础设施平台。在href="http://mp.weixin.qq.com/s?biz=MzI4NTA1MDEwNg==&mid=2650769309&idx=1&sn=1ddfddafc057f0......

卢山巍
2018/08/09
0
0
DBus API的使用(讲的很清晰)

转自DBus 入门与应用--基本概念 上(C API 级别的使用观点)、DBus 入门与应用--基本概念 下(C API 级别的使用观点) 转载请注明出处 作者: 唐风 DBus是用来进行进程间通信的。下面这张...

sflfqx
2013/03/12
5.3K
0
wpa_supplicant软件架构分析

struct socket 数据结构 interface network callback 目录(?)[+] 启动命令 wpa_supplicant 初始化流程 main函数 wpasupplicantinit函数 wpasupplicantadd_iface函数 wpasupplicantrun函数 Wp......

sflfqx
2013/09/18
444
0
 宜信正式开源其AIOps落地三大利器

宜信正式开源其AIOps落地三大利器 宜信技术研发中心在CNUTCon全球运维技术大会上宣布正式开源支撑AIOps 的三大利器:UAVStack, Wormhole, DBus. 不断开放开源技术,推动技术共同成长是宜信技...

宋庆离
2017/09/11
2.4K
1
linux的分布式思想

上一篇《X window的思想和终端的重大意义》谈到unix的哲学影响,继承unix的linux在分布式方面表现的淋漓尽致,它首先采用了x window作为自己的图形界面机制,然后又用netlink套接字作为自己的...

晨曦之光
2012/04/10
351
0

没有更多内容

加载失败,请刷新页面

加载更多

好程序员大数据教程Scala系列之样例类_Option_偏函数

  好程序员大数据教程Scala系列之样例类_Option_偏函数,在Scala中Option类型样例类用来表示可能存在或也可能不存在的值(Option的子类有Some和None)。Some包装了某个值,None表示没有值。 ...

好程序员官网
5分钟前
0
0
zk中ServerCnxnFactory连接管理工厂

作为ServerCnxn的工厂抽象类 属性 ZOOKEEPER_SERVER_CNXN_FACTORY zookeeper.serverCnxnFactory secure 在ServerCnxnFactory中SSL是否启用 sessionMap session管理配置中信息(sessionId,Ser......

writeademo
6分钟前
0
0
【代码审计01】几种常见的漏洞种类以及代码审计工具

前言 代码审计是在经过黑盒测试完毕,也就是检查应用的基本功能是否符合产品业务需求下进行的。需要有一定的编码基础以及对漏洞形成原理的基本认知,通过工具或者经验检测中代码中可能出现的...

北桥苏
7分钟前
0
0
重磅发布 | 全球首个云原生应用标准定义与架构模型 OAM 正式开源

作者: OAM 项目负责人 导读:2019 年 10 月 17 日,阿里巴巴合伙人、阿里云智能基础产品事业部总经理蒋江伟(花名:小邪)在 Qcon 上海重磅宣布,阿里云与微软联合推出开放应用模型 Open A...

阿里巴巴云原生
9分钟前
0
0
【进阶之定义函数】一个查询树结构数据的集合

1、基本定义 delimiter 自定义符号  -- 如果函数体只有一条语句, begin和end可以省略, 同时delimiter也可以省略create function 函数名(形参列表) returns 返回类型  -- 注意是retru...

卯金刀GG
15分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部