3.5 OGG的迁移升级案例

Oracle GoldenGate(OGG)是用于迁移、实时复制和数据集成项目的优秀工具。该软件虽然是Oracle核心的战略复制解决方案,但并不局限于Oracle数据库,而是支持各种主流平台。正因为OGG的实时复制技术,很多产商都会选择将其作为生产的容灾解决方案。但笔者个人对此并不赞同,而是更加倾向于将OGG作为数据集成或临时性的数据迁移解决方案。下面就来讲解一个基于OGG进行数据库迁移的案例。

在此迁移案例中,一套Oracle RAC数据库需要从AIX小型机上迁移到X86服务器上,数据库版本从10.2.0.5升级到11.2.0.4,且停机时间只有1个小时。为了满足这样的异构迁移,且停机时间较短的需求,我们最终选择通过OGG来做数据迁移。

使用OGG迁移数据,主要会涉及以下四个步骤。

1)环境准备(业务可正常运行)。

2)搭建OGG,同步数据(业务可正常运行)。

3)前期数据比对任务配置及初次比对(业务可正常运行)。

4)正式迁移(需要停止业务)。

3.5.1 源端环境准备

参考3.4.2节的数据信息统计脚本,统计需要同步的对象,以及搭建目标库Oracle所需要的信息,比如,字符集、表空间等。同时收集源端用户权限等以便OGG同步搭建完成后与目标端的权限进行比对。在此基础上还需要打开源端数据库附加日志、强制日志(force log)等才能配置OGG,具体实现步骤如下。

1.启用数据库的补充日志

配置OGG进行数据同步时,用户需要在源数据库上启用数据库级别的补充日志(Supplemental Log),以确保Oracle在OGG所需的重做日志(redo log)中添加额外信息。

首先,用户通过下列SQLPLUS命令验证是否已经启用了Oracle数据库的补充日志记录:


SQL> SELECT SUPPLEMENTAL_LOG_DATA_MIN FROM V$DATABASE;

对于Oracle 9i来说,SUPPLEMENTAL_LOG_DATA_MIN必须为YES。对于Oracle 10g及更高版本,SUPPLEMENTAL_LOG_DATA必须为YES或IMPLICIT,可以输入以下命令启用补充日志:


SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;

2.启用数据库的强制日志

与补充日志的记录不同,强制日志记录用于确保数据库中的所有更改(除了对临时表空间和临时段的更改之外)均有记录。对于OGG而言,强制日志记录非常详细,因为它可以确保能够捕获所有更改,而与需要捕获的表空间或对象无关。结合补充日志记录,强制日志将捕获对数据库执行的所有SQL事务,并将其记录到重做日志中。下面的命令可用于检查是否打开了强制日志,若没有则打开,命令如下:


SQL> SELECT FORCE_LOGGING FROM V$DATABASE;
SQL> ALTER DATABASE FORCE LOGGING;

3.打开OGG参数

从Oracle 11g(11.2.0.4或更高版本)开始,要想使用OGG,需要启用一个新参数,以告诉数据库OGG将在数据库内执行复制。show parameter命令可用于显示此参数的默认设置:


SQL> show parameter OGG 
NAME                   TYPE    VALUE 
---------------------- ------- ---------------- 
enable_OGG_replication boolean FALSE

enable_OGG_replication默认设置为FALSE。可以使用如下ALTER SYSTEM命令动态修改此参数:


SQL> alter system set enable_OGG_replication=true scope=both;

4.创建OGG管理用户

在为单向复制构建OGG环境之前,需要创建一个数据库用户,以便OGG与数据库之间进行交互,并确保可以执行复制。下面为用户创建一个独立的表空间,用于存放OGG的相关数据。示例代码如下:


SQL> create tablespace odc_tps datafile '+DATA/orcl/odc01.dbf' size 100M autoextend on;
SQL> create user odc identified by odc default tablespace odc_tps;

任何OGG配置都需要在复制环境的两侧创建此用户。该用户需要一组权限,以确保复制可以执行所有的更新、插入、删除和数据定义语言(DDL)等操作。权限授予命令如下:


SQL> GRANT CONNECT TO odc;
SQL> GRANT ALTER ANY TABLE TO odc;
SQL> GRANT ALTER SESSION TO odc;
SQL> GRANT CREATE SESSION TO odc;
SQL> GRANT FLASHBACK ANY TABLE TO odc;
SQL> GRANT SELECT ANY DICTIONARY TO odc;
SQL> GRANT SELECT ANY TABLE TO odc;
SQL> GRANT RESOURCE TO odc;
SQL> GRANT DBA TO odc;

安装成功后可以收回DBA的权限,但要赋予其UNLIMITED TABLESPACE权限,可使用下面任一命令实现赋权:


SQL>  GRANT UNLIMITED TABLESPACE TO odc;
SQL> alter user odc quota unlimited on odc_tps;

如果要在Oracle 11.2.0.4或更高版本的数据库上构建OGG用户,则可以选择使用DBMS_OGG_AUTH.GRANT_ADMIN_PRIVILEGE过程。

5.OGG的下载安装

(1)下载OGG软件

OGG的异构性质决定了该产品版本的多样性。第一次下载OGG软件时,用户也许会被各种版本迷得眼花缭乱,但还是可以从命名方式中看出一定的规律,它往往以OGG的版本、支持的数据库类型及操作系统来命名。

如何确定所需下载的版本呢?最简单的方法就是在Oracle技术网(OTN,http://otn.oracle.com)的中间件模块中查阅该页面提供的认证矩阵列表,确认所需的操作平台与数据库版本是否被支持,然后再下载相应的OGG安装包。如果需要下载更早版本的安装包,则可访问云平台(https://edelivery.oracle.com/)。

下载OGG软件后,可以将其存放在可以运行的位置,并保证空间充足,例如,示例中是将介质上传到/odc目录中。

(2)安装OGG软件

unzip使用“-d”选项将软件解压到指定目录中,代码如下:


shell> unzip OGG 12.3.0.1.4 for Oracle on Linux x86-64(V975837-01).zip -d /odc

解压生成一个名为fbo_ggs_Linux_x64_shiphome的目录,并进入Disk1子目录。运行runInstaller,初始化OUI(Oracle Universal Installer,Oracle统一用户安装界面)并进行安装,由于安装过程较为简单,在此省略对本次安装过程的讲解。

(3)配置OGG环境变量

OGG使用共享库,在运行OGG服务命令界面(GGSCI)或任何其他OGG进程之前,必须为OGG配置环境变量。在Linux(和Solaris等)上,需要将LD_LIBRARY_PATH设置为包含JVM共享库的目录。

AIX平台上设置的是LIBPATH,HP-UX IA64上设置的是SHLIB_PATH。

在Linux上配置路径的命令如下:


shell> export LD_LIBRARY_PATH=/odc/oggsoft:$ORACLE_HOME/lib:$LD_LIBRARY_PATH

(4)创建子目录

创建进程组之前,还需要创建一些子目录。创建子目录的方法非常简单,只需要启动OGG服务命令界面并执行CREATE SUBDIRS命令即可,示例代码如下:


GGSCI> create subdirs
Creating subdirectories under current directory /odc/oggsoft
Parameter file                 /odc/oggsoft/dirprm: created.
Report file                    /odc/oggsoft/dirrpt: created.
Checkpoint file                /odc/oggsoft/dirchk: created.
Process status files           /odc/oggsoft/dirpcs: created.
SQL script files               /odc/oggsoft/dirsql: created.
Database definitions files     /odc/oggsoft/dirdef: created.
Extract data files             /odc/oggsoft/dirdat: created.
Temporary files                /odc/oggsoft/dirtmp: created.
Credential store files         /odc/oggsoft/dircrd: created.
Masterkey wallet files         /odc/oggsoft/dirwlt: created.
Dump files                     /odc/oggsoft/dirdmp: created.

使用与安装源端OGG软件相同的步骤,安装目标库OGG软件。

(5)创建并启动MGR进程(Manager Process)

创建MGR进程参数文件,并启动MGR,命令如下:


GGSCI> edit param mgr

port 7809
DYNAMICPORTLIST 7800-7810
PURGEOLDEXTRACTS ./dirdat/bt*, USECHECKPOINTS, MINKEEPHOURS 24
autorestart extract * retries 10 waitminutes 10

GGSCI> start mgr

在上述MGR参数文件中,PURGEOLDEXTRACTS(清除旧的extract文件)选项可用于告诉管理员如何处理旧的跟踪(trail)文件。AUTORESTART(自动重启)选项可用于设置何时重新启动。动态端口参数DYNAMICPORTLIST可用于帮助OGG在需要时使用防火墙进行通信,并限制将端口分配给特定范围内的通信;否则,OGG会随机获取未使用的端口。

6.创建捕获进程并启动

设置数据库复制的第一步就是启动捕获进程。必须在数据初始化之前就启动捕获进程,并确认它可以正常捕获数据的变更。

1)添加表级别附加日志。使用配置的OGG用户登录数据库,通过运行schematrandata或trandata来创建OGG所需的表级补充日志组。OGG除了更改的数据之外还需要键值,将补充日志记录添加到数据库表可确保对OGG所需键值的记录,以便Replicate将更改的数据应用于目标数据库。使用ADD TRANDATA命令可以强制数据库记录源数据库上更新的所有主键列。在OGG服务命令界面执行如下命令可实现表级别附加日志的添加:


GGSCI> dblogin userid odc password odc 
GGSCI> add trandata hr.*
GGSCI> info trandata hr.*

需要添加表级别附加日志的表或用户可以按照具体需求进行更改,上述代码示例为HR用户下的所有表都加上了表级别附加日志并检查确认。

2)创建捕获进程。在OGG服务命令界面执行如下命令以创建捕获进程:


GGSCI> ADD EXTRACT E_HR, TRANLOG, BEGIN NOW 
GGSCI> ADD EXTTRAIL dirdat/bt, EXTRACT E_HR

上述代码段中参数的解释具体如下。

·ADD EXTRACT E_HR:添加捕获进程E_HR,该进程的名称与其参数文件中的名称一致。

·TRANLOG:使用数据库事务日志作为捕获数据源。

·BEGIN NOW:在启动捕获进程时就捕获数据。

·ADD EXTTRAIL:为E_HR进程添加本地trail文件。

·./dirdat:trail文件的存放目录。

·bt:trail文件的前缀为bt。

3)配置捕获进程的参数文件,命令如下:


GGSCI> edit param E_HR
EXTRACT E_HR
USERID odc, PASSWORD odc
SETENV (ORACLE_HOME="/u01/app/oracle/product/11.2.0/db_1")
SETENV (ORACLE_SID="orcl")
TRANLOGOPTIONS DBLOGREADER
EXTTRAIL ./dirdat/bt
TABLE HR.*;

从上面的例子中,我们可以看到这是一个名为E_HR的捕获进程,通过一个名为odc的用户,设置环境变量来访问名为orcl的数据库,从事务日志中读取变更,捕获来自HR用户中所有表的数据处理语言(DML)。TRANLOGOPTIONS是控制捕获进程与数据库事务日志交互方式的参数。通过DBLOGREADER选项,该捕获进程将使用Oracle 11.2.0.2及更高版本中新的可用的应用程序编程接口(API)。访问事务日志后,捕获进程所捕获的数据将移至自定义的本地跟踪文件中。

4)启动或停止捕获进程。添加捕获进程后,需要启动进程,启动命令如下:


GGSCI> START EXTRACT E_HR

如果需要停止捕获进程,则可以使用类似的方法来停止,停止命令如下:


GGSCI> STOP EXTRACT E_HR

7.创建传输进程并启动

为了方便trail文件的传送,我们还需要创建单独的传输进程。就像捕获参数文件一样,传输进程参数文件也提供了类似的信息。与捕获进程的区别是,传输进程主要用于将跟踪文件和所捕获的事务传送到网络上的远程位置。

1)创建传输进程。可以使用GGSCI的如下命令创建传输进程:


GGSCI> ADD EXTRACT P_HR, EXTTRAILSOURCE ./dirdat/bt 
GGSCI> ADD RMTTRAIL ./dirdat/rt, EXTRACT P_HR

上述代码段中参数的解释具体如下。

·ADD EXTRACT P_HR:添加传输进程P_HR,该进程的名称与其参数文件中的名称一致。

·EXTTRAILSOURCE:指定源端前缀为bt的跟踪trail文件作为数据源。

·ADD RMTTRAIL:在目标数据库的指定目录上创建一个前缀为rt的trail文件。

2)配置捕获进程参数文件,命令如下:


EXTRACT P_HR
PASSTHRU
RMTHOST 192.168.238.57, MGRPORT 7809
RMTTRAIL ./dirdat/rt
TABLE HR.*;

读取此参数文件时,如果看到参数PASSTHRU,就要意识到该进程为传输进程。此外,在参数文件中,RMTHOST参数可用于查看trail文件传送到的远程主机的位置,并告诉传输进程如何使用带有端口号的MGRPORT选项连接到远程服务器,以传输捕获到的HR用户中所有表的变更。RMTTRAIL参数可用于告诉OGG在传输时将在远端创建一个以rt为前缀的跟踪文件。

3)启动或停止传输进程。添加传输进程后,需要启动进程,启动命令如下:


GGSCI> START EXTRACT P_HR

如果需要停止传输进程,则可以使用类似的方法来停止,停止命令如下:


GGSCI> STOP EXTRACT P_HR

3.5.2 目标端环境准备

在目标端安装数据库软件创建实例,并根据3.5.1节的步骤,安装OGG软件并创建管理用户。下面就在此基础上完成目标端的剩余配置,包括数据初始化和复制进程的创建。

1.数据初始化

