ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Windows到Linux的OGG 12.2.0.2部署与同步避坑

Windows到Linux的OGG 12.2.0.2部署与同步避坑

简介:面向 Oracle DBA 与数据同步实施人员的技术文档,聚焦 Oracle GoldenGate 12.2 在 Windows 源库与 Linux 目标库之间的跨平台实时同步部署。内容覆盖源库归档模式、强制日志与附加日志开启,goldengate 专用用户及 dbms_goldengate_auth 授权,目标库额外 DML 权限配置,以及 ggsci 创建子目录、GLOBALS 与 checkpoint 表设定、Manager/Extract/Replicat 进程配置和后续监控排错思路,属于可直接照做的中高级实操参考。资源包共 1 个 PDF 文件,约 496KB,篇幅精炼、步骤与命令对照排列,便于在实施现场快速查阅。目前已有 297 人学习。读者可据此理清异构环境 OGG 的前置条件清单,掌握账号权限与参数配置的完整链路,并借助日志查看与参数调整方法定位同步异常,减少试错成本。

1. 从 Windows 到 Linux 的 OGG 12.2.0.2 部署,先别急着解压

Oracle OGG 12.2.0.2 从 Windows 同步到 Linux 的安装部署,听起来只是 Linux 端装好、Windows 端抽取进程指过去,实际做 oracle linux OGG 数据同步时,最先卡住的往往不是安装包,而是源库归档、附加日志和字符集。某次迁移,源库在 Windows 上跑着老业务,目标库在 Linux 上等着接流量,中间只留一个维护窗口。有人上来就解压122022_fbo_ggs_Linux_x64_shiphome.zip,跑完runInstaller才发现 Extract 起不来,回头再开归档、加附加日志、切日志,窗口已经过去一半。这套环境适合正在做异构库同步的开发者,也适合第一次接触 OGG 12.2.0.2 的运维;装不好不会只是进程红一下,复制延迟、重复应用、初始化 SCN 对不上,后面都要花时间补。

2. 安装 OGG 12.2.0.2:Linux 端 runInstaller 与 Windows 端介质选择

2.1 Linux 端上传与解压:oracle 用户和目录权限

Linux 目标端我一般先把安装包传到/u01/software,不要直接丢在/root下解压再用 root 跑安装。OGG 后面要用 oracle 用户启动 MGR、Extract、Replicat,目录属主不对,进程能起来但写 trail、写 report 会翻车。先用 oracle 用户登录,确认/u01空间够,再看一眼 ulimit 和/tmp权限。

# 切到 oracle 用户,避免安装出来的目录属主是 root su - oracle # 建一个独立软件目录,安装包和安装后的 OGG 目录分开 mkdir -p /u01/software/ogg122 cd /u01/software/ogg122 # -q 静默解压,-d 指定解压目标目录 unzip -q 122022_fbo_ggs_Linux_x64_shiphome.zip -d /u01/software/ogg122 # 确认 Disk1 和 runInstaller 存在 ls -l /u01/software/ogg122/fbo_ggs_Linux_x64_shiphome/Disk1

su - oracle是为了带上 oracle 用户的环境变量,不是只切用户;mkdir -p避免目录已存在时报错;unzip -q不刷屏,-d把解压内容固定到一个可回收的目录。安装包解压后目录名是fbo_ggs_Linux_x64_shiphome,下面有Disk1,runInstaller就在Disk1里。这里不要用 root 解压后再chown -R救火,后面安装程序写入 inventory 和 OGG 目录时容易混权限。

提示:/u01/software只放安装介质,OGG 实际安装目录我习惯单独放/u01/app/ogg,升级和回滚时好区分。

2.2 可视化安装 runInstaller:数据库版本选择与安装路径

进入Disk1后执行./runInstaller。如果当前 shell 没有图形环境,runInstaller会直接退出或者报 DISPLAY 相关错误,这不是安装包坏了,是缺少可视化条件。常见做法是在有图形界面的终端里执行,或者用支持 X11 转发的终端登录;不要在无图形环境里硬跑静默参数,除非你手上有对应响应文件。

