资讯动态

OGG架构深度解析:读懂日志复制与数据同步的核心进程

发布时间:2026/10/14 15:54:03 来源:尧图企业网站定制
做数据同步或者说数据灾备的朋友应该都有过这种经历业务系统要跨库迁移、报表库要实时读取生产数据、双活改造要求两边数据保持一致……这几年我梳理过不少OGG相关的集成方案也帮团队排过很多和OGG架构相关的坑。今天这篇文章就想系统性聊聊OGG的架构图怎么读、部署模式怎么选、分类边界在哪里给正在做数据复制选型或者被OGG链路搞得头疼的同学一个参考。全文不依赖具体版本讲的都是底层不变的东西理解之后你拿到任意一组OGG架构图都不会发怵。1. OGG到底是个什么角色先搞清楚它解决什么问题1.1 数据同步的几种粗暴做法和它们的天花板最早做数据同步很多团队用ETL工具定期抽数。比如说每天凌晨跑一次批把生产库的表全量或者增量拉一份到报表库。优点是简单一把SQL一把定时器就能搞定缺点也很明显数据时效性差T1甚至T2都算正常而且全量抽取对源库压力不小业务高峰期还得避开。后来有人用触发器在源业务表上建触发器把变更写到一张记录表再由另一个进程搬走。这个方法时效性好一些但要改业务库结构触发器本身也有性能开销还会拖慢业务事务的提交速度。再往后双写方案也流行过一阵子应用层同时写两个库逻辑上灵活但应用改造量巨大两边只要一边失败就会产生数据不一致。这些方案都不能算错它们的本质问题是所有同步逻辑都依赖业务侧或者应用层的配合没法和数据库自身的事务机制绑定。真正稳妥的做法是从数据库层面的日志里拿数据。OGG就是干这个的它直接读取数据库的事务日志把提交后的变更以事务为单位解析出来再通过网络投递到目标端落地。源库不需要多加索引、触发器也不改业务代码对源库的打扰极小。基于日志复制这一条是OGG所有架构设计的基础后面看到的每一个进程都是围绕“怎么安全地把日志里的变更搬过去”这个问题展开的。1.2 OGG能用的场景不只是做灾备OGG最常见的用法是做数据库容灾也就是把生产库的数据实时复制到另一台机器上的数据库主库挂了备库能快速顶上。第二个常见场景是读写分离和报表分流生产库连接数被打满的时候把查询类流量导向只读库。第三个场景是跨数据库迁移OGG支持异构环境源端和目标端可以是不同类型、不同操作系统的数据库做在线迁移时可以边复制边切换业务停机窗口能压到很短。第四个场景是多个业务系统之间的数据整合比如把分布在几个库里的订单数据集中汇到数据仓库。后面这几个场景有一个共同点它们对数据丢失的容忍度都很低对链路稳定的要求很高。OGG之所以在业界被大量采用核心不是因为它的同步性能有多亮眼而是因为它的架构清晰、进程职责单一、出问题时能按链路一段一段排查。这一点我们接下来细说。2. 架构核心进程组件一颗颗“螺丝钉”各管一摊2.1 Manager进程整个OGG链路的管家OGG架构里每个复制链路上都会有一个Manager进程它负责监管同一台机器上所有OGG进程的启停维护整个OGG环境的正常运行。我们常说的ggsci命令行工具在源端和目标端启动的时候会先拉起Manager进程。Manager的作用有三个一是启动、停止、重启其他进程二是监控进程运行状态三是定期清理过期的Trail文件。进程异常挂掉时Manager会因为配置的自动重启参数把它拉起来Trail文件占满磁盘时Manager会按保留策略把旧文件清掉。所以看一张OGG架构图时先找到Manager它是所有组件里最“基层”的那个。很多人忽略的一个细节是Manager启动时会读取一个全局参数文件这个文件决定了你之后创建的进程配置比如默认的Trail文件目录在哪、是否开启加密传输等。排障过程中发现Manager状态是RUNNING但某个进程一直起不来十有八九是进程配置和Manager期望的全局设定对不上。这个坑我在后面会单独讲。2.2 Extract进程从日志里“抠”事务变更的源头Extract进程部署在源端数据库所在服务器上它的任务只有一个读取源库的事务日志解析出已提交事务中包含的DML操作同时把提交/回滚信息也算进去最后把这些变更写成连续的文件。这个文件就是Trail文件。Extract是整条链路中第一个接触数据的进程它的配置质量直接决定同步准确性。比如不支持在线日志实时解析的数据库类型Extract会退化成用表级或者库级快照方式做初始加载然后再基于日志做增量同步。但在绝大多数主流库场景下Extract都能直接订阅日志解析出来的变更流。需要提醒的是Extract抓取的粒度是“已提交事务”未提交事务的中间状态不会出现在Trail文件里。这一点直接决定了后面任何一层拿到的数据都是干净的事务级快照不会出现“读到一半事务”的情况。2.3 Data Pump进程源端投递要有“二传手”Data Pump是可选进程它部署在源端位于Extract和网络传输之间。作用是把本地的Trail文件读取出来通过网络发送到目标端。有些场景链路很短且明确不需要做路由分发可以不开Data Pump让Extract直接通过网络投递数据。但生产环境里几乎都会开启Data Pump原因很现实Extract如果直接把变更通过网络跨机房发送一旦网络抖动导致超时重传Extract会被拖住进而可能阻塞日志解析而加上Data Pump后Extract只需要把数据写到本地Trail文件投递给目标端的任务独立交给Data Pump进程两边互不干扰。从架构图上理解Data Pump可以把它看作“源端的邮局分拣员”它不负责生成信只负责把已经写好的信装车发走。如果信件发不出去目标端网络断开邮局里的信会越堆越多但写信的人不会被逼停。正因为有这一层“解耦”OGG的实时链路才能在跨机房、弱网的场景下保持相对稳定。2.4 Trail文件和Collector变更数据的中转站与收件柜Trail文件是OGG在磁盘上保存变更数据的文件源端Extract写的是本地Trail文件网络传输链路里目标端也会生成一份远端Trail文件。Trail文件本质上是一个顺序写的二进制文件包含一连串格式化的记录块。它是一个“可中断再续”的关键载体——目标端应用进程可以根据Trail文件里记录的检查点信息从断点继续消费而不是每次重启都从头开始。目标端还有一个容易被忽略的进程叫Collector它负责监听网络端口接收来自源端Data Pump发过来的数据并写入目标端的Trail文件。Collector不像Replicat那样需要人工管理但它的状态是否正常决定了数据能不能落到目标盘上。如果你发现目标端Trail文件不增长而源端Data Pump又显示在正常发送优先检查网络端口连通性和Collector所在磁盘空间这两个问题占了九成。2.5 Replicat进程把变更“搬”进目标库的收尾人Replicat部署在目标端数据库所在服务器上角色和Extract正好对应它读取目标端Trail文件解析出DML操作在目标端数据库逐条应用这些变更。Replicat是整条链路的终点也是最容易出问题的环节。因为到了这里数据格式转换、目标端表结构映射、主键冲突、权限问题都会集中暴露出来。Replicat有两种典型的操作模式一种是直接连接目标端数据库以批处理方式应用SQL另一种是把变更写入外部应用队列由下游业务系统自行消费。前者适合数据库到数据库的同步后者适合做消息流集成。理解Replicat的配置参数时最核心的是它怎么拿到事务边界以及它以怎样的频率提交事务。OGG为了保证目标端数据一致Replicat默认会按照源端事务的提交顺序来应用变更而不是简单地逐行执行这样能最大程度避免外键约束和部分更新的时序问题。3. 部署模式分类拓扑结构决定你能做多大规模3.1 单向复制最简单也最稳的起点单向复制是OGG最基础的部署形态通俗理解就是源端Extract捕获数据投递给目标端Replicat应用数据只朝一个方向流动目标端的变化不会被传回源端。这种模式下不存在循环复制问题也不用配冲突解决规则。适合的场景包括生产库到灾备库、生产库到只读报表库、数据库在线迁移等方向性非常明确的需求。架构图上单向复制往往只有一条线简单干净新手入门最容易掌握。但单向复制不代表你可以随意忽略配置细节比如运维时经常犯的一个错是把源端同步用户或表结构改错了导致Extract记录的数据在目标端Replicat执行时报错。这类错误排查起来要回溯到源端日志解析的原始内容成本不低。3.2 双向复制Active-Active双写一致性问题在这爆发双向复制就是源端和目标端互为源和目标任何一边的数据变更都会被同步到另一边两边都能接受写入。它的价值在于可以做双活架构、就近读写、故障时无缝切换。但代价是必须处理“冲突”——同一条记录在两边几乎同时被修改怎么做决策OGG提供了一套冲突检测和解决策略比如基于时间戳的“最后写入者胜”、基于优先级的“特定节点胜出”、基于业务规则的“自定义解决函数”等。我的建议是除非业务上已经做过分库分表或者写路由保证同一条记录只会被单边写入否则不要轻易上双向复制。双向复制链路一旦出现数据不一致排查难度比单向复制高一个数量级。很多团队以为开启了冲突解决策略就万事大吉实际上策略只是在数据层面生成一个结果业务层面的正确性永远需要应用去兜底。3.3 广播式复制一源多目标只要配置得当没那么可怕广播式复制指一个源端同时向多个目标端投递数据常用于一份主数据同时供给报表库、数仓、下游业务库的场景。实现上也有两种做法一种是在源端开启多个Extract进程每个Extract对应一条目标链路另一种是开启一个Extract加多个Data Pump进程用多个Data Pump把同一个本地Trail文件广播出去。后者的好处是源端日志只需解析一次节省CPU成本和磁盘IO多个目标端之间互不影响。广播式复制在架构图上看起来像一棵树根是Extract枝是各Data Pump叶子是各目标端Replicat。排障时记住一个口诀某一个目标端出了问题只影响那一条分支不会拖垮整个链路千万不要因为一条分支报错就把整条链路相关的进程全部杀掉重启。3.4 集中式复制多源一目标数据汇聚最容易出现角色混乱集中式复制和广播式正好相反多个源端的数据汇到一个目标端常用于数据仓库数据集成、分机房数据的汇总。每一条源端的复制链路都是独立的目标端会有多个Replicat进程每个Replicat对应一个源端。集中式复制的难点不在进程配置而在统一口径不同源库的表结构命名不规范、主键策略不一致、时区字段不统一都会在汇聚时集中爆发。架构图上看起来很简单所有箭头都指向同一个目标但实际落地时表和字段映射规则可能比链路本身复杂得多。我强烈建议在搭建集中式架构之前先建立一套统一的元数据映射规范并写在文档里而不是靠各自写各自的映射参数。3.5 级联式复制绕开网络瓶颈但多了一层时延级联式复制指的是一套OGG链路把数据同步到中间节点再由中间节点作为二次源继续向下一级目标同步。它适用于源端与最终目标端网络不通、带宽受限或者需要跨安全域的复杂场景。中间节点上可能会同时运行着该节点的Replicat和下一段链路的Extract在架构图上形成一条“接力链条”。级联复制的核心代价是端到端时延增加因为数据在中间节点落了一次盘又被读出来。此外排障范围也会扩大——中间节点本身既是目标也是源任何一层处理慢都会沿着链路逐级放大。如果不是确有必要尽量用Data Pump的远端投递能力代替级联实在必须级联时要对每一级的Trail文件增长量和延迟做监控。4. 同步模式与事务一致性架构图上看不到的隐藏维度4.1 实时同步 vs 批量同步OGG最常用的实时同步模式是Extract以近乎实时的频率读取日志尾部变更数据从源端到目标端一般在秒级以内。批量同步通常用于历史数据追平或初始加载手段是把某张表或整个库的数据一次性快照并加载到目标端然后再切换到增量模式。架构图上这两种模式的区分要看进程参数判断实时模式下Extract持续运行Trail文件不断增长Replicat持续消费批量模式下通常会用专门的加载进程或配置临时参数限制范围。实际项目中经常做的是一个组合拳先用OGG的批量模式把历史数据导过去再把链路切到实时模式追平增量。切换窗口要设计好避免出现“历史数据还没导完、增量又追上来了”的中间态。4.2 事务提交序列号、提交顺序与检查点机制OGG里面有一个核心概念叫事务提交序列号它记录了源库每个事务提交时的全局唯一顺序标识。所有Trail文件中的数据记录都带着这个标识Replicat通过它判断事务的先后顺序和完整性。检查点机制则记录每个进程当前处理到哪个位置进程重启后可以从检查点继续而不是从头再来。检查点是OGG架构图中最容易被忽略但最要命的设计。比如Extract的本地检查点写在哪里、Trail文件多久做一次轮转、Replicat多久做一次检查点写入这些参数决定了一次故障恢复的数据损失窗口。把这些参数梳理清楚你才能回答“这套OGG架构到底能保证多小的数据丢失量”这个问题。没有哪个架构能保证绝对零丢失实际项目中要先定好明确可接受的恢复点。4.3 冲突检测与解决方案只有双向复制或多目标同时写同一套表集合的架构才需要冲突解决机制。OGG提供的默认规则有限大多数真实场景下需要编写自定义冲突解决逻辑比如在应用写入时打一条业务流水号或者时间戳列。架构图上不会画出这些规则但数据流里到处都是它们的影子——见过很多案例就是因为冲突解决规则没写对业务数据显示为“已同步成功”但数值最终不对。这里我的经验是冲突规则一定要在项目初期就跟业务团队确认语义比如“最后写入者胜”听起来很合理但如果两边的系统时钟有偏差就会选到错误的一方。最好是业务侧带一个明确单调递增的版本号或者时间戳让OGG的冲突解决有业务依据而不是纯粹靠数据库时钟。5. 从一张架构图读出完整链路实战读图方法论5.1 自底向上还是自上而下很多新手拿到OGG架构图第一反应是从源端开始顺着箭头读这没错但效率不够高。我的习惯是先找Manager和Replicat再找Extract最后才看中间网络。为什么因为架构图上的进程数量往往很多混杂着不同链路的相同角色如果你从源端开始读很容易把两条不同链路的Extract进程看混。推荐顺序是先确认这张架构图覆盖了哪几个“源→目标”链路一般是源库用一个标注块目标库用另一个标注块。然后把链路上的进程按“捕获-投递-接收-应用”四段切分每段对应一个角色再用箭头把四段串起来。四个角色全部对应完毕这张架构图就算读懂了剩下的是参数和细节问题。5.2 同进程不同链路最容易踩的混线坑多链路共存的架构图上经常出现两个Extract进程标着不同名字但部署在同一台服务器上。你可以通过进程名的后缀区分链路归属比如订单链路和用户链路的后缀不同。但架构图维护不当之后线条交叉时很容易出现视觉误导。我的建议是不要把链路画成一张大网优先用子树或分页的方式画。真实排障时先从监控面板捞出进程名和状态再去架构图定位对应链路比“看图找进程”要快得多。5.3 用一张表沉淀常见异常现象平时维护OGG要把“现象→对应角色”的心智模型固化下来。下面这张表是我自己做排障时经常对照的方便从现象快速锁定可疑进程。现象最可能出问题的一层优先检查对象源端日志解析慢捕获层Extract进程、源库日志读取权限、Trail文件目录空间数据迟迟未到目标端网络传输层Data Pump状态、网络连通性、Collector端口监听目标端Trail有数据Replicat不动应用层Replicat状态、数据库连接池、目标表权限Replicat报错大量回滚应用层目标表结构映射、主键冲突、外键约束整条链路卡住但进程全RUNNING协调层Manager参数、磁盘空间、全局配置这张表不是万能药但它能帮你缩小范围。切记不要一上来就动进程先观察现象和日志再定位角色再决定操作。6. 架构选型与落地一些踩过坑后的心得6.1 前期做需求调研时要问的四个问题选型阶段很多项目最后跑偏都是因为前期需求没问清楚就开干。搭建前至少把下面四件事确认下来第一数据流向是单向、双向还是汇流第二数据时效要求是秒级、分钟级还是小时级第三允许的数据丢失窗口是多少第四目标端的表结构能否由源端完全驱动还是允许异构映射这四个问题直接决定了架构图的形态也决定了进程配置参数范围。举个例子如果两个数据中心都要接受写入架构一定是双向的那冲突方案就要提前和业务对齐如果只是灾备就没必要让目标端开放写入权限风险小得多。6.2 运维中我反复遇到的三个坑第一个坑是配置参数前后不一致。我遇到过一位同学在参数文件里配置了加密传输但Manager的全局参数里没有做对应的证书配置导致Data Pump无法建立安全连接而进程状态还是RUNNING线上一直报错。表面看起来像网络断了实际上就是证书没配对。第二个坑是Trail文件清理策略太激进。为了省磁盘把保留时间设得很短导致某一个Replicat因为数据库维护窗口暂停之后再次启动时发现Trail已经被清理成了空洞检查点直接失效只能重新初始化那一段链路的同步场面相当难看。我的建议是保留时间至少覆盖一次完整维护窗口加上一天。第三个坑是误以为OGG所有进程都要手动管理。实际上Collector和部分内部辅助模块是由Manager自动管理的进程配置和参数管理好即可不需要手写启动脚本去硬拉那些内部进程。动手前先分清楚哪些是自己能操作的哪些是框架内部管理的能省掉很多不必要的折腾。6.3 如果真的出了问题第一件事不要重启链路故障时很多人的第一反应是重启进程这是我最想纠正的习惯。遇到OGG异常应该先采集四样东西当前进程状态、日志文件尾部输出、Trail文件的写入/消费进度、数据库连接测试。这四样信息基本能覆盖八成问题的定位。贸然重启有可能让进程从检查点重新读取暴露出更多问题也可能掩盖掉原始报错信息。除非是某个进程明确处于ABEND状态且通过启动命令无法拉起否则不建议第一时间重启。先看日志再翻架构图找到对应的环节确认是配置问题还是环境问题然后才有针对性地处理。排错不是拆弹慢一点反而快。最后说一点个人体会。OGG这套组件设计得比较“朴素”每一个进程只干一件很小的活但恰恰是这种朴素让它在生产环境里长期稳定运转而不被淘汰。真正要用好它靠的不是背命令而是把“捕获-投递-接收-应用”这个链路装进脑子里遇到任何架构图都能快速拆成四段。希望这篇聊架构、聊模式、聊分类的文章能在你做同步选型和日常排障的时候成为一个好用的参考轴。后续如果大家感兴趣我可以再展开讲讲操作细节、初始加载和性能调优的部分。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