初始化过程是将静态源数据库的副本加载到目标数据库中的过程。初始化时最常见的方法是使用Oracle数据泵(Data Pump)。使用此方法,需要先启动捕获进程和传输进程,然后使用创建副本的SCN启动复制进程。这样可以确保跳过在该SCN之前复制的所有事务,以免产生完整性冲突。使用数据泵做导出时,最关键的一点是必须使用参数FLASHBACK_SCN。以下提供了Oracle数据泵导出命令的示例代码:


shell> expdp "'"/ as sysdba"'" DIRECTORY=EXPORTS DUMPFILE="expdp_%U.dmp" 
    LOGFILE="expdp.log" PARALLEL=4 SCHEMA=HR FLASHBACK_SCN=189189821

Oracle数据泵导入命令的示例代码如下:


shell> impdp "'"/ as sysdba"'" DIRECTORY=IMPORTS DUMPFILE="expdp_%U.dmp" 
    LOGFILE="expdp-imp.log" PARALLEL=4 SCHEMA=HR

按需求导出数据,然后在目标端导入数据,完成数据的初始化。

数据初始化的方法有很多种,表3-7列举了4种常用初始化方法的适用场景。

表3-7 数据初始化方法对比

2.创建复制进程并启动

目标端数据导入完成,创建应用(复制)进程,该进程将读取文件,并按时间顺序应用数据。

1)创建检查点表(checkpointtable)。创建进程前,先为复制进程添加检查点表,用于跟踪已应用的事务。必须从GGSCI登录到数据库,然后运行ADD CHECKPOINTTABLE命令。如果在“./GLOBALS”文件中配置了检查点表名称,则OGG会使用该名称而不是默认的表名称。


GGSCI> dblogin userid odc password odc 
GGSCI> add checkpointtable 
No checkpoint table specified. Using GLOBALS specification (odc.checkpoint)… 
Successfully created checkpoint table odc.checkpoint.

2)创建复制进程,命令如下:


GGSCI> add replicat R_HR, exttrail ./dirdat/rt

上述代码段中参数的解释如下。

·ADD REPLICAT R_HR:添加复制进程R_HR,该进程的名称与其配置文件中的名称一致。

·EXTTRAIL:指定处理前缀为rt的trail文件。

3)配置复制进程的参数文件。复制参数文件的设置将控制OGG如何应用变更,其提供了将事务连接到目标表的映射命令,示例代码如下:


REPLICAT R_HR 
SETENV (ORACLE_HOME="/u01/app/oracle/product/11.2.0/db_1") 
SETENV (ORACLE_SID="orcl") 
USERID odc, PASSWORD odc 
ASSUMETARGETDEFS
map HR.*, target HR.*;

与捕获参数文件一样,复制参数文件需要对连接到Oracle数据库所需的环境进行设置。需要提供用户名和密码才能与数据库进行交互。在旧版本的OGG中,如果源端和目标端的表结构相同,则需要使用参数ASSUMETARGETDEFS关联源和目标之间的元数据结构。如果元数据不同,则此参数需要替换为支持映射的SOURCEDEF文件。在文件的末尾,添加map语句,该语句的作用是将传入的事务映射到目标端。

4)启动或停止复制进程。添加复制进程后,需要启动进程,命令如下:


GGSCI> START REPLICAT P_HR [ aftercsn || atscn ] [ SCN ]

使用先前记录的SCN运行此命令时,该进程将尝试从该时间点开始复制。

如果需要停止复制进程,则可以使用类似的方法停止,命令如下:


GGSCI> STOP REPLICAT P_HR

至此,OGG的数据同步已经配置完成。

3.5.3 数据比对安装配置

OGG Veridata是一种高速的数据比较和修复解决方案,可在不中断正在进行的业务流程的情况下,识别、报告和修复数据库之间的数据差异。OGG Veridata 12c减少了比较数据所需的时间和资源数量,而且最大程度地降低了人为错误的影响,同时还加快了发现潜在问题的速度,并能够迅速解决相关问题。Veridata 11g与Veridata 12c的安装方法存在很大区别,对于Veridata 12c(12.2.1.4)的安装,与OGG监控(Monitor)一样,也需要设置Oracle WebLogic Server域。完整的安装过程包括以下步骤。

1)安装JDK 1.8或更高版本。

2)安装Oracle WebLogic Server 12c版本。

3)为Veridata信息库安装受支持的数据库(Oracle或SQL Server)。

4)安装Veridata服务。

5)安装OGG Veridata代理。

6)使用RCU创建OGG Veridata信息库。

7)使用配置向导创建WebLogic Server域。

8)启动OGG Veridata服务。

9)启动OGG Veridata代理。

我们可以通过Oracle E-Delivery或Oracle技术网(OTN)获得所有的软件,下面通过示例展示OGG Veridata在Linux上的安装过程。所需的安装包及下载地址简单罗列如下。