cd /u01/software/ogg122/fbo_ggs_Linux_x64_shiphome/Disk1 ./runInstaller

安装界面里最关键的一步是选对数据库版本。OGG 12.2.0.2 的安装器会让你选择对应的 Oracle Database 版本,源库是 11.2.0.x 就选 11g 对应项,目标库是 12.2.0.1 就选 12c 对应项,不要随手选成 GoldenGate for Big Data,那是另一套产品线。安装路径填/u01/app/ogg,不要带空格,不要放在/home/oracle下面,后面参数文件里的./dirdat、./dirrpt都相对这个目录走。

安装完成后用 oracle 用户进ggsci看版本,能进命令行就说明基础安装没问题:

cd /u01/app/ogg ./ggsci # 进入后看版本信息,退出用 exit GGSCI (test1) 1> info all GGSCI (test1) 2> exit

info all在还没配进程时看不到东西是正常的,这里只验证ggsci能启动、能读当前目录。版本号应该能看到Version 12.2.0.2.2这一类信息。如果ggsci报共享库找不到,先查LD_LIBRARY_PATH和ORACLE_HOME,不要急着重装。

平台和介质可以先对照下表,别把 Windows 包传到 Linux 上解压:

角色平台安装介质安装方式装完先查
源端WindowsOGG 12.2.0.2 Windows 版安装包解压或运行 Windows 安装程序ggsci.exe能否启动
目标端Linux122022_fbo_ggs_Linux_x64_shiphome.ziprunInstaller可视化安装ggsci版本和安装路径
源库Windows Oracle不需要装 OGG 介质开归档、附加日志、建 goldengate 用户v$database附加日志状态
目标库Linux Oracle不需要装 OGG 介质建 goldengate 用户、开复制参数enable_goldengate_replication

2.3 Windows 源端安装包的落地位置与字符集检查

源端是 Windows 时,OGG 12.2.0.2 要用 Windows 对应介质,不要拿 Linux 的fbo_ggs_Linux_x64_shiphome去 Windows 上解压。安装目录我一般放D:\ogg,不要放C:\Program Files\ogg,路径里有空格,后面参数文件里的DISCARDFILE、RMTTRAIL写起来容易多引号,排错时也难看。解压或安装后,用管理员身份打开命令行,进目录执行ggsci.exe。

REM 进入 Windows 端 OGG 目录 D: cd D:\ogg REM 启动 GGSCI,确认 Windows 端介质可用 ggsci.exe REM 在同一个命令行窗口里设置会话级环境变量,便于测试 set ORACLE_HOME=D:\app\oracle\product\11.2.0\dbhome_1 set ORACLE_SID=orcl set NLS_LANG=AMERICAN_AMERICA.AL32UTF8

set只对当前命令行窗口生效,手工测试够用;如果后面要把 MGR 注册成 Windows 服务,环境变量要写到系统变量里,或者确认服务账户能读到ORACLE_HOME。NLS_LANG不要凭感觉写AMERICAN_AMERICA.UTF8,先查数据库真实字符集:

-- 在源库和目标库都执行,确认字符集和语言环境 select userenv('language') from dual; select value from nls_database_parameters where parameter = 'NLS_CHARACTERSET';

userenv('language')返回的是会话语言环境,常见结果是AMERICAN_AMERICA.AL32UTF8;NLS_CHARACTERSET查的是数据库字符集。两边不一致时,先在 OGG 参数文件的SETENV (NLS_LANG=...)里对齐,不要等 Replicat 报字段截断再回头改。Windows 源端的ORACLE_HOME、ORACLE_SID要和实际数据库实例一致,ORACLE_SID写错时dblogin会直接失败,这个错比进程起来后报错好查。

3. 源库与目标库配置:归档、附加日志和 goldengate 用户

3.1 源库四件事:归档、强制日志、附加日志、enable_goldengate_replication

