XReader
xReader - PostgreSQL 的 XLOG 阅读器 - Google Summer of Code 2012 项目提案
项目标题 - xReader - PostgreSQL 的 XLOG 阅读器
提案者姓名和电子邮件 - Aakash Goel, [email protected]
摘要
注意:有关所用术语的解释,请参阅“项目细节”。
xReader 是一种工具,允许用户从任何 xlog 流中读取过滤后的数据。
在主服务器 - 热备数据库配置中,xReader 将拦截 xlog 流,并向与其关联的每个监听器提供自定义过滤(基于令牌过滤)的逻辑信息。
该工具将成为未来无触发器审核和复制系统的基础。
xReader 将作为 contrib/ 目录中的扩展程序进行打包。
对 PostgreSQL 社区的益处
xReader 提供的功能将成为未来多种应用程序的基础。由于我们可以直接从 XLOG 流中获取所需的数据,因此可以在 xReader 之上构建依赖于这些数据的工具来开发数据审核、数据分析和数据复制应用程序。这些应用程序中的每一个都将是 xReader 的“监听器”。
该工具还消除了对数据复制和分析任务的触发器的依赖。触发器有一些缺点,包括
- 对主数据库的性能开销 - 想象一下在复杂的复制环境中对更新运行 5 个不同的触发器 - 每次更新发生时,都需要执行 5 个触发器,这会导致巨大的开销。
- 排序问题 - 在特定事件上定义的多个触发器增加了处理触发器触发顺序的复杂性。
- 灵活性 - 触发器过于僵化,无法满足审核和复制需求。如果数据库对象不参与,处理过滤就容易得多。
从 xlog 流中读取自定义过滤的逻辑数据绕过了这些限制。
项目细节
a. 对 xReader 的需求 + 基本设计
PostgreSQL 日志是记录对数据库进行的物理级别更改。例如,对于更新操作,这些记录不会直接说明更新了哪个表的哪个列,而只说明更改了哪个页面的哪些字节。
因此,这些记录无法用于在逻辑级别上执行对数据库的查询。由于性能始终是任何生产数据库的重要因素,因此必须从数据库中卸载这些查询。如果审核或复制应用程序持续查询数据库,它会降低性能。
另一方面,数据库日志可以进行流式传输、复制或分发。有人可能会说,数据库文件也可以。是的,它们可以,但这些数据文件包含物理级别的动态数据。仅当数据库没有更改状态时,使用数据文件才会有用,这几乎不可能发生。
PostgreSQL 数据库日志不包含有关对数据库进行的逻辑更改的信息。如果没有访问逻辑信息,我们就无法理解日志中的数据。由于物理到逻辑的映射信息已经在数据库本身中可用,因此查询数据库元数据是解决此问题的方案。
b. 术语
- 主数据库 - 产生所有数据更改的主数据库。这将在复制配置中充当源数据库。
- 备用数据库 - 正在应用更改的辅助数据库,用于使数据库与主数据库保持同步。
- 监听器 - 可以注册 xReader 的任何客户端的通用名称。
- 注册 - 监听器指定读取 xlog 内容的偏好的过程。
- 注销 - 监听器从 xReader 脱离以停止接收过滤后的 xlog 内容的过程。
- 订阅者 - 发布者模型 - 订阅者向发布者提供其偏好,然后发布者根据这些偏好将信息推送到其每个订阅者的设计模型。
c. 监听器功能
注册
register(<Listener Name>,<xReader Name>,<Comma Separated List of tokens to be read>,<Stream Handle>);
- 监听器名称 = 监听器的唯一名称(每个 xReader 实例唯一)
- xReader 名称 = xReader 的唯一名称
- 要读取的令牌的逗号分隔列表 = 监听器将接收数据的令牌列表
- 流句柄 = xReader 将推送结果数据的流句柄
示例
register('Listener1','xReader_Main','oid,ctid','myfilehandle');
register('Listener2','xReader_Main','*','stdout');
注销
deregister(<Listener Name>,<xReader Name>);
示例
deregister('Listener1','xReader_Main');
d. xReader 将会放在哪里?
如下图所示,xReader 将拦截从主服务器到备用服务器的 xlog 流,查询元数据,并通过为注册的监听器提供过滤后的信息来满足其需求。
e. xReader 的组件是什么?
- 接收器:接收 xlog 流并将其分叉。一个子流传递给发送器,然后传递给备用服务器,而另一个子流传递给解析器进行解析。
- 解析器:解析接收到的流中存在的令牌,并将有关令牌的请求转发给元数据客户端。
- 元数据客户端:作为任何其他客户端连接到备用数据库,并执行必要的查询以理解 xParser 解析的令牌。
- 订阅列表:维护特定时间点所有注册到 xReader 的监听器及其订阅令牌的记录。
- 分配器:对于从解析器接收到的每个信息令牌,循环遍历订阅列表并将数据发送给请求该特定令牌的所有监听器。
- 发送器:将 xlog 流发送到备用数据库,不作任何更改。
f. xReader 将如何工作?
- 接收器将透明地拦截来自源数据库的 xlog 流。
- 发送器将透明地将 xlog 流发送到备用数据库。接收器和发送器共同确保 xReader 对两个数据库都透明。
- 为了破译读取的令牌的逻辑含义,xReader 将查询备用数据库以获取信息。
- 订阅者可以在任何时候添加或分离与 xReader 的关联。
- xReader 将异步接收来自主服务器的日志,并同步将日志发送到备用服务器。必须同步将日志发送到备用服务器并等待应用更改完成,因为我们需要确保元数据查询始终返回正确的结果。
- 只有当所有以前的更改都应用到备用数据库后,元数据客户端才能查询备用数据库。
- 更新备用服务器和查询备用服务器都是阻塞同步操作。
- 一旦获取了所需数据,xReader 将循环遍历订阅列表并发送数据。
- 只要有监听器附加到 xReader,就会重复所有之前的步骤。在没有监听器的情况下,xReader 将充当透明的直通工具。
g. xReader 代码将驻留在哪里?
该工具将作为 PostgreSQL 发行版 contrib 目录中的扩展模块进行打包。
h. 变体和实验
上面描述的 xReader 模型适用于复制环境,并且依赖于备用数据库的可用性。可以探索的一种替代方案是利用主数据库进行元数据查询。下图显示了这种配置。为了确保我们查询的是正确的元数据,需要同步从主数据库流式传输日志。
里程碑
在此处提供要实现的单个增量步骤的列表。
- 创建 xReader 作为简单的直通工具
- 创建接收器,从主数据库监听 xlog 流
- 创建发送器,将 xlog 流发送到备用数据库
- 创建元数据客户端,查询备用数据库
- 为监听器创建注册 + 注销模型
- 创建可以附加到 xReader 并接收数据的简单监听器
- 逐个实现 xlog 记录类型
- 将代码打包为 contrib/ 目录中的扩展程序
- 文档
项目时间表
为上面的里程碑提供时间表。
- 2012 年 6 月 15 日
- 2012 年 6 月 20 日
- 2012 年 7 月 5 日
- 2012 年 7 月 12 日
- 2012 年 8 月 10 日
- 2012 年 8 月 12 日
- 2012 年 8 月 18 日
完成标准
我们如何判断你是否成功?
工作原理证明应用程序 - 使用 xReader 拦截异步的 xlog 记录流,并将它们的逻辑解释转储到磁盘文件。