·Java Development Kit(JDK)。安装和运行Veridata服务器和代理都需要安装软件JDK,可以通过如下地址下载该软件:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

·Oracle融合中间件12.2.1.4.0(Oracle Fusion Middleware 12c)Product Distribution。运行OGG Veridata服务需要此软件,可通过如下地址下载该软件:https://www.oracle.com/tools/downloads/application-development-framework-downloads.html

·OGG Veridata 12c。应用程序软件本身,该软件可用于执行两个数据库之间的数据比对,可通过如下地址下载该软件:https://www.oracle.com/middleware/technologies/OGG-downloads.html

·官方文档。由于篇幅限制,此处不再详细展开Veridata的安装过程,具体安装步骤请参考官方文档:https://docs.oracle.com/en/middleware/goldengate/veridata/12.2.1.4/gvdis/index.html

安装完Veridata后,下面就来对其进行配置,并展开初次的数据比对。Veridata的配置步骤具体如下。

1)创建数据库连接。

2)创建组。

3)配置比较对。

4)创建Job。

5)执行作业。

6)查看报告。

1.创建数据库连接

配置比较对(Compare Pair)的第一步是定义源与目标数据库的连接。在Veridata应用程序服务器主页上,单击左侧菜单功能区中“Configuration”(配置)菜单上的“Connect Configuration”(连接配置),然后单击右上角的“new”(新建)创建新连接。“New Connection Assistant”(新建连接助手)对话框将分三步完成新连接的创建,具体步骤如下。

1)“Connection Name”页面:输入需要创建的连接的名称和相关描述(可选)。

2)“GoldenGate Connection”页面:填写源端IP、对应的数据库类型,以及在配置Veridata代理时设置的端口(参考agent.properties文件中的server.port参数)。点击“verify”(验证)进行连接验证,成功后进入下一步。

3)“Database Connection”页面:填写用于数据库连接的账号和密码,点击“Test connection”进行验证,成功后点击“Finish”结束。至此,源端连接配置完成。目标端的连接配置同上。

2.创建组

实际创建工作之前,应该先定义一个工作组,组是一个或多个比较对的逻辑容器。首先,从左侧“Configuration”菜单中选择“Group Configuration”(组配置),单击右上角的“new”打开“New Group Assistant”(新建组助手)对话框开始定义组。具体步骤如下。

1)在“Group Name”页面输入需要创建的工作组的名称和相关描述(可选)。

2)在“Connection Information”页面通过下拉菜单选择对应的源端和目标端连接。

确认完上面两步之后,单击“Finish”进入确认对话框,在此选中复选框“Go to Compare Pair Configuration…”(进入比较对配置界面),将跳转到“Compare Pair Configuration”对话框,可在此进行比较对的配置。

3.配置比较对

既可以在创建组时就直接设置比较对象,也可以为已经存在的组设置比较对象。从左侧“Configuration”菜单中选择“Group Configuration”,选择需要配置比较对的组,将跳转到Edit Group页面,选择“Go to Compare Pair Configuration…”,将跳转到“Compare Pair Configuration”页面进行比较对配置。进入比较对配置界面后,根据需求选择相应的映射模式,“Pattern Mapping”(模式映射)模式可以一次映射多个对象,如选择源端和目标端的相应用户,Veridata会根据表名自动逐一配对以组成比较对;“Manual Mapping”(人工映射)模式一次只能配置一个比较对。此处笔者一般会选择“Pattern Mapping”模式。配置完成后点击页面右下角“Compare Pair”(比较对)跳转到“preview”(预览)页面。到目前为止,新的比较对尚未保存到存储库中。确认后点击“save”进行保存。

4.创建Job

下一个任务是创建和配置验证作业(Job)。从左侧“Configuration”菜单中选择“Job Configuration”(作业配置),单击“new”开始打开“New Job Assistant”(新建作业助手)对话框开始创建作业。具体步骤如下。

1)在“Job Name”页面输入需要创建的作业的名称和相关描述(可选)。

2)在“Group Information”页面勾选需要在此作业中进行比对的工作组。

后面的Task3和Task4是可选的,因为连接信息在选择的组中已经配置过,所以到这一步可以直接单击“Finish”完成作业的配置。当然也可以根据步骤提示配置完4个页面后再点击完成。

至此,系统已经准备好执行简单的数据验证作业了。

5.执行作业

要运行作业,请单击左侧菜单功能区上的“job/execute job”(作业/执行作业),进入相应的菜单。从“job”下拉列表中选择定义的作业,单机“run job”开始执行作业。

6.查看报告