源库配置是整套 OGG 12.2.0.2 的地基。归档没开,Extract 读不到在线日志切换后的内容;强制日志没开,某些操作可能不走 redo;附加日志没开,Extract 缺少定位行所需的补充信息;enable_goldengate_replication没开,OGG 管理员权限和复制功能会受限。下面这组 SQL 按顺序在源库执行,路径和 SID 按实际环境替换。

-- 1. 开归档:先 mount,再开归档,最后 open startup mount; alter database archivelog; alter database open; -- 2. 强制记录日志,保证关键操作进 redo alter database force logging; -- 3. 开最小附加日志 alter database add supplemental log data; -- 4. 查看结果,SUPPLEME 和 FOR 都应为 YES select SUPPLEMENTAL_LOG_DATA_MIN, FORCE_LOGGING from v$database; -- 5. 切一次日志,让附加日志生效 alter system switch logfile;

startup mount是开归档必须经过的状态,数据库已经 open 时不能直接alter database archivelog;force logging是库级强制记录,不是只对某张表生效;add supplemental log data开的是最小附加日志,后面还要对同步表加表级或用户级附加日志。查v$database时,SUPPLEMENTAL_LOG_DATA_MIN为YES、FORCE_LOGGING为YES才算过。切日志这一步别省,附加日志开关后不切日志,Extract 可能还在读旧日志,表现为“配置都对但就是没数据”。

3.2 goldengate 用户与权限:源端和目标端的差异

源库和目标库都要建goldengate用户,但授权不完全一样。源库侧重读日志、读表、执行 OGG 管理包;目标库侧重对同步表做 DML。表空间路径不要照抄/u01/app/oracle/oradata/test1/ogg01.dbf,换成目标库实际数据文件目录,大小先给 300M 自动扩展,后面按 checkpoint 表和日志增长再调。

-- 源库:建表空间和 OGG 用户 create tablespace goldengate datafile '/u01/app/oracle/oradata/test1/ogg01.dbf' size 300m autoextend on; create user goldengate identified by goldengate default tablespace goldengate; grant connect, resource, create session, alter session to goldengate; grant flashback any table to goldengate; -- 授予 OGG 管理员所需权限 exec dbms_goldengate_auth.grant_admin_privilege('GOLDENGATE'); -- 开库级 OGG 复制参数 alter system set enable_goldengate_replication = true scope=both;

grant_admin_privilege('GOLDENGATE')是 OGG 管理员权限的关键,少了它dblogin可能成功,但后续注册 Extract、读日志会缺权限。flashback any table是当日志里信息不够时,OGG 可以回查表或做闪回查询,不是让业务随便闪回。scope=both让参数立即生效并写进 spfile,重启后不用再补。源库还要给utl_file执行权限,后面 DDL 同步脚本会用到。

目标库建用户和表空间的语句基本一致,但不用开附加日志,额外给 DML 权限:

-- 目标库:建用户和表空间,语句与源库类似 create tablespace goldengate datafile '/u01/app/oracle/oradata/test1/ogg01.dbf' size 300m autoextend on; create user goldengate identified by goldengate default tablespace goldengate; grant connect, resource, create session, alter session to goldengate; grant flashback any table to goldengate; exec dbms_goldengate_auth.grant_admin_privilege('GOLDENGATE'); -- 目标端 Replicat 需要写同步表 grant insert any table, update any table, delete any table to goldengate; alter system set enable_goldengate_replication = true scope=both;

目标库的insert/update/delete any table是 Replicat 应用增量数据用的,不给就会在REPERROR里看到权限不足。注意目标库不要因为“怕漏”就把源库的附加日志也开一遍,目标库不是抽取端,开了不参与复制,反而增加日志量。

3.3 目标库只做复制端该做的事:别把附加日志开反

源库和目标库的配置最容易反的一点,是把附加日志开到目标库、源库却没开。判断方法很简单:Extract 跑在哪边,哪边就要有归档和附加日志;Replicat 跑在哪边,哪边就要有 DML 权限和 checkpoint 表。Windows 源端要确认归档路径有空间,Linux 目标端要确认goldengate用户能建表、能写表。

