简介:面向数据库管理员与运维工程师的Oracle GoldenGate跨平台数据同步部署指南,聚焦Windows源端到Linux目标端的完整实施流程。资源以OGG 12.2.0.2版本为例,覆盖从数据库初始化到OGG进程配置的关键环节:源端需开启归档模式、强制记录日志与附加日志,创建goldengate表空间和用户,并通过dbms_goldengate_auth授予OGG管理员权限;目标端则建立对应账号,额外授予insert、update、delete any table权限,同时开启enable_goldengate_replication参数。在此基础上,文档详细演示了ggsci中创建OGG子目录、配置Manager、Extractor、Replicat进程与checkpoint表的方法,并给出可视化安装、GLOBALS参数设置以及日常监控、日志管理、故障排查的建议。整个PDF共1个文件,容量496KB,章节划分清楚,每一步都附带可直接执行的SQL命令和说明,读者可按源端、目标端、进程配置等模块快速定位查阅。资源已有295人学习浏览,适合正在搭建异构环境实时同步、实施OGG迁移或准备灾备演练的Oracle技术团队参考使用。
1. 从 Windows 源库到 Linux 目标库:OGG 12.2.0.2 这套部署到底怎么落地
做 Oracle 数据同步的人,早晚会被 OGG(Oracle GoldenGate)这套东西绊一脚。这篇笔记拆的是 OGG 12.2.0.2 在 Windows 源库与 Linux 目标库之间的完整部署过程,覆盖从数据库前置准备、OGG 软件安装、Manager/Extract/DataPump/Replicat 四级进程配置,到初始化数据和增量 DML/DDL 同步验证的整条链路。适合两类人:一类是从没碰过 OGG、需要一套能照着敲的命令清单的 DBA;另一类是已经配过同构环境、但第一次做跨平台同步,想确认附加日志、字符集、checkpoint 表这些环节有哪些坑的人。文章所述操作均基于 OGG 12.2.0.2 版本在 Oracle 11g 源库向 Linux 目标库同步的模拟项目场景,版本差异会在关键处标注。
2. 同步前置条件:源库和目标库的数据库配置
2.1 为什么必须先开归档、强制日志和附加日志
OGG 的抽取进程读取的是 Oracle 在线日志和归档日志。如果数据库跑在非归档模式,日志切换时历史日志被覆盖,抽取进程读取不到完整事务数据,同步会断。这个逻辑在单机同步场景中容易忽略,因为很多人以为只有 Data Guard 才需要归档。实际上 OGG 的 Extract 进程在日志中定位事务起点,归档模式是它的命根子。
源库强制日志(force logging)的作用是确保所有 DML 操作即使绕过数据库的正常日志路径,也会生成完整日志记录。附加日志(supplemental log)则是 OGG 能拿到"更新前镜像"的关键——没有附加日志,OGG 在 apply 阶段只能拿到 ROWID,无法还原完整记录。
具体操作在源库用 sysdba 执行:
-- 源库:以 mount 模式启动后开启归档 SQL> startup mount SQL> alter database archivelog; SQL> alter database open; -- 开启强制记录日志模式 SQL> alter database force logging; -- 开启最小附加日志 SQL> alter database add supplemental log data; -- 确认两个参数都已生效 SQL> Select SUPPLEMENTAL_LOG_DATA_MIN, FORCE_LOGGING from v$database; -- 切换日志,让附加日志真正进入日志流 SQL> alter system switch logfile;参数说明:SUPPLEMENTAL_LOG_DATA_MIN显示 YES 表示最小附加日志已生效;FORCE_LOGGING显示 YES 表示强制日志模式已开启。alter system switch logfile这一步不是可选的,我在实际部署中见过附加日志参数已经设置但没切换日志文件、导致 OGG 抽取进程一直报日志信息不足的情况。日志切换后新生成的 redo 才完整携带补充日志数据。
2.2 goldengate 用户、表空间与权限授予
OGG 需要独立的数据库用户来连接源库和目标库。这个用户要建专门的表空间,避免把数据文件散落在 SYSTEM 表空间里。源库和目标库的操作基本一致,唯一差别是目标库不需要附加日志,但需要额外的 DML 权限来执行复制写入。
源库执行:
-- 创建 OGG 专用表空间 SQL> create tablespace goldengate datafile '/u01/app/oracle/oradata/test1/ogg01.dbf' size 300m autoextend on ; -- 创建用户并指定默认表空间 SQL> create user goldengate identified by goldengate default tablespace goldengate; -- 基础权限 SQL> grant connect, resource, create session, alter session to goldengate; -- flashback any table:初始化数据时 OGG 通过闪回查询获取一致快照 SQL> grant flashback any table to goldengate; -- 授予 OGG 管理员权限 SQL> exec dbms_goldengate_auth.grant_admin_privilege('GOLDENGATE'); -- 开启 OGG 复制必需的数据库参数 SQL> alter system set enable_goldengate_replication = true scope=both;目标库额外执行:
-- 目标库额外权限:replicat 进程写入数据用 SQL> grant insert any table, update any table, delete any table to goldengate;参数说明:enable_goldengate_replication是 OGG 在 Oracle 11g 及以上版本运行的前置参数,不开启的话 Extract 或 Replicat 启动直接报错。dbms_goldengate_auth.grant_admin_privilege这个存储过程的作用是给用户赋予 OGG 内部管理权限,后续配置 GLOBALS 里的 GGSCHEMA 指定用户时,必须是已经被这个存储过程授权过的用户。
目标库不需要alter database add supplemental log data,因为 Replicat 是消费端,它读 Trail 文件里已经包含完整前后镜像的数据。目标库只管把数据写进表里,不需要自己生成附加日志。我在实际配置中见过有人源库目标库都开附加日志的"保险"操作,这在功能上没有危害,但增加了目标库 redo 生成量,完全没有必要。
2.3 归档模式的坑:确认日志切换是否正常
归档模式开启后,OGG 抽取进程依赖归档日志的连续性。如果归档目录空间不足导致归档进程 hang 住,Extract 进程会报 OGG-00235 或 OGG-01161 之类的错误,表现为日志无法读取。检查方法是在源库执行archive log list确认归档目录状态,同时监控v$archived_log视图看最近归档日志是否正常生成。我在配置时习惯先确认源库的 DB_RECOVERY_FILE_DEST 或 LOG_ARCHIVE_DEST_n 指向的目录有足够空间,再启动 OGG 进程。
3. OGG 软件安装与 GLOBALS 初始化:这一层做错后面全白搭
3.1 解压与静默式安装
本次测试基于 OGG 12.2.0.2 版本,安装包是一个 zip 压缩文件,解压后有两个目录:一个是源库 Windows 的安装包,另一个是目标库 Linux 的安装包。Windows 端解压后直接运行 Setup.exe 走图形界面,Linux 端解压后的安装核心命令如下。如果你拿到的是 Linux x64 的安装包,解压后目录结构里会有 Disk1 目录。
安装时用 oracle 系统用户操作,不要用 root。OGG 软件目录建议规划在独立文件系统下,不要放在 ORACLE_HOME 下面,便于版本升级和权限隔离。
# 切换到 oracle 用户 su - oracle # 解压安装包 unzip 122022_fbo_ggs_Linux_x64_shiphome.zip # 进入安装目录 cd fbo_ggs_Linux_x64_shiphome/Disk1 # 启动图形安装界面 ./runInstaller安装过程中的关键选择项包括:安装目录(比如 /u01/app/ogg)、数据库版本(选择 11g 或 12c,取决于目标库版本)、是否配置自动启动。这里有个经验值:源库如果是 Windows,安装路径建议不要带空格和中文,否则后续edit params写路径时经常因为转义问题翻车。另外,Windows 端安装完成后,OGG 程序目录下会有ggsci.exe,Linux 端是./ggsci,后续两个端的命令操作界面逻辑一致,但路径分隔符和权限模型不同,统一用 forward slash 写参数文件里的路径,避免踩坑。
3.2 创建子目录与 GLOBALS 参数文件
安装完成后的第一件事是进入 GGSCI 命令行创建子目录。源端和目标端都要执行这一步,而且必须用 oracle 用户登录 OGG 安装目录后执行。你可能会问为什么强调这个,因为create subdirs是在当前目录下创建的,如果当前目录不对,子目录会出现在错误的路径下,后面 MGR 进程找不到 checkpoint 表信息。
# 进入 GGSCI 交互界面 [oracle@test1 ogg]$ ./ggsci GGSCI (test1) 1> create subdirs执行后系统会依次创建 dirprm、dirrpt、dirchk、dirpcs、dirsql、dirdef、dirdat、dirtmp、dircrd、dirwlt、dirdmp 这 11 个子目录。其中最常用到的是 dirprm(进程参数文件)、dirdat(Trail 文件)和 dirrpt(报告与丢弃文件)。我见过有人在 Windows 端把 OGG 装在中文目录下,create subdirs 成功后后续编辑参数文件时路径识别异常,这个从安装路径规划阶段就要避免。
创建子目录后,配置全局参数文件 GLOBALS。这个文件不存放在 dirprm 下,而是放在 OGG 安装根目录下,用edit params ./GLOBALS打开编辑。注意./GLOBALS是相对路径,必须精确写到文件名,否则命令不识别。
GGSCI (test1) 2> edit params ./GLOBALS文件内容如下:
GGSCHEMA goldengate CHECKPOINTTABLE goldengate.ggschkpt SYSLOG NONE参数说明:GGSCHEMA 指定 OGG 管理用户,必须是之前用dbms_goldengate_auth.grant_admin_privilege授权过的用户;CHECKPOINTTABLE 指定 checkpoint 表的全名,格式是 schema.table;SYSLOG NONE 表示不向操作系统 syslog 写入日志,避免日志刷屏。
这里有个容易忽略的细节:GLOBALS 文件修改后,需要重启 MGR 进程才会生效。如果你配置完 GLOBALS 不重启 MGR 就启动 Extract 进程,OGG 会报找不到 checkpoint 表,但实际上表已经建了。我当时在这个问题上耗了半天,最后发现是 MGR 没重启,旧配置还驻留在内存里。
3.3 checkpoint 表到底是干什么的
checkpoint 表的核心作用是记录 Replicat 进程的消费进度。OGG 的抽取进程在读了 redo 日志后,把事务写入 Trail 文件,然后由 DataPump 投递到目标端。目标端的 Replicat 进程从 Trail 文件读取并 apply 到数据库。如果 Replicat 进程意外退出,重启后它需要一个记录"上次 synced at this point"的信息来定位从哪个位置继续读 Trail 文件,这个位置信息就存在 checkpoint 表里。
先 dblogin 再用 goldengate 用户创建 checkpoint 表:
# 用 goldengate 用户登录数据库 GGSCI (test1) 4> dblogin userid goldengate password goldengate # 创建 checkpoint 表 GGSCI (test1 as goldengate@test1) 6> add CHECKPOINTTABLE goldengate.ggschkpt源端和目标端都要执行这个操作。注意源端即使没有 Replicat 进程,也需要创建 checkpoint 表,因为 MGR 进程自身也会使用 checkpoint 信息管理 trail 文件清理。我在只配了抽取链路没有配置复制链路的测试环境中,漏掉了源端的 checkpoint 表创建,导致 MGR 启动后自动删除捕获进程还在使用的 trail 文件,系统报 OGG-01017 错误。
3.4 MGR 进程参数详解
MGR 是 OGG 的门卫进程,负责启停其他进程、动态端口分配、清理历史文件。源端和目标端的 MGR 参数基本一致。
GGSCI (test1 as goldengate@test1) 7> edit params mgr参数文件内容:
PORT 7809 DYNAMICPORTLIST 7800-7810 USERID goldengate,PASSWORD goldengate AUTORESTART ER *,RETRIES 3, WAITMINUTES 5, RESETMINUTES 60 LAGREPORTMINUTES 10 LAGCRITICALMINUTES 10 PURGEOLDEXTRACTS ./dirdat/*, USECHECKPOINTS, MINKEEPHOURS 12 PURGEDDLHISTORY MINKEEPDAYS 7, MAXKEEPDAYS 14, FREQUENCYHOURS 3 PURGEMARKERHISTORY MINKEEPDAYS 7, MAXKEEPDAYS 14, FREQUENCYHOURS 3参数说明:
- PORT 7809:MGR 进程监听端口。源端 DataPump 配置的 RMTHOST 后面跟着的端口号就是它。
- DYNAMICPORTLIST 7800-7810:当 OGG 需要建立多条网络连接时,动态分配的端口范围。如果你源端配置了多个 Extract 进程,每个进程投递数据时都可能需要独立的端口。
- AUTORESTART:进程异常退出后自动重启,3 次重试,每次间隔 5 分钟,60 分钟周期内重置计数。
- PURGEOLDEXTRACTS:定期清理 dirdat 目录下老的 Trail 文件,USECHECKPOINTS 保证不清理掉 Replicat 还没读到的文件,MINKEEPHOURS 12 是保留最近 12 小时的 Trails。
启动 MGR 用start mgr,查看状态用info mgr。如果 MGR 启动失败,看 OGG 安装目录下 ggserr.log 的尾部,大部分问题出在端口被占用或 GLOBALS 配置错误。
4. 抽取到投递到复制:三级进程配置的完整链路
4.1 DDL 同步前置脚本的执行顺序
OGG 处理 DDL 同步需要在数据库上执行一套脚本,这套脚本在 OGG 安装目录下。源库需要执行,因为 DDL 捕获发生在源端,目标库不执行这些脚本,只需要在 Replicat 参数里配置 DDL INCLUDE MAPPED 子句来接收 DDL。
先看脚本文件在哪个位置。OGG 安装目录下通常会看到 marker_setup.sql、ddl_setup.sql、role_setup.sql、ddl_enable.sql、ddl_pin.sql 这几个脚本。执行顺序不能乱:先是 marker_setup.sql,然后 ddl_setup.sql,再 role_setup.sql,接着把角色授权给 goldengate 用户,然后 ddl_enable.sql 启用 DDL 捕获,最后可选执行 ddl_pin.sql 把 DDL 触发器相关对象驻留内存提升性能。
-- 用 sysdba 连接源库 SQL> conn / as sysdba -- 授予 utl_file 执行权限,DDL 脚本运行时需要写文件系统 SQL> grant execute on utl_file to goldengate; -- 依次执行 DDL 配套脚本,注意路径要对应 OGG 安装目录 SQL> @/u01/app/ogg/marker_setup.sql SQL> @/u01/app/ogg/ddl_setup.sql SQL> @/u01/app/ogg/role_setup.sql -- 将 OGG DDL 角色授予 goldengate 用户 SQL> GRANT GGS_GGSUSER_ROLE TO Goldengate; -- 启用 DDL 捕获 SQL> @/u01/app/ogg/ddl_enable.sql -- 可选:将 DDL 对象驻留内存,提升 DDL 复制性能 SQL> @/u01/app/ogg/ddl_pin goldengate注意:ddl_setup.sql执行过程中会要求输入 schema 名称,脚本会提示你指定一个 OGG 管理用户;role_setup.sql执行后会创建一个名为 GGS_GGSUSER_ROLE 的角色,需要你手动把该角色授予 goldengate 用户。在执行ddl_enable.sql之前,必须完成角色授权,否则启用失败。这个顺序我在第一次配置时踩过,当时先把 ddl_enable 跑了,角色没授予,报了一串权限不足。其实脚本顺序在安装文档里写得很清楚,但紧张起来容易跳步,建议按上面顺序一步一步来,每步执行完确认输出中没有ORA-字符串再进入下一步。
4.2 添加表级附加日志:有主键和没主键是两套玩法
表级附加日志是 OGG 能把 UPDATE 操作还原成完整 SQL 的基础。add trandata命令会在数据库级别设置该表的补充日志属性。
GGSCI (test1) 3> dblogin userid goldengate password goldengate # 为需要同步的表添加表级附加日志 GGSCI (test1 as goldengate@test1) 13> add trandata TEST.T1执行成功后输出信息类似:
Logging of supplemental redo data enabled for table TEST.T1. TRANDATA for scheduling columns has been added on table 'TEST.T1'. TRANDATA for instantiation CSN has been added on table 'TEST.T1'.有个关键限制:如果表上没有主键或唯一索引,add trandata命令会提示你必须指定一个或多个列作为附加日志的关键列。我一般这样处理:先看表结构里有没有业务主键,如果有,直接add trandata;如果没有主键但有唯一索引,OGG 会自动识别;如果什么都没有,需要手工指定列,比如add trandata TEST.T1 COLS (ID, NAME)。这里的 COLS 指定的列会被 OGG 用来做 UPDATE 定位和重复数据过滤,不是随便选几个列就行,要选那些业务上能够唯一定位一条记录的列。
还有一点容易被忽略:DDL 同步开启时,新表通过 OGG 复制到目标端后,如果源端执行了ALTER TABLE ADD COLUMN之类的 DDL,目标端的表结构变了,但表级附加日志不会自动更新。EE80 版本的DDLOPTIONS ADDTRANDATA参数可以解决这个问题,12.2.0.2 版本同样支持。配置 Extract 进程参数时,这个参数建议加上。
4.3 源端 Extract 进程:事务捕获的第一站
Extract 进程是 OGG 链路的第一环,它直接连接源库读取 redo 日志,解析事务,把数据写入本地的 Trail 文件。配置参数文件:
GGSCI (test1) 1> edit param extgsxf参数文件内容:
-- Extract 进程名:extgsxf EXTRACT extgsxf -- 设置环境变量,确保连接源库时使用正确的 ORACLE_HOME 和 SID SETENV (ORACLE_HOME="/u01/app/oracle/product/11.2.0/db_1") SETENV (ORACLE_SID="test1") SETENV (NLS_LANG="AMERICAN_AMERICA.AL32UTF8") -- 数据库连接信息 USERID goldengate,PASSWORD goldengate -- 本地 Trail 文件前缀 EXTTRAIL ./dirdat/gs -- 日志读取参数 TRANLOGOPTIONS LOGRETENTION DISABLED BR ,BRINTERVAL 20M TRANLOGOPTIONS BUFSIZE 2048000 -- 是否捕捉 Replicat 进程产生的数据,防止数据回流 GETREPLICATES CACHEMGR CACHESIZE 2GB -- truncate 操作同步 GETTRUNCATES -- DDL 复制范围:只捕获映射的表/索引对象 DDL INCLUDE MAPPED , OBJTYPE 'TABLE' & INCLUDE MAPPED OBJTYPE 'INDEX' DDLOPTIONS ADDTRANDATA RETRYOP RETRYDELAY 10 MAXRETRIES 10 DDLOPTIONS REPORT -- 丢弃文件和报告策略 DISCARDFILE ./dirrpt/extgsxf.dsc,APPEND,MEGABYTES 1000 DISCARDROLLOVER AT 6:00 REPORTROLLOVER AT 6:00 REPORTCOUNT EVERY 1 HOURS,RATE FETCHOPTIONS FETCHPKUPDATECOLS REPORT AT0:01 FETCHOPTIONS MISSINGROW ABEND STATOPTIONS REPORTFETCHWARN -- 长事务监控 LONGTRANS 1H,CHECKINTERVAL 10m -- 动态解析表名 DYNAMICRESOLUTION -- 同步范围:test schema 下所有表 TABLE test.*;配置完参数文件后,在 GGSCI 里执行添加和启动操作:
# 添加 Extract 进程,指定从当前时间点开始抽取 GGSCI (test1) 2> add extract extgsxf tranlog, begin now # 把本地 Trail 文件绑定到该进程 GGSCI (test1) 3> add exttrail ./dirdat/gs, extract extgsxf, megabytes 1024 # 启动抽取进程 GGSCI (test1) 4> start extgsxf逻辑说明:extgsxf进程把捕获的事务写到./dirdat/gs这个 Trail 文件,文件大小上限 1024MB,超过后自动滚动生成新的队列文件。begin now表示从当前日志位置开始抽取,适用于不需要历史数据恢复的场景。
参数说明里值得关注的是GETREPLICATES和GETTRUNCATES。前者确保 Replicat 产生的数据不会被 Extract 再抓一次形成死循环,后者确保 truncate 操作能被捕获。在只做 DML 同步的场景,GETTRUNCATES可以不写,但业务上需要同步 truncate 的话,必须在 Extract 和 Replicat 两端都配置,少一端都不行。
4.4 源端 DataPump 进程:跨网络传输的关键角色
DataPump 进程负责把 Extract 写入的本地 Trail 文件通过网络投递到目标端的 Trail 文件。之所以不在 Extract 里直接配置 RMTHOST,是为了解耦抽取和传输,否则 Extract 进程一旦处理网络延迟就会阻塞日志读取。
GGSCI (test1 as goldengate@test1) 60> edit param dpgskf参数文件内容:
-- DataPump 进程名:dpgskf EXTRACT dpgskf -- PASSTHRU 模式:不做数据转换,与目标端 no DB conversion PASSTHRU -- 动态解析表名 DYNAMICRESOLUTION -- 指定目标系统 MGR 进程地址和端口 RMTHOST 10.0.100.141,MGRPORT 7809 -- 目标端 Trail 文件位置 RMTTRAIL ./dirdat/gs -- 错误处理和报告策略 DISCARDFILE ./dirrpt/dpgskf.dsc,APPEND,MEGABYTES 100 DISCARDROLLOVER AT 6:00 REPORTROLLOVER AT 6:00 REPORTCOUNT EVERY 1 HOURS,RATE -- 投递范围 TABLE test.*;添加和启动 DataPump 进程:
# 添加 DataPump 进程,指定读取源端 Extract 进程写入的 Trail GGSCI (test1 as goldengate@test1) 61> add extract dpgskf, exttrailsource ./dirdat/gs # 指定目标端远程 Trail GGSCI (test1 as goldengate@test1) 62> add RMTTRAIL ./dirdat/gs, extract dpgskf, megabytes 1024 # 启动投递进程 GGSCI (test1 as goldengate@test1) 63> start dpgskf参数说明:RMTHOST后面写目标端服务器的 IP 和 MGR 端口,IP 必须是目标端能被源端访问到的地址;RMTTRAIL指定目标端接收数据的 Trail 文件位置,这个路径是目标端 OGG 安装目录下的相对路径,不需要在数据库里创建什么,但目录必须存在。PASSTHRU表示 DataPump 不做数据格式转换,直接把 Trail 文件原样投递,这个模式性能最好,前提是源端和目标端的平台差异影响不大(字符集由 Extract 阶段的 NLS_LANG 统一处理)。如果源端是 Windows、目标端是 Linux,字符集编码已经由 Extract 进程的SETENV (NLS_LANG)在读取时统一,DataPump 传的是字节流,PASSTHRU 没问题。
到这里有个典型排错点:DataPump 进程启动后,检查它的状态用info dpgskf,你看的时候留意Trail位置那一行的变化,如果 Trail 位置在增长,说明数据正在流动;如果位置纹丝不动,看view report dpgskf检查网络连通性,最常见的错误是目标端防火墙没放行 7809 端口。我那次就是telnet 目标IP 7809不通,查了一圈发现安全组策略挡了,在目标端加白名单后 DataPump 自动就恢复正常了。
4.5 目标端 Replicat 进程:事务落地的最后一环
Replicat 是数据同步链路的终点,目标端的全部配置集中在这个进程上。它读取目标端 Trail 文件并把每条事务应用到目标数据库。
GGSCI (test2 as goldengate@test1) 13> edit param repgs1参数文件内容:
-- Replicat 进程名:repgs1 REPLICAT repgs1 -- 环境变量 SETENV (ORACLE_HOME = "/u01/app/oracle/product/11.2.0/db_1" ) SETENV (ORACLE_SID = "test1") SETENV (NLS_LANG = "AMERICAN_AMERICA.AL32UTF8") -- 复制进程连接目标库 USERID goldengate password goldengate -- 假设源和目标表结构完全一致,不需要读取数据库定义文件 ASSUMETARGETDEFS -- 延迟约束检查,提高大批量写入性能 DBOPTIONS DEFERREFCONST -- 不触发目标端数据库触发器 DBOPTIONS SUPPRESSTRIGGERS -- 错误处理和丢弃文件 DISCARDFILE ./dirrpt/repgs1.dsc, APPEND, MEGABYTES 1000 DISCARDROLLOVER AT 6:00 REPERROR (DEFAULT, ABEND) -- DDL 复制配置 DDL INCLUDE MAPPED , OBJTYPE 'TABLE' & INCLUDE MAPPED OBJTYPE 'INDEX' DDLOPTIONS REPORT -- 报告策略 REPORTROLLOVER AT 6:00 REPORTCOUNT EVERY 30 MINUTES, RATE REPORT AT0:01 STATOPTIONS RESETREPORTSTATS NUMFILES 150 -- 同步 truncate GETTRUNCATES -- 动态解析表名 DYNAMICRESOLUTION -- 允许空更新(UPDATE 中前后镜像一致) ALLOWNOOPUPDATES -- 事务合并,每 1000 个操作提交一次 GROUPTRANSOPS 1000 -- 映射关系:源 schema 到目标 schema MAP test.* , TARGET test.* ;添加 Replicat 进程:
GGSCI (test2 as goldengate@test1) 20> add replicat repgs1, exttrail ./dirdat/gs, checkpointtable goldengate.ggschkpt逻辑说明:add replicat需要指定exttrail参数,告诉 Replicat 读取哪个 Trail 文件;checkpointtable参数明确这个进程用它自己的 checkpoint 表记录消费进度。如果你在 GLOBALS 文件里已经定义了全局 CHECKPOINTTABLE,这里的显式指定可以省略,但显式写出来更安全。
GROUPTRANSOPS 1000是一个值得关注的参数。OGG 默认逐条事务应用,对于高频小事务的业务表,会频繁 commit 导致目标端 redo 生成量过大。设成 1000 表示积累 1000 个操作后由一个事务提交,能显著提升大流量场景的 apply 性能。但这个参数不是越大越好,事务合并会放大单次事务的执行时间,如果有其他系统并发访问目标表,行锁竞争会变激烈。我的经验值在 500-2000 之间,配合目标端数据库的 undo 表空间大小来评估。
4.6 三级进程状态检查命令与常见输出
配置完成后,用info all查看所有进程状态,正常情况源端应该看到 MGR、EXTRACT、DataPump 三个进程都处于 RUNNING,目标端看到 MGR 和 REPLICAT 处于 RUNNING。
GGSCI (test1 as goldengate@test1) 70> info all Program Status Group Lag at Chkpt Time Since Chkpt MANAGER RUNNING EXTRACT RUNNING EXTGSXF 00:00:00 00:00:04 EXTRACT RUNNING DPGSKF 00:00:00 00:00:02 GGSCI (test2 as goldengate@test1) 25> info all Program Status Group Lag at Chkpt Time Since Chkpt MANAGER RUNNING REPLICAT RUNNING REPGS1 00:00:00 00:00:01如果 Extract 启动失败,最常见的提示是权限不足或日志读取位置错误,查看view report extgsxf和 ggserr.log 定位具体报错。Replicat 启动失败,优先确认 checkpoint 表有没有建,检查目标库里select count(*) from goldengate.ggschkpt是否能查到记录。我遇到的一次情况是写了ASSμMETARGETDEFS这个参数但源端和目标端某张表的列顺序不一致,导致 Replicat 报 OGG-01028,解决方式是改成在 Extract 端生成 DEF 文件,或者在 Replicat 里明确SOURCEDEFS指定定义文件。跨平台同步中表结构一致性是一个需要认真确认的依赖项。
5. 跨平台同步避坑:初始化数据、字符集与进程恢复的常见问题
5.1 初始化数据用 expdp + flashback_scn:先快照再开闸
OGG 同步在业务上线前需要做一次基础数据初始化,让目标端的数据快照与源端某个时间点对齐。这个对齐点用 SCN 来标记。常见做法是把 Extract 进程启动时的 SCN 拿到,然后通过 datapump 导出一致性快照,导入目标端,最后 Replicat 从那个 SCN 开始 apply 增量数据。
先查当前数据库 SCN:
SQL> select to_char(current_scn) from v$database; CURRENT_SCN ----------- 1085057用 expdp 导出这张表,指定 flashback_scn 参数保证导出数据的一致性,导出期间表上的 DML 不会影响导出内容:
# 导出源表数据,指定闪回 SCN expdp test/test TABLES=test.t1 DUMPFILE=t1.dmp flashback_scn=1085057把 dump 文件拷贝到目标端后导入:
# 目标端导入 impdp test/test dumpfile=t1.dmp导入完成后,启动 Replicat 并指定从对应 SCN 开始应用:
GGSCI (test2 as goldengate@test1) 20> start replicat repgs1, aftercsn 1085057逻辑说明:aftercsn参数让 Replicat 忽略 Trail 文件中 SCN 小于等于 1085057 的事务,只应用 SCN 大于它的增量数据。这样设计的好处是初始化数据导出的那个时间点恰好是副本一致点,所有在导出开始后发生的新事务都会被 Replicat 后续应用。如果不用 SCN 而用时间,会因为时钟偏差带来精度损失,跨平台环境尤其明显,SCN 是 Oracle 内部全局递增的,不会有两套时钟。
初始化完成后验证目标端数据量是否与源端快照一致,再检查 Replicat 是否有丢弃记录(看 repgs1.dsc 文件)。我见过初始化完成后目标端数据比源端多的情况,原因就是源端在 expdp 导出期间还有业务写入,flushback_scn 没在导出开始时固定,导致导出的数据包含了导出期间的部分新事务,而 Replicat 又从那个 SCN 开始再应用了一遍。
5.2 字符集不一致:乱码数据的元凶
源库是 Windows、目标库是 Linux,字符集不一致是跨平台同步最常见的隐性风险。如果源库字符集是 AL32UTF8,目标库是 ZHS16GBK,源端插入的中文在传输链路中按 UTF-8 编码,目标端按 GBK 解码后就是乱码。
OGG 的字符集处理逻辑是:Extract 在读取 redo 时需要知道源库的字符集,通过SETENV (NLS_LANG)指定;Replicat 在写入目标库时通过它的SETENV (NLS_LANG)控制连接会话的字符集映射。追踪日志和 Trail 文件是 OGG 内部编码,不受数据库字符集影响。
# Extract 和 DataPump 端 SETENV (NLS_LANG="AMERICAN_AMERICA.AL32UTF8") # Replicat 端 SETENV (NLS_LANG="AMERICAN_AMERICA.ZHS16GBK")在配置抽取进程前先在数据库层确认两端字符集,执行:
SQL> select userenv('language') from dual;如果源库和目标库的字符集设置不一致,替换参数值后再启动进程,不要在同步跑起来之后才处理。初始化数据阶段expdp/impdp的字符集转换是一条独立路径,由 Oracle 的NLS_LANG环境变量控制,OGG 的 Trail 文件不参与,这是两类不同的传输机制,容易混在一起排查。
5.3 避坑记录:现象、原因与解决
以下四条避坑记录来自模拟项目 X 的部署过程,每一条都真实耗掉过时间。
避坑 1:Extract 进程启动报 OGG-01161 错误,提示日志中不存在指定 SCN现象:源数据库刚开完归档模式,启动 Extract 进程时报找不到要读取的日志位置。原因:切换归档模式后,oracle 的 current log 的 sequence 变了,但 Extract 进程参数里begin now指定的起点与实际日志序列不匹配,日志中找不到对应 SCN。解决:在源库执行alter system switch logfile,确保日志切换完成后再启动 Extract,同时确认info extgsxf显示的日志位置与v$log当前日志序列一致。
避坑 2:数据同步过程中目标端中文乱码现象:目标端查询同步过来的中文数据显示为乱码。原因:源库是 AL32UTF8,目标库是 ZHS16GBK,Replicat 端 SETENV NLS_LANG 没配或配错。解决:在 Extract 和 Replicat 两端都明确设置与源库一致的 NLS_LANG,并在 Replicat 端根据目标库字符集调整。这个问题的隐蔽之处在于初始化数据阶段可能不乱码,因为 expdp 导出的 dump 文件自带字符集信息,但 OGG 的 Trail 文件走的是另一条通道,漏配 NLS_LANG 就翻车。
避坑 3:MGR 重启后 checkpoint 表丢失现象:MGR 进程重启后,start replicat 报 checkpoint table 不存在。原因:GLOBALS 文件里配置的 CHECKPOINTTABLE 用户写错了,或者create subdirs在执行时没有生成对应版本的 GLOBALS 文件。解决:检查 GLOBALS 文件内容,确认 GGSCHEMA 和 CHECKPOINTTABLE 写法正确后重启 MGR。注意配置 GLOBALS 后必须重启 MGR 才能生效,这是一条很容易跳过的时间成本。
避坑 4:Replicat 报 OGG-01028 无法识别列现象:Replicat 启动后立刻 abend,错误信息是 replay row failed,提示某列无法识别。原因:源端表结构在 OGG 部署后发生过 ALTER TABLE ADD COLUMN,但 DDL 同步没生效,目标端表结构没有跟着变。解决:在 Extract 参数里配置DDLOPTIONS ADDTRANDATA,同时目标端 Replicat 的参数要配DDL INCLUDE MAPPED确保 DDL 能被复制过来。这类问题的排查思路是先对比源和目标端表结构,执行desc test.t1看列数是否一致,再做 DDL 捕获配置修复。
6. 用 OGG 自带命令验证同步链路:info 与 stats 的组合诊断习惯
OGG 提供了一套命令行诊断工具,用好info和stats基本上能覆盖 90% 的同步问题定位。我先说结论:每次配置完 OGG,不要急着插入测试数据,先用info all确认进程状态,然后用stats <进程名>确认进程间数据流是通的,最后才做 DML 验证。
stats命令的输出会显示进程处理过的操作数,这是判断数据是否有实际流转的最直接证据。比如 Extract 端stats extgsxf会显示Total operations,DataPump 端stats dpgskf会显示它投递过的 Trail 文件字节数,Replicat 端stats repgs1会显示 apply 了多少条记录。如果 Extract 有数据但 DataPump 没有,问题在网络层或 RMTHOST 配置;如果 DataPump 有数据但 Replicat 没有,问题在目标端 Trail 文件路径或 checkpoint 位置。
# 查看 Extract 进程统计 GGSCI> stats extgsxf # 查看 DataPump 进程统计 GGSCI> stats dpgskf # 查看 Replicat 进程统计 GGSCI> stats repgs1实际验证时,我习惯用一个三连操作:源端执行一条 update、commit,然后依次在三个进程上看 stats 输出。具体步骤是源端执行update test.t1 set object_name='ogg_test' where object_id=87366; commit;。然后看发现 Extract 的 stats 里 DML 计数加 1,DataPump 的 stats 里的 trail 文件大小增长,Replicat 的 stats 里 show 的 insert/update 计数加 1。三处计数都动过,说明链路通畅;哪一处不动,就从那一环开始查。
窗口期这个指标也值得习惯性关注,info输出里 Lag at Chkpt 字段是同步延迟,如果这个值持续增长到分钟级别,说明 Replicat apply 跟不上 Extract 抽取的速度。通常的原因有两个:目标库 undo 表空间不足导致长事务回滚,或者 GROUPTRANSOPS 设置过大导致单事务执行时间过长。我遇到过一次 Lag 持续增长,原因是目标库表上有个性能很差的触发器,每次 apply 都被触发执行几十毫秒,累积起来就把 Replicat 拖垮了,后来和业务确认这个触发器可以禁用,停用后 Lag 恢复正常。
从那以后,我每次部署 OGG 都强制走一遍同一个验证流程:先拉通进程状态确认全部 RUNNING,然后对每条链路做 insert、update、delete、truncate 四类 DML 验证,每类操作都看一眼三个进程的 stats 和 Lag 指标。这套流程做完,基本可以确定同步链路经受住了跨平台的折腾。希望帮到你。
本文还有配套的精品资源,点击获取