如果执行的作业中需要比对的表较多,或者表较大,那么作业会持续运行一段时间。若我们想要查看运行中作业的情况,比如,还剩多少表没有比对,或者查看目前的比对中是否存在不一致的表,则可以在左侧“running Jobs”(正在运行的作业)菜单中按需求进行选择,比如,图3-1选择按作业查看,可以看到目前正在运行名为jtest的作业,该作业一共比对了5张表,其中2张表已经比对成功且数据一致,还剩3张表正在比对。

图3-1 查看运行中的作业比对情况

作业完成后,将在“Finished Jobs”(已结束的作业)菜单中添加一条记录。如图3-2所示,jscott作业对应的“comparison status”(比较状态)列为绿色,表示已运行成功,且没有发现数据差异。该列还有其他两种状态:红色表示作业运行失败;黄色表示作业运行成功,但是存在数据差异。

图3-2 已完成的作业比对情况查看

有关作业运行的其他详细信息,可以单击列表右侧的“report”(报告)超链接获取相关信息。

3.5.4 正式迁移前的准备

1.OGG反向同步部署

根据3.5.1节和3.5.2节中的进程创建步骤,在目标端上配置抽取进程和传输进程,但不启动进程;在源端上部署应用进程,也不启动进程。限于篇幅,这里就不再介绍具体配置过程了。

这一步作为回退方案,等数据库正式迁移后,启动反向同步进程,将新环境的增量数据抽取到老环境中。如果新环境无法正常提供业务,或是因为其他原因需要重新启用老环境,则可以在修改IP地址之后,重新启用老环境。基于反向同步进程的实时应用,即使是在迁移之后,新老环境的数据也能保持一致。不过,为了保留老环境,一般建议在迁移之后只启动反向的抽取进程和传输进程,只有在决定要回退时才启动应用进程。

2.OGG检查

检查源端和目标端的OGG同步是否正常,命令如下:


GGSCI > Info all
GGSCI > info 进程名

3.对象检查

检查新老环境的对象是否一致,命令如下:


SQL> SELECT D.OWNER, D.OBJECT_TYPE, COUNT(*)
  FROM dba_objects@old d
 WHERE d.OWNER in (代入需要迁移的用户)
   and d.object_type not in ('TRIGGER', 'JOB', 'VIEW', 'LOB')
   and object_name not like 'MLOG%'
   AND NOT EXISTS (SELECT *
          FROM DBA_RECYCLEBIN@old B
         WHERE B.object_name = D.OBJECT_NAME
           AND D.OWNER = B.owner)
 GROUP BY D.OWNER, D.OBJECT_TYPE
minus
SELECT D.OWNER, D.OBJECT_TYPE, COUNT(*)
  FROM dba_objects d
 WHERE d.OWNER in (代入需要迁移的用户)
   and d.object_type not in ('TRIGGER', 'JOB', 'VIEW', 'LOB')
   and object_name not like 'MLOG%'
   AND NOT EXISTS (SELECT *
          FROM DBA_RECYCLEBIN B
         WHERE B.object_name = D.OBJECT_NAME
           AND D.OWNER = B.owner)
 GROUP BY D.OWNER, D.OBJECT_TYPE;

4.索引检查

按用户表名比对两边的索引数量,得到新老环境索引不一致的用户和表名。索引检查命令如下:


SQL> select TABLE_OWNER, TABLE_NAME, COUNT(*)
  from DBA_INDEXES@old
 where owner in (代入需要迁移的用户)
 group by table_owner, table_name
minus
select TABLE_OWNER, TABLE_NAME, COUNT(*)
  from DBA_INDEXES
 where owner in (代入需要迁移的用户)
 group by table_owner, table_name;

根据具体的表进一步比对索引(按照索引使用的字段进行比对):


SQL> select index_owner,
       index_name,
       table_owner,
       table_name,
       listagg(to_char(column_name), ',') within group(order by index_name) as 
           full_column
  from DBA_IND_COLUMNS@old
 where table_owner = '用户名' 
   and table_name = '表名'
 group by index_owner, index_name, table_owner, table_name
minus
select index_owner,
       index_name,
       table_owner,
       table_name,
       listagg(to_char(column_name), ',') within group(order by index_name) as 
           full_column
  from DBA_IND_COLUMNS
 where table_owner = 'ZMY'
   and table_name = 'TEST201922'
 group by index_owner, index_name, table_owner, table_name;

5.视图检查

检查新老环境的视图是否一致,命令如下:


SQL> select v.owner, v.view_name, b.status
  from dba_views@old v, dba_objects@old b
 where v.owner in (代入需要迁移的用户)
   and v.view_name = b.object_name
minus
select v.owner, v.view_name, b.status
  from dba_views v, dba_objects b
 where v.owner in (代入需要迁移的用户)
   and v.view_name = b.object_name

若缺少视图,则在源端获取DDL后在目标端重建,命令如下:


SQL> select  sys.dbms_metadata.get_ddl(VIEW,'视图名','用户') From DUAL;

6.database link检查

检查新老环境DBLINK是否一致,且是否全都可以正常使用,命令如下:


SQL> select owner, object_name, status
  from dba_objects@old
 where object_type = 'DATABASE LINK'
minus
select owner, object_name, status
  from dba_objects
 where object_type = 'DATABASE LINK';

若DBLINK缺失,则采用重导的方式修复差异,导出老环境所有数据库连接的代码如下:


shell> expdp "'"/ as sysdba"'" include=db_link directory=EXPDP dumpfile=dblink.dmp
    logfile=expdp_dblink.log full=y  
shell> impdp "'"/ as sysdba"'" directory=IMPDP dumpfile=dblink.dmp logfile=
    impdp_dbkink.log

7.函数检查

检查新老环境的函数是否一致,命令如下:


SQL> select distinct s.name,s.owner, b.status
  from dba_source@old s, dba_objects@old b
 where s.name = b.object_name
   and b.object_type = 'FUNCTION'
   and s.owner in (代入需要迁移的用户)
minus
select distinct s.name,s.owner, b.status
  from dba_source s, dba_objects b
 where s.name = b.object_name
   and b.object_type = 'FUNCTION'
   and s.owner in (代入需要迁移的用户)

若缺少函数,则在源端获取DDL后在目标端重建,命令如下:


SQL> select  sys.dbms_metadata.get_ddl('FUNCTION','函数名','用户名') From DUAL;

8.过程检查

检查新老环境的过程(PROCEDURE)是否一致,命令如下:


SQL> select distinct s.name,s.owner, b.status
  from dba_source@old s, dba_objects@old b
 where s.name = b.object_name
   and b.object_type = 'PROCEDURE'
   and f.owner in (代入需要迁移的用户)
minus
select distinct s.name,s.owner, b.status
  from dba_source s, dba_objects b
 where f.name = b.object_name
   and b.object_type = 'PROCEDURE'
   and s.owner in (代入需要迁移的用户)

若缺少PROCEDURE,则在源端获取DDL后,在目标端重建,命令如下:


SQL> select  sys.dbms_metadata.get_ddl('PROCEDURE','过程名','用户名') From DUAL;

9.包检查

检查新老环境的包是否一致,命令如下:


SQL> select distinct s.name,s.owner, b.status
  from dba_source@old s, dba_objects@old b
 where s.name = b.object_name
   and b.object_type = 'PACKAGE'
   and s.owner in (代入需要迁移的用户)
minus
select distinct s.name,s.owner, b.status
  from dba_source s, dba_objects b
 where s.name = b.object_name
   and b.object_type = 'PACKAGE'
   and s.owner in (代入需要迁移的用户)

SQL> select distinct s.name,s.owner, b.status
  from dba_source@old s, dba_objects@old b
 where s.name = b.object_name
   and b.object_type = 'PACKAGE BODY'
   and s.owner in (代入需要迁移的用户)
minus
select distinct s.name,s.owner, b.status
  from dba_source s, dba_objects b
 where s.name = b.object_name
   and b.object_type = 'PACKAGE BODY'
   and s.owner in (代入需要迁移的用户)

若缺少包,则在源端获取DDL后在目标端重建,命令如下:


SQL> select  sys.dbms_metadata.get_ddl('PACKAGE','对象名','用户名') From DUAL;
SQL> select  sys.dbms_metadata.get_ddl('PACKAGE_BODY','对象名','用户名') From DUAL;

10.同义词检查

检查新老环境的同义词(synonym)是否一致,命令如下:


SQL> select s.*, b.status
  from dba_synonyms@test s, dba_objects@test b
 where s.synonym_name = b.object_name
   and b.object_type = 'SYNONYM'
   and s.owner in (代入需要迁移的用户)
minus
select s.*, b.status
  from dba_synonyms s, dba_objects b
 where s.synonym_name = b.object_name
   and b.object_type = 'SYNONYM'
   and s.owner in (代入需要迁移的用户)

如缺少同义词,则在源端获取DDL后在目标端重建,命令如下:


SQL> select  sys.dbms_metadata.get_ddl('SYNONYM','对象名','用户名') From DUAL;

11.物化视图检查

检查新老环境的物化视图是否一致,若新环境没有,则重建物化视图,命令如下:


SQL> select * from DBA_MVIEWS;

3.5.5 正式迁移

1.老生产端停止提供业务

确认老生产端的应用已经停止后,即可停止数据库监听,命令如下:


shell> cd /oracle/crs10g/bin

shell> ./srvctl status nodeapps -n hisdb01
shell> ./srvctl status nodeapps -n hisdb02