源端还要做 DDL 同步准备时,按安装目录执行脚本。下面这些脚本在/u01/app/ogg下,执行时当前用户要有 DBA 权限,ddl_pin要指定 OGG 管理员 schema。

-- 源端:给 goldengate 用户执行 utl_file 的权限 conn / as sysdba grant execute on utl_file to goldengate; -- 进入 OGG 安装目录后执行 DDL 同步准备脚本 @/u01/app/ogg/marker_setup @/u01/app/ogg/ddl_setup @/u01/app/ogg/role_setup grant GGS_GGSUSER_ROLE to goldengate; -- 开 DDL 同步 @/u01/app/ogg/ddl_enable -- 把 OGG 相关对象 pin 住,减少 DDL 复制性能问题 @?/rdbms/admin/dbmspool.sql @/u01/app/ogg/ddl_pin goldengate

marker_setup、ddl_setup、role_setup是 DDL 同步的三件套,执行顺序不要颠倒;grant GGS_GGSUSER_ROLE to goldengate把角色给到 OGG 用户;ddl_enable打开 DDL 捕获;ddl_pin需要传 OGG 管理员 schema 名,这里就是goldengate。这些脚本执行时如果报“对象已存在”,先查是不是之前装过一遍,不要直接 drop 掉重来,尤其是 marker 表。

表级附加日志在 GGSCI 里加,只对需要同步的表做,不要全库扫:

# 登录数据库 GGSCI (test1) 1> dblogin userid goldengate password goldengate # 对同步表加 trandata,表上要有主键或唯一索引 GGSCI (test1 as goldengate@test1) 2> add trandata test.t1 # 查看表级附加日志状态 GGSCI (test1 as goldengate@test1) 3> info trandata test.t1

add trandata test.t1要求表上有主键或唯一索引;没有主键的表要指定列作为主键,否则 Replicat 应用更新时可能重复。info trandata能看到Logging of supplemental redo data enabled才算加成功。这里只对test.t1做示例,实际同步哪些表就加哪些表,不要图省事add trandata *。

4. OGG 进程配置:MGR、Extract、DataPump、Replicat 的落地顺序

4.1 初始化目录与 GLOBALS:checkpoint 表先落地

安装完先不要急着配 Extract,进ggsci执行create subdirs,把dirprm、dirrpt、dirchk、dirdat这些目录建出来。源端和目标端都要做,目录不存在时edit params会失败,add exttrail也没地方写。

cd /u01/app/ogg ./ggsci # 建 OGG 子目录,源端和目标端都执行 GGSCI (test1) 1> create subdirs

create subdirs会在当前 OGG 目录下建参数、报告、检查点、trail 等目录。执行后看到Parameter files ... already exists不一定是错,说明之前建过;只要dirdat、dirrpt、dirchk都在就行。

接着配全局参数文件GLOBALS,源端和目标端都要配,且GGSCHEMA、CHECKPOINTTABLE要和实际用户一致:

-- ./GLOBALS GGSCHEMA goldengate CHECKPOINTTABLE goldengate.ggschkpt SYSLOG NONE

GGSCHEMA指定 OGG 管理员 schema;CHECKPOINTTABLE指定检查点表;SYSLOG NONE表示不往系统日志写,排错时主要看ggserr.log和进程报告。改完GLOBALS后重新进ggsci,再dblogin和add CHECKPOINTTABLE,顺序不要反。

# 源端和目标端都要登录数据库 GGSCI (test1) 4> dblogin userid goldengate password goldengate # 在 goldengate 用户下建 checkpoint 表 GGSCI (test1 as goldengate@test1) 5> add CHECKPOINTTABLE goldengate.ggschkpt

dblogin成功会提示Successfully logged into database;add CHECKPOINTTABLE成功会提示Successfully created checkpoint table。checkpoint 表建在哪个用户下,后面 Replicat 的checkpointtable就要写同一个,不能源端写goldengate.ggschkpt、目标端写别的 schema,否则重启后找不到检查点,重复应用就来了。

