简介:Oracle GoldenGate(OGG)跨平台同步是数据库运维中的常见需求。这份资料面向有一定 Oracle 基础的 DBA 与数据运维人员,以 Windows 端 Oracle 作为源库、Linux 端 Oracle 作为目标库,系统梳理 OGG 12.2.0.2 的安装部署流程。内容包括开启归档模式与强制日志、添加补充日志、创建 goldengate 表空间和用户、完成 OGG 管理员授权,以及 ggsci 目录初始化、checkpoint 表与 Manager、Extractor、Replicat 进程配置,操作命令和步骤说明均清晰可查。压缩包内含 1 个 PDF 文档,大小约 496KB,篇幅精炼、便于按节点查阅。文档不只列出命令,还解释了各步骤的作用,如 flashback 权限、goldengate 管理员授权和目标库额外 DML 权限的意义,便于理解从源端捕获到目标端应用的完整同步链路,减少配置阶段常见踩坑。已有 295 人学习下载,适合作为 OGG 跨平台部署的快速参考。
1. Windows同步到Linux:OGG跨平台部署到底在解决什么问题
做数据同步的同行应该都有过这种经历:一套业务系统跑在Windows上的Oracle库里,为了降成本或者统一运维,公司决定把数据库迁到Linux服务器。迁移本身不难,难的是迁移窗口之后还有新数据不断产生,旧库不能一停了之,新库又要尽快接管查询。这时候最稳妥的做法不是停库拷贝,而是让两个库并行跑一段时间,实时把Windows上的增量事务搬到Linux端。Oracle GoldenGate(OGG)干的就是这件事,它读源库的redo日志,把变更解析成自己的trail文件,再通过网络投递到目标端重放,不依赖数据库自身的快照或物化视图。
OGG最值钱的地方在于异构和跨平台。Windows到Linux这种组合,Data Guard基本无能为力,因为主备的操作系统不同;物流视图要手动刷增量,延迟和冲突都让人头疼;而OGG从设计上就支持源端和目标端跑在不同操作系统上,只要两边数据库版本兼容、字符集规划好,就能做到秒级延迟的实时同步。这篇文章会把整个部署过程拆开讲透:从版本选型、环境准备,到Windows源端的抽取配置、Linux目标端的复制配置,再到初始化同步和运维踩坑,每一步都给出可复现的命令和参数说明。
适合谁看?一种是刚接触OGG、被迫在异构环境里做同步的新手,照着这篇能把环境搭起来;另一种是已经跑过同平台同步、第一次处理跨平台字符集和文件格式问题的老手,可以直接跳到避坑章节和最后的验证技巧。
2. 部署前必须想清楚的三件事:版本、方向与初始化策略
2.1 OGG版本和数据库版本怎么配才不翻车
OGG的版本选择是整套部署里最不能拍脑袋的一步。很多人上来就下载最新版,结果源端Windows跑着Oracle 11g,目标端Linux上装了19c的数据库,OGG中间件版本却选了一个只支持12c以上数据库的,启动直接报错。OGG的兼容性规则说起来不复杂:OGG微服务架构(21c及以后)只支持较新的数据库版本,而经典架构(20c之前的版本)对11g到19c的支持都还可以。跨平台同步时,源端和目标端的OGG版本最好保持一致,或者至少大版本相同,否则trail文件的格式解析可能出问题。
另一个容易忽略的点是OGG的安装包是分平台分架构的,Windows x64的安装包不能用在Linux上,反之亦然。下载时盯着平台标识选,别拿到一个通用的压缩包就到处解压。还有一个隐藏约束:如果源端数据库是RAC,需要部署OGG集成抽取模式(Integrated Extract)才能正确处理多实例的redo;如果源端是单实例,经典抽取(Classic Extract)就够用。Windows上的Oracle一般不会跑RAC,所以这里按经典抽取来讲,但目标端如果是RAC,复制进程建议用集成复制模式(Integrated Replicat)。
版本选型这块我一般这么落地:先确认源端和目标端Oracle数据库的版本和补丁级别,再在官方兼容性矩阵里找到同时支持这两个数据库版本的OGG版本范围,取中间偏新的那个。说白了就是别用最老的,也别追最新,中间版本最稳。
2.2 Windows到Linux的同步方向有没有隐藏限制
绝大多数OGG同步场景都是单向的:源端在Windows,目标端在Linux,数据只往一个方向流。这个方向组合在功能上没有限制,Extract、Data Pump、Replicat三大进程该怎么配就怎么配,但有几个细节和同平台同步不太一样。
首先是trail文件的格式。OGG在源端生成的trail文件是二进制的,虽然不依赖操作系统,但目标端OGG读取时对字符集编码很敏感。Windows上的Oracle数据库字符集通常是ZHS16GBK,而Linux上新建的数据库很多默认是AL32UTF8,两种字符集在OGG投递过程中如果没做映射转换,中文字段到了目标端就是一堆乱码。这个问题在参数文件里要显式处理,后面初始化同步的章节会展开说。
其次是大小写和文件路径。Windows文件系统不区分大小写,但Linux区分,OGG的参数文件、目录路径、数据文件命名在两端要保持一致的大小写习惯,否则目标端启动进程时报文件找不到,排查起来特别费劲。我见过不止一次有人在Windows上建了参数文件叫ext_sync.prm,到Linux上写成EXT_SYNC.PRM,然后整个进程起不来。
再者,Windows端的OGG服务默认以当前登录用户身份运行,如果这个用户没有权限读取Oracle的redo日志目录,抽取进程会一直报权限错误;而Linux端的OGG服务通常用oracle系统用户运行,文件权限和属主问题更隐蔽。部署前把两端OGG进程的运行用户、目录权限都列清楚,能省掉后面一大半排错时间。
2.3 初始化同步的两种路线,别一上来就双击EXE
OGG只负责同步增量数据,存量数据得靠初始化来搬。初始化同步的路线选择直接决定整个迁移窗口的长短。常见做法有两种:一种是停业务、导出导入全量数据、再启动OGG追增量;另一种是业务不停,用RMAN备份或者数据泵导出的方式先搬基础数据,然后让OGG从某个SCN开始追。
第一种做法适合业务能接受短时间停机的场景。操作流程是:先在源端停止业务写入,记录当前SCN,导出全量数据,传到Linux端导入,然后在OGG里配置从该SCN开始抽取和复制。第二种做法适合不能停机的场景,但需要源端开启归档日志和补充日志,OGG才能从备份时间点之后继续解析redo。千万别直接在业务运行状态下只导数据不记录SCN,那样OGG启动后要么丢数据要么重复数据,两头不讨好。
不管走哪条路线,初始化之前必须确认源端Oracle已开启归档模式,并且打开了最小补充日志和主键补充日志。OGG抽取进程解析redo的前提就是这些日志开关全部打开,没开的赶紧补上,不然进程起来后看不到任何变更。
3. 源端Windows的OGG安装与抽取配置:从解压到Data Pump投递
3.1 Windows端安装OGG:目录规划与GGSCI初始化
Windows上安装OGG比Linux简单,本质上就是把安装包解压到一个专用目录,然后运行GGSCI做初始化。但目录规划要做好,别把OGG装到C盘系统盘,因为trail文件增长很快,系统盘满了操作系统都会出问题。我一般习惯把OGG装在独立数据盘下,比如D:\ogg,和Oracle数据库软件所在盘分开。
安装过程分三步。第一步,解压OGG安装包到目标目录,确保当前用户对目录有完全控制权限;第二步,打开命令行切到OGG目录,运行ggsci进入OGG命令行界面;第三步,在GGSCI里执行CREATE SUBDIRS创建OGG运行所需的子目录结构。代码示例如下:
cd /d D:\ogg ggsci CREATE SUBDIRS EXIT这段命令的逻辑是:ggsci是OGG的控制台入口,所有进程管理都在这里面操作;CREATE SUBDIRS会在当前OGG目录下生成dirprm(参数文件目录)、dirrpt(报告目录)、dirdat(trail文件目录)等固定子目录,没有这些目录OGG根本起不来。参数说明:/d是Windows命令行切换盘符的固定写法,后面路径跟着OGG的实际安装路径走。
接下来配置Manager进程的参数。Manager是OGG的总控进程,负责启动和监控其他进程,它的参数文件在dirprm下,叫MGR.prm。用文本编辑器创建这个文件,写入端口号和日志清理策略:
PORT 7809 DYNAMICPORTLIST 7810-7830 PURGEOLDEXTRACTS ./dirdat/*, USECHECKPOINT, MINKEEPHOURS 24参数含义:PORT 7809是Manager的固定监听端口,源端和目标端都要放通这个端口;DYNAMICPORTLIST 7810-7830是抽取和投递进程动态协商使用的端口范围,防火墙要把这个段也放开;PURGEOLDEXTRACTS是trail文件清理策略,MINKEEPHOURS 24表示至少保留最近24小时的文件,防止投递不及时时文件被误删。这里有个容易踩的坑:MINKEEPHOURS设太短,网络抖动一天以上时trail文件被清掉,目标端追数据直接断层。
写完后回到GGSCI启动Manager:
ggsci START MANAGER INFO MANAGERINFO MANAGER用来确认Manager进程处于RUNNING状态,如果显示STOPPED,检查端口是否被占用、防火墙是否放通、当前用户对OGG目录是否有写权限。
3.2 配置抽取进程EXTRACT:从redo里抓变更
抽取进程是整个OGG链路的起点,它负责读取源库的redo日志并把变更写入本地trail文件。在配置EXTRACT之前,先确认源库的日志模式已经满足要求。用SQL检查:
SELECT SUPPLEMENTAL_LOG_DATA_MIN, SUPPLEMENTAL_LOG_DATA_PK, LOG_MODE FROM V$DATABASE;期望看到的结果是:SUPPLEMENTAL_LOG_DATA_MIN和SUPPLEMENTAL_LOG_DATA_PK都是YES,LOG_MODE是ARCHIVELOG。如果MIN不是YES,执行下面两条SQL开启补充日志,然后重启数据库让归档模式生效:
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS; ALTER SYSTEM ARCHIVE LOG CURRENT;补充日志的原理是:Oracle默认的redo日志只记录被修改的字段,不保证记录主键列的旧值,OGG在目标端执行UPDATE和DELETE语句时需要根据主键定位记录,没有主键补充日志就定位不到。配置好日志后,开始建EXTRACT进程。在GGSCI里执行:
ggsci ADD EXTRACT EXT_SYNC, TRANLOG, BEGIN NOW ADD RMTTRAIL /ogg/dirdat/lt, EXTRACT EXT_SYNC这两条命令的逻辑:ADD EXTRACT创建抽取进程,名字叫EXT_SYNC,类型是TRANLOG(解析日志),BEGIN NOW表示从当前时刻开始捕获变更;ADD RMTTRAIL告诉OGG把抽取结果写到远程trail文件lt开头命名的文件序列,这里/ogg/dirdat/lt是目标端Linux机器上的路径,不是源端的。参数说明:EXT_SYNC这个进程名可以自定义,但建议用有含义的缩写,后面排错时一眼能认出职责。
接下来为EXT_SYNC编写参数文件,在dirprm目录下创建EXT_SYNC.prm:
EXTRACT EXT_SYNC USERID ogg_user@orcl, PASSWORD ogg_password EXTTRAIL /ogg/dirdat/lt TABLE dsg.T_ORDER; TABLE dsg.T_PRODUCT;参数说明:EXTRACT指定进程名;USERID是OGG连接源库的账号,这个账号需要授予DBA角色或者至少SELECT ANY TABLE、ALTER ANY TABLE、LOGMINING相关权限;EXTTRAIL指定本地trail文件路径和序列前缀;TABLE列出要同步的表,格式是模式名.表名,可以用通配符dsg.*同步整个模式,但生产环境我建议显式列出要同步的表,避免把临时表、日志表也同步过去。
然后回到GGSCI启动抽取进程并查看状态:
ggsci START EXTRACT EXT_SYNC INFO EXTRACT EXT_SYNC VIEW REPORT EXT_SYNCINFO看进程启停状态,VIEW REPORT看运行日志。这里有个重要的检查点:启动后等一分钟,再执行STATS EXTRACT EXT_SYNC,如果看到Extract statistics里的Total operations在增长,说明redo解析正常;如果一直是0,大概率是补充日志没开或者日志挖掘权限有问题。
3.3 配置Data Pump:把trail文件送到Linux
Extract进程写本地trail只是第一步,真正跨网络传输的是Data Pump进程。Data Pump其实就是第二个Extract,它读取本地trail文件,压缩加密后通过TCP投递到目标端。为什么要多这一层?因为Extract直接投递的话,网络抖动会影响日志解析的连续性,把抽取和投递拆开,源端本地trail攒着,网络恢复了Data Pump继续传,不丢不重。
在GGSCI里创建Data Pump进程:
ggsci ADD EXTRACT DP_SYNC, EXTTRAILSOURCE /ogg/dirdat/lt ADD RMTTRAIL /ogg/dirdat/rt, EXTRACT DP_SYNCEXTTRAILSOURCE指向前一步配置的本地trail文件路径,RM TTRAIL指向目标端Linux上的trail文件路径,前缀用rt区分。这里注意:源端trail前缀lt和目标端trail前缀rt不能相同,否则OGG在两端共用目录时会产生文件覆盖。
DP_SYNC的参数文件DP_SYNC.prm这样写:
EXTRACT DP_SYNC RMTHOST 192.168.1.100, PORT 7809 RMTTRAIL /ogg/dirdat/rt TABLE dsg.T_ORDER; TABLE dsg.T_PRODUCT;RMTHOST后面跟目标端Linux服务器的IP和Manager端口,RMTTRAIL就是上一条ADD命令里定义的路径。需要注意的是,这里的TABLE列表要和Extract保持一致,如果两边不一致,OGG会报Table not found in extract file之类的错误。启动过程和Extract一样:START EXTRACT DP_SYNC、INFO EXTRACT DP_SYNC、VIEW REPORT DP_SYNC。
这一步常见的坑是:Extract正常在跑,但Data Pump的trail文件在目标端一直不出现。排查顺序是:先在源端看INFO EXTRACT DP_SYNC的状态是否是RUNNING,再用VIEW REPORT看有没有报网络错误,最后去目标端Linux的/ogg/dirdat目录下看文件有没有过来。80%的情况是防火墙没放通7809端口,或者RMTHOST的IP写错了。
4. 目标端Linux的OGG安装与复制配置:从解压到Replicat执行
4.1 Linux端安装OGG:权限、目录和系统环境
Linux端的安装比Windows端多几个前置条件:操作系统用户、目录权限、动态库依赖。OGG进程不能以root身份运行,必须用Oracle数据库的属主用户(通常是oracle)来启动。另外Linux的OGG安装包解压后运行时依赖libc、libaio等系统库,缺了库进程起不来,启动时报error while loading shared libraries。
安装步骤先从创建目录和授权开始:
mkdir -p /ogg chown -R oracle:oinstall /ogg su - oracle cd /ogg unzip ogg_linux_x64.zip命令逻辑:chown -R把/ogg目录的属主改为oracle用户和oinstall用户组,确保后续OGG所有进程都有权限写入;su - oracle切换到数据库属主用户再解压,避免用root解压后文件属主不一致。参数说明:oinstall是Oracle安装时创建的用户组,如果目标机器上没建,建一个就行,OGG只用到属主和组权限。
接着初始化GGSCI:
ggsci CREATE SUBDIRS和Windows端一样,生成dirprm、dirrpt、dirdat等目录。然后配置Linux端的Manager参数,创建MGR.prm:
cd /ogg/dirprm vi MGR.prm PORT 7809 PURGEOLDEXTRACTS ./dirdat/*, USECHECKPOINT, MINKEEPHOURS 24注意Linux端的Manager端口最好和Windows端一致,方便运维记忆,但这不是强制要求。如果目标端有多个OGG实例,端口要错开。启动Manager:
ggsci START MANAGER INFO MANAGER4.2 配置Replicat:把trail变成目标库的SQL
Replicat进程是OGG链路的终点,它读取目标端trail文件,把里面的操作重放到Linux数据库上。Replicat的配置分两步:先创建进程,再写参数文件。
创建Replicat进程的命令:
ggsci ADD REPLICAT REP_SYNC, EXTTRAIL /ogg/dirdat/rtREP_SYNC是进程名,EXTTRAIL指向Data Pump投递过来的trail文件路径。注意:这里的路径和源端RMTTRAIL定义的路径必须完全一致,OGG在目标端就是靠这个路径找到投递来的文件。
然后编写REP_SYNC.prm参数文件:
REPLICAT REP_SYNC USERID ogg_user@orcl, PASSWORD ogg_password ASSUMETARGETDEFS MAP dsg.T_ORDER, TARGET dsg.T_ORDER; MAP dsg.T_PRODUCT, TARGET dsg.T_PRODUCT;参数说明:ASSUMETARGETDEFS表示源端和目标端表结构一致,OGG直接按源端定义的字段映射,不用额外传defgen文件;MAP是源表到目标表的映射关系,格式是源模式.源表, TARGET 目标模式.目标表,表名可以不同,只要这里显式指定映射。如果两端表结构有差异,比如目标端加了字段,就不能用ASSUMETARGETDEFS,需要在源端用defgen工具生成定义文件传到目标端,写法会复杂不少。
现在先别启动Replicat,因为初始化同步还没做,trail文件里还没有数据。标准流程是:先做完存量数据导入,再从某个SCN开始启动Replicat。但这里可以先启动Replicat做一次空跑验证参数配置是否正确:
ggsci START REPLICAT REP_SYNC如果进程秒级退出,用VIEW REPORT REP_SYNC看日志,最常见的问题是数据库账号密码错、目标表不存在、目标端OGG用户没有对应表的DML权限。确认进程能稳定运行后,停掉它,等初始化完成再正式启动。
4.3 目标端数据库的准备:表空间、用户与字符集
Replicat要往目标库写数据,目标库必须提前建好对应的表空间、业务用户和表结构。OGG只复制DML操作,不复制DDL,更不会帮你建表建用户,这些都得在初始化阶段提前做好。
表空间和用户用SQL创建:
CREATE TABLESPACE DSG_DATA DATAFILE '/u01/app/oracle/oradata/ORCL/dsg01.dbf' SIZE 10G AUTOEXTEND ON NEXT 1G MAXSIZE 32G; CREATE USER dsg IDENTIFIED BY dsg_password DEFAULT TABLESPACE DSG_DATA QUOTA UNLIMITED ON DSG_DATA; GRANT CONNECT, RESOURCE, DBA TO dsg;表结构直接复用源库的建表脚本,或者用数据泵导入时带上结构。这里要特别留意DBA角色的授予:OGG的Replicat进程运行账号如果权限不够,执行INSERT、UPDATE、DELETE会报ORA-01031: insufficient privileges,但又不是所有环境都敢直接给DBA,折中方案是授予CONNECT、RESOURCE、SELECT ANY TABLE、INSERT ANY TABLE、UPDATE ANY TABLE、DELETE ANY TABLE这几项,够用且不过度授权。
字符集这块,前面说过Windows源库通常是ZHS16GBK,Linux目标库可能是AL32UTF8。在OGG层面要做一次显式转换,方法是在Replicat参数文件里加一行:
SOURCEDEFS /ogg/dirdef/source.def如果两端字符集不一致但表结构一致,更简单的做法是在源端Data Pump参数里设置:
SETENV (NLS_LANG = "AMERICAN_AMERICA.ZHS16GBK")SETENV这个参数设置OGG进程读取源库时的语言环境,强制它按源库字符集解析。实际部署中,我一般建议目标端数据库直接建为ZHS16GBK,和源端一致,从根上消除字符集转换的变数;如果目标端必须建AL32UTF8,那就要在Replicat端反复验证中文数据落地没问题再继续。
5. OGG跨平台同步的避坑指南:四个踩烂了的坑
5.1 源端抓不到日志变化,进程一直无操作
现象:Extract进程状态是RUNNING,但STATS EXTRACT显示Total operations一直为0,源端业务表里插入了新数据,目标端始终看不到。
原因:最常见的是补充日志没开全。只开了最小补充日志但没有开主键补充日志,OGG解析不到UPDATE和DELETE操作的主键信息,这类变更会被静默丢弃。另一种情况是OGG账号缺少读取redo的权限,尤其是LOGMINING相关权限,导致日志挖掘会话建立失败但进程不报错。
解决:用第3.2节的SQL确认SUPPLEMENTAL_LOG_DATA_PK是YES,不是就执行ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;再重启数据库。权限问题在OGG账号上补上GRANT SELECT ANY TRANSACTION, GRANT EXECUTE ON DBMS_LOGMNR, GRANT EXECUTE ON DBMS_LOGMNR_D这几项,然后重启Extract进程。这类问题排查很耗时间,建议在部署阶段就把日志和权限一次性检查到位,别等同步跑起来了才回头补。
5.2 目标端中文乱码,数字和字母正常
现象:同步过去的表里,英文和数字准确,中文字段全部变成问号或者乱码符号。用户一看就是乱码,但OGG各进程状态全正常,没有报错。
原因:源端字符集是ZHS16GBK,目标端是AL32UTF8,Data Pump在投递过程中没有做字符集转换,OGG按源端编码读取后投递,目标端Replicat却按数据库字符集去解析,两边编码对不上。为什么没有报错?因为OGG认为字符集转换是数据库层的事,它只负责搬运字节。
解决:两种方案。方案一,把目标库的字符集改成和源库一致,最省事但需要重建数据库;方案二,在源端Data Pump参数文件里加SETENV (NLS_LANG = "AMERICAN_AMERICA.ZHS16GBK"),强制Data Pump按GBK解析源端日志,在投递到目标端之前完成编码转换。改完参数后重启Data Pump进程,重新同步一条中文记录验证。如果已经同步了一堆乱码数据,最直接的办法是先清掉目标端表数据,再重新做一次初始化。所以初始化同步时就要把字符集问题处理好,等数据量大了再返工,血泪经验。
5.3 Replicat进程启动后秒退,报找不到表
现象:START REPLICAT REP_SYNC刚执行完,INFO一看进程变成ABENDED,VIEW REPORT里报ERROR OGG-01172或者ORA-00942: table or view does not exist。
原因:目标端表不存在,或者表名大小写不一致。OGG的MAP语句里写的是dsg.T_ORDER,如果目标库里的表实际建成了DSG.T_ORDER(双引号大写),在Linux的Oracle里大小写敏感,找不到就是找不到。在Windows源库上,表名大小写不敏感,容易让人忽略这个差异。
解决:在目标端确认表名实际大小写:
SELECT OWNER, TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'DSG';如果表名是大写,把MAP语句改成对应的大小写;如果表还没建,用源端导出的建表脚本原样执行,不要手工改大小写。修改参数文件后,在GGSCI里执行STOP REPLICAT REP_SYNC(如果卡在ABENDED要先KILL),再START REPLICAT REP_SYNC。这里还有个习惯:ADD REPLICAT时我习惯把进程名和表名统一用小写,减少跨平台大小写混淆的概率。
5.4 初始化导入后启动Replicat,重复数据导致主键冲突
现象:用数据泵导完全量数据后启动Replicat,进程开始运行,但过一会儿报主键冲突ORA-00001: unique constraint violated,同步被终止。
原因:初始化数据导出时源库业务没有完全停,导出的SCN和Extract开始抓取的SCN有重叠。比如导出开始时是SCN 1000,但导出结束已经到SCN 2000,Extract从SCN 1500开始抓取,这中间产生的变更既在导出数据里,又在trail文件里,Replicat重放时插入重复记录。
解决:初始化必须和OGG的抽取SCN对齐。做法是:先在源端停业务写操作(或者至少保证没有事务),在GGSCI里用INFO EXTRACT EXT_SYNC查到Extract当前读到的SCN,然后基于这个SCN做数据导出;导出完成后启动Replicat时,指定从该SCN开始重放。命令是:
ggsci START REPLICAT REP_SYNC, SCN 1500SCN参数让Replicat跳过SCN 1500之前的所有trail操作,直接从1500开始。如果已经踩了坑数据不一致,最干净的办法是把目标端表数据truncate掉,重新做一次初始化,再按上述方式启动。这个坑碰到过就长记性了:先在源端停业务,再记SCN,再导出,顺序不能乱。
6. 用ANYCSCN参数把增量追平:一个省心的初始化同步技巧
第5章说到了SCN对齐的问题,那个方案适合停机时间可控的场景。但生产上经常遇到的情况是:数据库不能停,业务每秒都在写入,初始化导出一个十亿级的大表要跑好几个小时,这期间源端事务不断产生,SCN一直在往前走,Replicat启动时到底该从哪个SCN开始?
很多人的第一反应是:取导出开始时的SCN作为基线,然后让Replicat从基线SCN往后放。问题是导出过程中产生的那些变更已经不在导出快照里了,从基线SCN开始放会漏掉导出期间的数据;取导出结束时的SCN,又和导出数据包含的变更重叠,产生主键冲突。OGG的ANYCSCN参数就是为了解决这个两难设计的。
ANYCSCN的作用是告诉Replicat:启动时不要强行校验trail文件里的第一条操作SCN是否和启动SCN匹配,允许从任意SCN开始重放,遇到已经存在的数据(即初始化导出已经包含的变更)自动跳过主键冲突。配好这个参数后,整个初始化流程就简化成:先启动Replicat并加上ANYCSCN,再启动Data Pump,再启动Extract,让OGG自己从当前时刻开始抓取并回放,不需要手动记录SCN,也不需要停业务。核心命令如下:
ggsci ALTER REPLICAT REP_SYNC, SCN 0 EDIT PARAMS REP_SYNC在参数文件REP_SYNC.prm里加上:
REPLICAT REP_SYNC USERID ogg_user@orcl, PASSWORD ogg_password ASSUMETARGETDEFS ANYCSCN MAP dsg.T_ORDER, TARGET dsg.T_ORDER; MAP dsg.T_PRODUCT, TARGET dsg.T_PRODUCT;ALTER REPLICAT ... SCN 0把Replicat的启动点重置到开始位置,ANYCSCN则取消SCN严格匹配的限制。这个组合的巧妙之处在于:当Replicat遇到trail里某条记录在目标端已经存在时,它不会像默认模式那样报主键冲突,而是当作幂等操作跳过;当遇到目标端不存在的记录(即导出后产生的增量)时正常插入。整个追平过程是自动化的。
配合ANYCSCN,我还会加一个HANDLECOLLISIONS参数,它让Replicat在遇到UPDATE操作时如果找不到目标记录,就把它转成INSERT再执行,进一步降低初始化追平阶段的误报错风险。不过这个参数在正常运行期必须拿掉,因为业务高峰期如果都开着手工容错,反而会掩盖真实的同步问题。我的习惯是:初始化追平阶段用ANYCSCN加HANDLECOLLISIONS双保险,追平后ALTER REPLICAT去掉HANDLECOLLISIONS,保留ANYCSCN继续跑。
验证追平是否完成的标准话术是:在GGSCI里执行INFO REPLICAT REP_SYNC看Read checkpoint和Write checkpoint是否一致,如果两个checkpoint的SCN相同,说明Replicat已经追到trail文件尾部。再对比源端和目标端业务表的总行数,以及最近一分钟的新增记录数,两边一致就算真正跑通了。这套方案我用过不止一次,从Windows到Linux的跨平台同步,配合ANYCSCN做初始化,整个切换窗口可以压到重新起Replicat的那几十秒,给业务方留的维护窗口非常宽裕。最后还是那句老话:踩过的坑都写在前面几章里了,照着做能少走很多弯路,希望帮到你。
本文还有配套的精品资源,点击获取