shell> ./srvctl stop listener -n hisdb01
shell> ./srvctl stop listener -n hisdb02

将监听端口修改为1523,防止写物理IP的应用连入,命令如下:


shell> cd /oracle/ora10g/network/admin
shell> vi listener.ora

将原来使用的1521端口(默认设置)修改为1523,并重启数据库,命令如下:


shell> ps -ef |grep "LOCAL=NO" |grep -v grep | awk '{print $2}' | xargs kill -9
SQL> shutdown immediate
SQL> startup

2.新老环境停止OGG同步

老生产端多次切换归档后,即可停止生产端OGG进程,命令如下:


shell> sqlplus / as sysdba
SQL> alter system switch logfile; 
SQL> alter system archive log current;
SQL> alter system checkpoint;

GGSCI> stop 抽取进程
GGSCI> stop 传输进程
GGSCI>stop mgr

目标端确认跟踪文件已经全部应用后,即可停止目标端OGG进程,命令如下:


GGSCI> stop 应用进程
GGSCI>stop mgr

3.老生产端停止作业

为了防止定时作业等操作,将老生产端的作业设置为0,命令如下:


SQL> show parameter job_queue_processes
SQL> alter system set job_queue_processes=0 sid='*';

4.重建触发器、序列和作业

1)重建触发器。源端导出触发器,命令如下:


shell> expdp "'"/ as sysdba"'" include=trigger directory=EXPDIR dumpfile=trigger.
    dmp logfile=expdp_trigger.log schemas= 代入需要迁移的用户

删除目标库的触发器,命令如下:


SQL> select 'drop trigger '|| '"'|| owner || '"' ||'.'||trigger_name||';' from 
    dba_triggers where owner in (代入需要迁移的用户);
logfile=expdp_trigger.log schemas= 代入需要迁移的用户

目标端导入触发器,命令如下:


shell> impdp "'"/ as sysdba"'" include=trigger directory=IMPDIR dumpfile=trigger.DMP 
    logfile=impdp_trigger.log

2)重建序列(sequence)。源端导出序列,命令如下:


shell> expdp "'"/ as sysdba"'" include=sequence directory=EXPDIR dumpfile=
    sequence.dmp logfile=expdp_sequence.log schemas= 代入需要迁移的用户

删除目标库的序列,命令如下:


SQL> select 'drop sequence '|| '"'|| SEQUENCE_OWNER || '"' ||'.'||SEQUENCE_NAME||';' 
    from dba_sequences where SEQUENCE_OWNER in (代入需要迁移的用户);

目标端导入序列,命令如下:


shell> impdp "'"/ as sysdba"'" include=sequence directory=IMPDIR dumpfile=
    sequence.dmp logfile=impdp_sequence.log

3)重建作业。源端导出作业,命令如下:


shell> expdp "'"/ as sysdba"'" include=job directory=EXPDIR dumpfile=job.dmp 
    logfile=expdp_job.log schemas=代入需要迁移的用户

删除目标库的作业,命令如下:


SQL select 'exec dbms_job.remove('||JOB||');' FROM dba_jobs where log_user in 
    (代入需要迁移的用户);

目标端导入作业,命令如下:


shell> impdp "'"/ as sysdba"'" directory=IMPDIR dumpfile=job.dmp logfile=
    impdp_job.log

5.比对数据

这里使用Veridata再次比对数据。

6.编译无效对象,收集统计信息

1)比对无效对象,命令如下:


SQL> select owner, object_name, object_type, status
  from dba_objects
 where status <> 'VALID'
   and owner not in ('SYSMAN','PUBLIC')
   and object_name not in
       (select object_name from odc.invalid_object_20191114@old);

2)重新编译无效对象,命令如下:


SQL> @?/rdbms/admin/utlrp.sql

3)最后一次收集统计信息,命令如下:


SQL> EXEC DBMS_STATS.GATHER_DICTIONARY_STATS;

7.新库设置作业

在目标端设置作业,命令如下:


SQL> alter system set job_queue_processes=16 sid='*';

至此,迁移已经全部完成,若不需要修改IP,则可进行内部业务测试,确认测试没问题后即可对外提供业务。

3.5.6 迁移失败的回退措施

打开反向同步,在目标端执行如下命令:


ggsci> alter 抽取进程 begin now
ggsci> start 抽取进程
ggsci> start 传输进程

上述代码段只打开抽取进程和传输进程,不打开应用。

若需要回退,则启动目标端抽取进程和传输进程(一般迁移完成后就会启动),启动源端应用进程,确认增量数据追平后,即可停止各OGG进程。若IP发生了变更,则在修改IP之后再打开数据库,并启用源端Job,禁用目标端Job。