4.2 MGR 参数:端口、动态端口、自动重启和清理

MGR 是 OGG 的管理进程,源端和目标端都要起。目标端 MGR 还要接收源端 DataPump 投递过来的 trail,所以PORT和DYNAMICPORTLIST要规划好,防火墙只放必要端口。

-- ./dirprm/mgr.prm 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 主端口;DYNAMICPORTLIST 7800-7810给 DataPump 动态分配端口,范围不要和业务端口撞;AUTORESTART ER *,RETRIES 3, WAITMINUTES 5, RESETMINUTES 60表示进程异常后重试 3 次,每次等 5 分钟,60 分钟后重置重试计数;PURGEOLDEXTRACTS清理已应用的旧 trail,MINKEEPHOURS 12至少保留 12 小时,给排错留后悔药。PURGEDDLHISTORY和PURGEMARKERHISTORY控制 DDL 历史表清理,保留 7 到 14 天比较稳。

# 源端和目标端都启动 MGR GGSCI (test1 as goldengate@test1) 6> start mgr # 查看 MGR 状态 GGSCI (test1 as goldengate@test1) 7> info mgr

start mgr后看到Manager started才算起来;info mgr能看到端口和进程状态。如果 MGR 起不来,先看ggserr.log里是不是端口被占,或者USERID密码错。

4.3 源端 Extract 与 DataPump:从本地 trail 到远端 trail

源端 Extract 负责从 redo 或归档里抽数据,写到本地 trail;DataPump 负责把本地 trail 投递到目标端。先配 Extract,参数文件里的SETENV要跟源端平台一致。下面是 Linux 源端示例;如果源端是 Windows,ORACLE_HOME、ORACLE_SID和路径要换成 Windows 实际值,EXTTRAIL也换成D:\ogg\dirdat\gs这类路径。

-- ./dirprm/extgsxf.prm EXTRACT extgsxf 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 EXTTRAIL ./dirdat/gs TRANLOGOPTIONS LOGRETENTION DISABLED BR ,BRINTERVAL 20M TRANLOGOPTIONS BUFSIZE 2048000 GETREPLICATES CACHEMGR CACHESIZE 2GB GETTRUNCATES 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 AT 0:01 FETCHOPTIONS MISSINGROW ABEND STATOPTIONS REPORT FETCHWARN LONGTRANS 1H,CHECKINTERVAL 10m DYNAMICRESOLUTION TABLE test.t1;

EXTRACT extgsxf是进程名,后面add extract要一致;三个SETENV分别指定 Oracle Home、实例名和字符集,Windows 源端要改路径;EXTTRAIL ./dirdat/gs是本地 trail 前缀;TRANLOGOPTIONS LOGRETENTION DISABLED表示不让 Extract 去管日志保留,日志保留交给数据库备份策略;BR ,BRINTERVAL 20M是 Bounded Recovery 参数,长事务多的时候有用;CACHEMGR CACHESIZE 2GB给缓存,内存小的机器要往下调;GETTRUNCATES让 truncate 也能同步;DDL INCLUDE MAPPED只同步有映射的 DDL;DISCARDFILE和DISCARDROLLOVER保证丢弃记录有文件可查;LONGTRANS控制长事务检查;TABLE test.t1;是同步表,实际按业务替换。

添加 Extract 和本地 trail:

# 添加抽取进程,从当前时间开始 GGSCI (test1) 8> add extract extgsxf tranlog, begin now # 绑定本地 trail,每个文件 1024M GGSCI (test1) 9> add exttrail ./dirdat/gs, extract extgsxf, megabytes 1024 # 启动抽取 GGSCI (test1) 10> start extgsxf

tranlog, begin now表示从当前时间点开始抽;add exttrail的megabytes 1024是单个 trail 文件大小,不要设太小,否则切换频繁;start extgsxf后看info extgsxf,状态应是Running。

DataPump 参数:

-- ./dirprm/dpgskf.prm EXTRACT dpgskf PASSTHRU DYNAMICRESOLUTION RMTHOST 192.0.2.10, MGRPORT 7809 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.t1;

PASSTHRU表示不做额外过滤,直接把 Extract 写出的 trail 投递过去;RMTHOST是目标端 IP,MGRPORT 7809要和目标端 MGR 端口一致;RMTTRAIL ./dirdat/gs是目标端 trail 前缀,目标端 Replicat 要读同一个。TABLE test.t1;要和 Extract 的同步表匹配,否则投递过去也没人读。

# 添加 DataPump,指定读取本地哪个 trail GGSCI (test1) 11> add extract dpgskf, exttrailsource ./dirdat/gs # 指定投递到目标端的 trail 和文件大小 GGSCI (test1) 12> add RMTTRAIL ./dirdat/gs, extract dpgskf, megabytes 1024 # 启动投递 GGSCI (test1) 13> start dpgskf

exttrailsource指向本地 trail,RMTTRAIL指向目标端路径,两个不要写成同一个物理路径;megabytes 1024和 Extract 的 trail 大小保持一致。

4.4 目标端 Replicat:ASSUMETARGETDEFS 和 MAP 的写法

目标端 Replicat 读远端 trail,把数据应用到目标库。源端和目标端表结构一致时用ASSUMETARGETDEFS,省掉源端定义文件;不一致时要用SOURCEDEFS,那是另一套流程。下面参数文件在 Linux 目标端执行。

-- ./dirprm/repgs1.prm 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 INCLUDE MAPPED , OBJTYPE 'TABLE' & INCLUDE MAPPED OBJTYPE 'INDEX' DDLOPTIONS REPORT REPORTROLLOVER AT 6:00 REPORTCOUNT EVERY 30 MINUTES, RATE REPORT AT 0:01 STATOPTIONS RESETREPORTSTATS NUMFILES 150 GETTRUNCATES DYNAMICRESOLUTION ALLOWNOOPUPDATES GROUPTRANSOPS 1000 MAP test.t1, TARGET test.t1;

ASSUMETARGETDEFS表示假定目标端表定义和源端一致;DBOPTIONS DEFERREFCONST延迟引用约束检查;SUPPRESSTRIGGERS避免触发器在复制时二次触发;REPERROR (DEFAULT, ABEND)让默认错误直接中止,避免错数据继续写;GROUPTRANSOPS 1000把 1000 个事务合成一组应用,提高吞吐;ALLOWNOOPUPDATES允许更新操作没有实际字段变化时报成功;MAP test.t1, TARGET test.t1;是映射,实际按业务表改。

# 添加 Replicat,指定读取的 trail 和 checkpoint 表 GGSCI (test2 as goldengate@test1) 14> add replicat repgs1, exttrail ./dirdat/gs, checkpointtable goldengate.ggschkpt # 启动 Replicat GGSCI (test2 as goldengate@test1) 15> start replicat repgs1

checkpointtable必须和GLOBALS里写的一致;start replicat后看info repgs1,状态Running且Checkpoint Lag不持续增长才算正常。目标端 MGR 要先起来,否则 Replicat 可能读不到 trail。

5. 避坑与排查:Windows 到 Linux 同步最容易翻车的五处

5.1 附加日志没生效,Extract 起不来

现象:start extgsxf后进程刚起就 ABEND,ggserr.log里提示缺少补充日志或无法定位行;info trandata test.t1显示没有启用。

原因:源库只执行了add supplemental log data,但没有对表加add trandata,或者加完没有切日志。最小附加日志不等于表级附加日志,Extract 要定位更新前的行,还需要表级补充信息。Windows 源端如果归档没开,Extract 读不到切换后的日志,也会表现成起不来。

解决:先查库级和表级状态,再切日志。下面两条在源库和 GGSCI 里分别执行:

-- 源库确认库级附加日志 select SUPPLEMENTAL_LOG_DATA_MIN, FORCE_LOGGING from v$database; -- 切日志让配置生效 alter system switch logfile;
# GGSCI 里重新加表级附加日志并查看 GGSCI (test1) 1> dblogin userid goldengate password goldengate GGSCI (test1 as goldengate@test1) 2> add trandata test.t1 GGSCI (test1 as goldengate@test1) 3> info trandata test.t1

如果表没有主键,add trandata会提示需要指定列,这时不要跳过,按业务唯一键补add trandata test.t1, COLS(...)。加完再start extgsxf,看ggserr.log是否还报补充日志错误。

5.2 大小写和字符集不一致,表找不到

现象:Extract 能起,但 Replicat 报No such table或Table not found;或者表名在源端是小写,目标端建成了大写;字段里有中文,复制后出现乱码或截断。

原因:Windows 上 Oracle 默认大小写行为和 Linux 不一定一样,建表时加了双引号的小写表名在目标端要用同样引号;NLS_LANG和数据库字符集不一致时,OGG 按会话字符集解释数据,字段长度算错就会截断。参数文件里SETENV (NLS_LANG=...)写错一个字符,报错能查半天。

解决:源端和目标端都查字符集,表名统一用实际大小写。下面 SQL 两边都跑:

-- 查数据库字符集和当前会话语言环境 select value from nls_database_parameters where parameter = 'NLS_CHARACTERSET'; select userenv('language') from dual; -- 查表实际名称,注意引号和大小写 select owner, table_name from dba_tables where table_name like '%T1%';

如果表名是小写,MAP里要写成MAP "test"."t1", TARGET "test"."t1";,不要凭感觉写TEST.T1。字符集不一致时,先在参数文件SETENV里对齐,再重启 Extract 和 Replicat;不要只改目标端,源端 Extract 的NLS_LANG也要一致。

5.3 目标端权限不够,Replicat 报错

现象:Replicat 启动后应用几条就 ABEND,dirrpt/repgs1.dsc里提示ORA-01031: insufficient privileges或对某张表没有 INSERT/UPDATE/DELETE 权限。

原因:目标库只建了goldengate用户,给了connect、resource,但没给insert any table, update any table, delete any table;或者表在别的 schema 下,goldengate没有该 schema 的 DML 权限。源端权限够不代表目标端够,两边角色不同。

解决:目标库补 DML 权限,并确认enable_goldengate_replication已开:

-- 目标库补权限 grant insert any table, update any table, delete any table to goldengate; -- 确认 OGG 复制参数已开 show parameter enable_goldengate_replication;

如果不想给any table,也可以按表授予insert/update/delete,但同步表多的时候维护成本高。补完权限后start replicat repgs1,再看 discard 文件是否还报权限错。

5.4 checkpoint 表建错用户,重启后重复应用

现象:Replicat 第一次跑正常,重启后从很早的 SCN 开始重放,目标端出现重复数据;或者add replicat时提示 checkpoint 表不存在。

原因:GLOBALS里写的CHECKPOINTTABLE goldengate.ggschkpt和add replicat时指定的checkpointtable不一致,或者 checkpoint 表建在了别的用户下。还有一种情况是dblogin用了别的用户,add CHECKPOINTTABLE建到了错误 schema。

解决:统一GLOBALS、add replicat和实际表三者。下面命令查 checkpoint 表和进程配置:

# 查 Replicat 使用的 checkpoint 表 GGSCI (test2) 1> info replicat repgs1 # 重新登录正确用户,确认 checkpoint 表存在 GGSCI (test2) 2> dblogin userid goldengate password goldengate GGSCI (test2 as goldengate@test1) 3> info checkpointtable goldengate.ggschkpt

如果已经重复应用,不要直接删 checkpoint 表重来,先停 Replicat,确认重复数据的范围,用主键或业务唯一键清理后再从正确 SCN 启动。checkpoint 表是 OGG 的后悔药,建错用户等于把药丢了。

5.5 日志只看 ggserr.log 不够,还要看 discard 文件

现象:ggserr.log里只有一句Aborted,看不出哪张表、哪条记录出错;或者 Extract 正常、Replicat 延迟一直涨。

原因:ggserr.log记录进程级事件,具体丢弃记录在dirrpt下的.dsc文件,参数文件里DISCARDFILE配了才会写。只看主日志,等于只看黑匣子外壳,没看里面的记录。

解决:先看ggserr.log定位进程,再进dirrpt看对应 discard 文件。下面命令按时间找最近报告:

# 看 OGG 主日志尾部 tail -n 200 /u01/app/ogg/ggserr.log # 看 Replicat 报告和丢弃记录 ls -lt /u01/app/ogg/dirrpt/repgs1* tail -n 200 /u01/app/ogg/dirrpt/repgs1.dsc

DISCARDFILE ./dirrpt/repgs1.dsc, APPEND, MEGABYTES 1000里APPEND是追加写,MEGABYTES 1000控制单文件大小;DISCARDROLLOVER AT 6:00每天 6 点切文件。排错时先看.dsc里有没有具体表名和 SQL,再看REPERROR配置是不是ABEND。如果 discard 文件没生成,回头查参数文件路径是不是相对 OGG 安装目录写错。

6. 装完怎么验证跑通:初始化、增量与 truncate 的三步验收

6.1 用 SCN 对齐初始化:expdp/impdp 与 aftercsn

初始化数据不要凭感觉“先导过去再说”。先查源库当前 SCN,用flashback_scn导出,目标端导入后用同一个 SCN 启动 Replicat,这样初始化和增量能接上。

-- 源库查当前 SCN select to_char(current_scn) from v$database;
# 源库导出,flashback_scn 换成上一步查到的值 expdp test/test TABLES=test.t1 DUMPFILE=t1.dmp flashback_scn=1085057 # 目标库导入 impdp test/test dumpfile=t1.dmp

导出时TABLES=test.t1指定表,flashback_scn保证导出的数据对应一个一致点;导入完成后在目标端启动 Replicat 时带aftercsn:

GGSCI (test2 as goldengate@test1) 1> start replicat repgs1, aftercsn 1085057

aftercsn要和导出用的 SCN 一致,写错会漏数据或重复应用。初始化完成后先看info replicat repgs1的 lag 是否回落到 0。

6.2 增量验证:insert/delete/truncate 的目标端回查

增量验证至少做三类:插入、删除、truncate。源端执行后到目标端查结果,不要只看 OGG 进程状态。

-- 源端插入一条 insert into t1 (object_id) values (87366); commit; -- 目标端查最大值,应该能看到 87366 select max(object_id) from test.t1; -- 源端删除并提交 delete from t1 where object_id = 87366; commit; -- 目标端再查,应该回到 87365 select max(object_id) from test.t1; -- 源端 truncate truncate table t1; -- 目标端查数量,应该为 0 select count(*) from test.t1;

插入看目标端有没有新值,删除看目标端有没有跟着少,truncate 看目标端表是不是也清空。三步都过,说明 Extract、DataPump、Replicat 链路和GETTRUNCATES都生效。

6.3 每天收工前必看的三条命令

收工前我固定看三条:进程状态、checkpoint lag、最近错误。进程 Running 不代表数据在动,lag 持续涨说明投递或应用堵了。

# 看所有进程状态和 lag GGSCI (test1) 1> info all # 看 Replicat 详细状态 GGSCI (test2) 2> info replicat repgs1 # 看最近错误 tail -n 100 /u01/app/ogg/ggserr.log

info all里Status是Running、Checkpoint Lag不持续增长,才算链路健康;info replicat repgs1能看到当前读到的 trail 和最后应用的 SCN;ggserr.log里没有新的ERROR或ABEND再收工。这次用到的 OGG 12.2.0.2 Linux 安装包、Windows 端介质说明、参数文件模板和检查 SQL,我整理在资源包里,替换 IP、SID、表空间路径就能按顺序复现。从那以后我每次做完 OGG 部署,都会先把初始化 SCN、增量三类操作和info all走一遍再交付,不再只看进程绿不绿。希望帮到你。

本文还有配套的精品资源,点击获取

返回列表