MSSQL Server 迁移至 ORACLE解决方案

时间:2022-06-21 00:38:53

一、       概要

本方案旨在提供项目运行中的数据库平台及类型迁移转换工作参考,阅读本方案将有助于清楚了解数据库类型转换相关工作内容。预评估各项工作内容的工作量。

 

数据库类型迁移的工作内容至少包含转换数据库结构(DDL )、视图、存储过程、函数、触发器、业务查询SQL 及相关SQL 脚本转换。

 

Ø    适用范围

Microsoft   SQL   Server   2000 2014

ORACLE 10g 11g 12c

二、       迁移工具

OGG

 


三、       数据库对象类型及语法转换

1         数据库结构转换

Ø    常见数据库数据类型:

SQL  Server Oracle 之间的数据类型映射。

 

字符和二进制字符串类型:

SQLServer

说明

ORACLE

CHAR (n)

Fixed-length non-Unicode string, 1 <=  n <= 8000

CHAR(n)

NCHAR(n)

Fixed-length Unicode UCS-2 string, 1 <=  n <= 4000

NCHAR(n)

NVARCHAR n

Variable-length Unicode UCS-2 string, 1 <=  n <= 4000

NVARCHAR2(n)

NVARCHAR m ax

2G

NCLOB

VARCHAR

Variable-length non-Unicode string, 1 <=  n <= 8000

VARCHAR2(n)

VARCHAR(max)

2GB

CLOB

 

数字类型:

SQLServer

说明

ORACLE

BIGINT

64 位整数

NUMBER(19)

DECIMAL(p,s) / DEC(p,s) 

Fixed-point number

NUMBER(p,s)

FLOAT(n)

Single ( n <= 24) and double ( n <= 53) 
precision floating-point number

NUMBER

INTERGER / INT

32-bit integer

NUMBER(10)

NUMBERIC(p,s)

Fixed-point number

NUMBER(p,s)

REAL

Single precision floating-point number

NUMBER

SMALLINT

16-bit integer

NUMBER(5)

TINYINT

0 to 255

NUMBER(3)

 

日期和时间:

SQLServer

说明

ORACLE

DATA

Date (year, month and day)

DATE includes time

DATATIME

Date and time with milliseconds (accuracy .000, .003, .007 seconds)

TIMESTAMP(3)

TIME(p)

Time, 0 <=  p <= 7 (100 nanoseconds accuracy)

TIMESTAMP(p)

 

其他数据类型:

SQLServer

说明

ORACLE

BIT

0,1 and NULL

NUMBER(1)

MONEY

Monetary data

NUMBER(19,4)

SMALLMONEY

Monetary data

NUMBER(10,4)

UNIQUEIDENTIFIER

GUID with dashes(-)

CHAR(36)

XML

XML data

XMLTYPE

 

Ø    常用内置SQL 函数:

 

转换内置SQL 函数

SQLServer

说明

ORACLE

CONVERT CHAR | VARCHAR exp

Convert to string

TO_CHAR(exp)

GETDATE()

Get the current date and time

SYSTIMESTAMP

MONTH(datetime)

Extract month from datetime

EXTRACT(MONTH FROM datetime)

SYSTEM_USER

OS   user name

SYS_CONTEXT(‘USERENV‘,’OS_USER’)

YEAR(datatime)

Extract year from datetime

EXTRCT(YEAR FROM datetime)

 

Ø    建表语句声明语法

 

SQLServer

说明

ORACLE

IDENTITY( start, increment)

Identity column

Emulated using a sequence and trigger

DEFAULT  exp

Column default

DEFAULT must be specified right after 
data type, before NOT NULL etc. 

CONSTRAINT  name DEFAULT  value

Named DEFAULT

DEFAULT  value

CLUSTERED | NONCLUSTERED

Clustered and non-clustered 
primary and unique key

Keyword removed

col type   CONSTRAINT  name 
PRIMARY KEY( col)

Inline primary key

col type   CONSTRAINT  name 
PRIMARY KEY - no column name 
in inline constraint

PRIMARY KEY( col ASC | DESC, …)

Sorting order in constraint

PRIMARY KEY( col, …) - No ASC, DESC allowed

ROWGUIDCOL

Indicates that the column is 
GUID, but IDs are not generated

Keyword removed

 

主健和唯一索引选项:

SQLServer

说明

ORACLE

ALLOW_PAGE_LOCKS = ON | OFF

Allow to use page locks

Removed

ALLOW_ROW_LOCKS = ON | OFF

Allow to use row locks

Removed

FILLFACTOR =  num

Leave free space in leaf index nodes

Removed

IGNORE_DUP_KEY = ON | OFF

Ignore duplicate keys

Removed

PAD_INDEX = ON | OFF

Leave space in intermediate index nodes

Removed

STATISTICS_NORECOMPUTE = ON | OFF

Automatic statistics update

Removed

 

Ø    查询语句

SQLServer

说明

ORACLE

SELECT @v = (SELECT  c FROM …)

Assignment statement

SELECT  c INTO  v FROM …

SELECT @v = c, @v2 = c2 FROM …

SELECT INTO statement

SELECT  c, c2 INTO  v, v2 FROM …

SELECT … FROM

Result set from a procedure

OPEN  out_refcur FOR SELECT … FROM

 

返回行数:

SQLServer

说明

ORACLE

SELECT TOP  n …

Without sorting

SELECT … WHERE rownum <=  n

SELECT TOP  n … ORDER BY

With sorting

SELECT * (SELECT … ORDER BY) WHERE rownum <=  n

SELECT TOP  n PERCENT …

% Without sorting

SELECT … WHERE rownum <=  n/100 * 
(SELECT COUNT(*) …)

SELECT TOP  n PERCENT … ORDER BY

% With sorting

SELECT * (SELECT … ORDER BY) rownum <=  n/100 * 
(SELECT COUNT(*) …)

 

存储过程创建语句

SQLServer

说明

ORACLE

CREATE PROCEDURE | ALTER PROCEDURE  name


CREATE OR REPLACE PROCEDURE  name

@param   datatype   default OUT | OUTPUT


p_param   IN | OUT | IN OUT  datatype DEFAULT  default

Optional () for procedure parameters


() required

AS


IS | AS

RETURN  int

Return the status code

RETURN;

GO


/

 

SET  选项声明

SQLServer

说明

ORACLE

SET ANSI_NULLS ON | OFF

Use = <> with NULLs

Commented

SET ANSI_PADDING ON | OFF

Insert trailing blanks to VARCHAR

Commented

SET NOCOUNT ON | OFF

Send messages on affected rows

Removed

SET QUOTED_IDENTIFIER ON | OFF

Quote identifiers with ""

Commented

 

 

SQLServer

说明

ORACLE







 

 

 

数据库同步环境搭建

     实施环境如下:

 


版本

IP

OGG 版本

操作系统

源库

008R2

192.168.242.117

12.3

WIN2016

目标库

Oracle 11.2.0.4

192.168.238.56

12.2

Linux 6

            

 

参考文档:

 

 

  检查生产库

数据库需要设置为full recovery

打开sqlserver manager studio= 》展开database= 》右键点击源数据库= 》选择属性= = 》点击选项= 》选择恢复模式为全部

MSSQL Server 迁移至 ORACLE解决方案

 

检查

开启CDC

SELECT  is_cdc_enabled , CASE   WHEN  is_cdc_enabled =

THEN   'CDC 功能禁用'

ELSE   'CDC 功能启用'

END   描述

FROM   sys . databases

WHERE   NAME   =   'jmtest'

 

USE  jmtest

GO

EXECUTE   sys . sp_cdc_enable_db ;

GO

 

EXEC   sys . sp_cdc_enable_db

 

关闭数据库 'trunc. log on chkpt'

use   master

go

EXEC   sp_dboption   'jmtest' ,   'trunc. log on chkpt' ,   'false'

go

 

数据库须为完整回复(FULL)模式

use   master

go

alter   database  jmtest  set   recovery   full

go

 

查看数据库或表是否启用cdc (不需要启动,配置完成自动启动)

SELECT   name , is_cdc_enabled  FROM   sys . databases   WHERE  is_cdc_enabled  =  1  

SELECT   name , is_tracked_by_cdc  FROM  jmtest . sys . tables   WHERE  is_tracked_by_cdc  =  1 

GO

 

创建ODBC 数据源

MSSQL Server 迁移至 ORACLE解决方案

 

MSSQL Server 迁移至 ORACLE解决方案

 

 

 

这里最好选择集成windows身份验证

MSSQL Server 迁移至 ORACLE解决方案

 

MSSQL Server 迁移至 ORACLE解决方案

 

MSSQL Server 迁移至 ORACLE解决方案

 

MSSQL Server 迁移至 ORACLE解决方案

 

 

1 Ensure that the Extract has been deleted via  GGSCI: DELETE EXTRACT <extname>

确保没有挖掘进程存在,若有先删除

 

2 、删除已有的

EXECUTE sys.sp_cdc_drop_job 'cleanup'

 

3 Run the  ogg_cdc_cleanup_setup.bat  file, providing the following variable values:

执行 cdc cleanup 脚本

模板:

ogg_cdc_cleanup_setup.bat deleteExtCheckpoint <userid> <password> <databasename> <servername\instancename> <schema>

 

C:\ogg>ogg_cdc_cleanup_setup.bat createJob ggsadmin Hzmc321# jmtest (local) dbo

 

 

有时候会报错提示没有cdc capture ,这时可以先添加trandata 表后再来做这个步骤

MSSQL Server 迁移至 ORACLE解决方案

 

 

不支持的操作与类型

不支持truncate TextCopy WRITETEXT UPDATETEXT 操作

不支持SQL_Variant 类型

 

  安装生产端ogg

解压软件,配置mgr

C:\odc>ggsci

GGSCI (WIN-ARKCDINPK6G) 1> create subdirs

 

C:\odc>install addservice

// 这个命令保证如果运行 mgr 可以在后台跑,如果不添加这个服务运行进程的时候就会有一个窗口,且如果关掉进程就要停止

GGSCI> edit param mgr

参数:

PORT 7809

DYNAMICPORTLIST 7808-7809

autorestart extract *

PURGEOLDEXTRACTS C:\ogg\dirdat\* ,usecheckpoints, minkeepdays 1

 

ggsci>edit param ./GLOBALS

输入:

GGSCHEMA dbo

 

GGSCI> start mgr

 

创建挖掘进程

GGSCI> dblogin sourcedb  ogg3  –dblogin sourcedb + ODBC 数据源

GGSCI> add trandata ggsadmin.* -- 添加表级别附加日志

GGSCI> add extract jmext tranlog begin now

GGSCI> edit param jmext

参数:

extract jmext

sourcedb ogg3 userid ggsadmin password Hzmc321#

exttrail C:\ogg\dirdat\jm,format release 12.2

COMPRESSUPDATES

WILDCARDRESOLVE DYNAMIC

numfiles 5000

DISCARDFILE  C:\ogg\dirdat\jm.dsc,append,megabytes 100

TRANLOGOPTIONS MANAGECDCCLEANUP

//  MANAGESECONDARYTRUNCATIONPOINT 这个参数在 12.3 for SQL server 中无效,需要更改为 MANAGECDCCLEANUP ,但这个参数的前提就是要创建 cdc cleanup process

table odc.test;

 

 

创建传输进程

参数:

extract jmdmp

TRANLOGOPTIONS MANAGECDCCLEANUP

RMTHOST 192.168.238.56, MGRPORT 7809

RMTTRAIL /ogg12/dirdat/jm,format release 12.2

table odc.test;

 

生成表定义文件

GGSCI> edit param defgen

参数:

sourcedb ogg3 userid ggsadmin password Hzmc321#

table odc.test;

 

cmd 中进入ogg 安装目录,运行如下语句:

 C:\ogg\dirprm\defgen.prm

拷贝源端dirdef文件下的def文件到目标端的 dirdef文件下

 

数据库和日志

数据库备份:

》任务》备份

MSSQL Server 迁移至 ORACLE解决方案

选择磁盘方式及备份文件,注意空间

覆盖备份集

完成后验证

不压缩

MSSQL Server 迁移至 ORACLE解决方案

 

 

日志备份:

右键》任务》备份

 

MSSQL Server 迁移至 ORACLE解决方案

选择磁盘方式及备份文件,注意空间

覆盖备份集

完成后验证

截断日志

不压缩

 

MSSQL Server 迁移至 ORACLE解决方案

 

 

 

 

  目标主机安装ogg

创建用户

SQL> create tablespace odc_tps datafile '/oradata/smkdb/odc01.dbf' size 128M autoextend on;

 

Tablespace created.

 

SQL> create user odc identified by odc default tablespace odc_tps;

 

GRANT CONNECT TO odc;

GRANT ALTER ANY TABLE TO odc;

GRANT ALTER SESSION TO odc;

GRANT CREATE SESSION TO odc;

GRANT FLASHBACK ANY TABLE TO odc;

GRANT SELECT ANY DICTIONARY TO odc;

GRANT SELECT ANY TABLE TO odc;

GRANT RESOURCE TO odc;

GRANT DBA TO odc;

 

创建checkpoint table

cd /odc

$ sqlplus odc/odc

SQL> @chkpt_ora_create.sql

DROP TABLE ggs_checkpoint

           *

ERROR at line 1:

ORA-00942: table or view does not exist

 

Table created.

 

配置环境变量

HP-UX : SHLIB_PATH

AIX : LIBPATH

LINUX : LD_LIBRARY_PATH

例如:

export LD_LIBRARY_PATH=/odc:$LD_LIBRARY_PATH

export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH

 

安装ogg 配置 mgr

$ cd /odc

$ tar -xvf fbo_ggs_Linux_x64_ora11g_64bit.tar

$ ./ggsci

GGSCI> create subdirs

GGSCI> edit param mgr

参数:

port 7809

DYNAMICPORTLIST 7800-7810

PURGEOLDEXTRACTS ./dirdat/sm*, USECHECKPOINTS, MINKEEPHOURS 24

autorestart extract * retries 10 waitminutes 10

 

GGSCI> edit param ./GLOBALS

参数:

GGSCHEMA odc

CHECKPOINTTABLE odc.ggs_checkpoint --- 保存退出

 

GGSCI> start mgr

 

目标端创建replicat 进程

GGSCI> dblogin userid odc password odc

GGSCI> add replicat jmrep exttrail ./dirdat/jm

GGSCI> edit param jmrep

参数:

replicat jmrep

setenv (NLS_LANG="AMERICAN_AMERICA.ZHS16GBK")

userid odc, password odc

--handlecollisions

sourcedefs ./dirdef/defgen.def

DISCARDFILE /ogg12/dirrpt/me.dsc, APPEND megabytes 20

DISCARDROLLOVER on sunday

map dbo.test target xjm.test;

 

 

  初始化同步

初始化同步有2 中方法,一种是通过中间库的离线同步,一种是直接在线同步。

无论哪种方法,必须先在目标库里创建表结构,具体的数据类型转换,查看附录。

 

通过中间库的离线同步数据

4.1.1 还原数据库和日志

传送备份文件到中间库(本地库也可以)。

还原数据库:

数据库》还原数据库

目标数据库填写数据库名称

目标时间点默认

还原设备选择数据库备份文件

源设备》添加》选择备份文件,先还原数据库

 

MSSQL Server 迁移至 ORACLE解决方案

 

选择with replace restore with norecovery

 

MSSQL Server 迁移至 ORACLE解决方案

 

数据库还原后,右键点击该数据库= 》任务= 》还原= 》事务日志

选择从文件或磁带

 

MSSQL Server 迁移至 ORACLE解决方案

 

选择日志备份文件

 

MSSQL Server 迁移至 ORACLE解决方案

时间点选择备份完成时间(记录该时间点,作为挖掘进程的起始挖掘点)

此处为 56


 

MSSQL Server 迁移至 ORACLE解决方案

 

MSSQL Server 迁移至 ORACLE解决方案

 

选择restore with recovery

  MSSQL Server 迁移至 ORACLE解决方案 

4.1.2 中间库数据迁移到Oracle 数据库

Kettle 将中间库数据迁移到Oracle 数据库

 

4.1.3 启动ogg 进程

源端启动抽取和传输进程

GGSCI>  35  ( 要保证刚才恢复的事务日志还在原位置,否则无法启动进程 )

GGSCI> start extmed

GGSCI> start dmpmed

目标端启动应用进程

GGSCI> start repmed

 

在线同步数据

4.2.1 开启抽取进程和传输进程

GGSCI> start extmed

GGSCI> start dmpmed

 

4.2.2 第三方工具迁移数据

Kettle sqlserver 数据迁移到Oracle 数据库。

 

4.2.3 配置容错参数,开启应用进程

应用进程中添加handlecollisions 参数。

 

4.2.4 等到数据追平后,去掉容错参数,重启应用进程

GGSCI> edit param jmrep

参数:

replicat jmrep

setenv (NLS_LANG="AMERICAN_AMERICA.ZHS16GBK")

userid odc, password odc

--handlecollisions

sourcedefs ./dirdef/defgen.def

DISCARDFILE /ogg12/dirrpt/me.dsc, APPEND megabytes 20

DISCARDROLLOVER on sunday

map dbo.test target xjm.test;

 

GGSCI> stop jmrep

GGSCI> start jmrep

 

  数据比对方案

在正式迁移前多次校验数据,提前准备好 SQL 脚本

1)       veridata校验数据

使用veridata对表进行比对,提前多次校验,确认大致需要的比对时间。

2)       veridata失败的对象使用SQL脚本校验数据

对于veridata比对失败的对象,使用sql语句比对记录数。

 


 

  正式迁移

 

生产库停止业务

1)       确保OGG应用完毕

select group#,thread#,status from v$log;

切换多个归档,确保OGG 应用完(至少切x 次,因为有x 组日志组)。

alter system archive log current;

alter system checkpoint;

 

比对对象

是否一致

Veridata 比对任务


用户对象以及数量


索引以及数量


Lob 表数量


视图数量


无效对象数量


对象权限


Veridata 比对慢或者失败的表


 

提前创建一个到EMR 生产库的dblink ,方便数据比对

create public database link olddatabase connect to odc identified by odc using 'olddatabase';

 

中的任务

单表比对时间超过 10 分钟的表以及比对失败的表除外(根据客户情况,以及停机时间决定)

veridataadmin/hzmc321#

 

SELECT D.OWNER, D.OBJECT_TYPE

FROM dba_objects d

WHERE d.OWNER in ('ADT','AIB','BEHAVIORLOG'……)

and object_name not like 'MLOG%'

AND NOT EXISTS (SELECT 1

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

FROM dba_objects d

WHERE d.OWNER in ('ADT','AIB','BEHAVIORLOG'……)

and object_name not like 'MLOG%'

AND NOT EXISTS (SELECT 1

FROM DBA_RECYCLEBIN B

WHERE B.object_name = D.OBJECT_NAME

AND D.OWNER = B.owner)

GROUP BY D.OWNER, D.OBJECT_TYPE;

 

SELECT D.OWNER,D.OBJECT_TYPE,COUNT(*)

FROM dba_objects@old d

WHERE d.OWNER in ('ADT','AIB','BEHAVIORLOG'……)

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

minus

SELECT D.OWNER,D.OBJECT_TYPE,COUNT(*)

FROM dba_objects d

WHERE d.OWNER in ('ADT','AIB','BEHAVIORLOG'……)

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;

select owner,count(*) from dba_indexes@old 

where owner in ('ADT','AIB','BEHAVIORLOG'……)

group by owner 

minus

select owner,count(*) from dba_indexes 

where owner in ('ADT','AIB','BEHAVIORLOG'……)

group by owner order by owner;

 

select owner,INDEX_NAME from dba_indexes@old 

where owner in ('ADT','AIB','BEHAVIORLOG'……) 

minus

select owner,INDEX_NAME from dba_indexes 

where owner in ('ADT','AIB','BEHAVIORLOG'……);

表数量

select owner,table_name from dba_lobs@old where owner in ('ADT','AIB','BEHAVIORLOG'……) 

minus

select owner,table_name from dba_lobs where owner in ('ADT','AIB','BEHAVIORLOG'……);

select owner,VIEW_NAME from dba_views@old 

where owner in ('ADT','AIB','BEHAVIORLOG'……)

minus

select owner,VIEW_NAME from dba_views 

where owner in ('ADT','AIB','BEHAVIORLOG'……);

select count(*) from dba_objects where status<>'VALID';

@?/rdbms/admin/utlrp.sql

EMR 生产库权限(通过dblink 查找生产库环境权限)

drop table t_tmp_user_lhr;

create table t_tmp_user_lhr( id number, username varchar2(50), exec_sql varchar2(4000),create_type varchar2(20));

drop sequence s_t_tmp_user_lhr;

create sequence s_t_tmp_user_lhr;

 

begin

  for cur in (SELECT d.username,

                     d.default_tablespace,

                     d.account_status,

                     'create user ' || d.username || ' identified by ' ||

                     d.username || ' default tablespace ' ||

                     d.default_tablespace || ' TEMPORARY TABLESPACE ' ||

                     D.temporary_tablespace || ';' CREATE_USER,

                     replace(to_char(DBMS_METADATA.GET_DDL('USER',

                                                           D.username)),

                             chr(10),

                             '') create_USER1

                FROM dba_users@old d

               WHERE d.username in ('DXY')) loop

    INSERT INTO t_tmp_user_lhr

      (id, username, exec_sql, create_type)

    values

      (s_t_tmp_user_lhr.nextval, cur.username, cur.CREATE_USER, 'USER');

    INSERT INTO t_tmp_user_lhr

      (id, username, exec_sql, create_type)

      SELECT s_t_tmp_user_lhr.nextval,

             cur.username,

             CASE

               WHEN D.ADMIN_OPTION = 'YES' THEN

                'GRANT ' || d.privilege || ' TO ' || d.GRANTEE ||

                ' WITH GRANT OPTION ;'

               ELSE

                'GRANT ' || d.privilege || ' TO ' || d.GRANTEE || ';'

             END priv,

             'DBA_SYS_PRIVS'

        FROM dba_sys_privs@old d

       WHERE D.GRANTEE = CUR.USERNAME;

  

    INSERT INTO t_tmp_user_lhr

      (id, username, exec_sql, create_type)

      SELECT s_t_tmp_user_lhr.nextval,

             cur.username,

             CASE

               WHEN D.ADMIN_OPTION = 'YES' THEN

                'GRANT ' || d.GRANTED_ROLE || ' TO ' || d.GRANTEE ||

                ' WITH GRANT OPTION;'

               ELSE

                'GRANT ' || d.GRANTED_ROLE || ' TO ' || d.GRANTEE || ';'

             END priv,

             'DBA_ROLE_PRIVS'

        FROM DBA_ROLE_PRIVS@old d

       WHERE D.GRANTEE = CUR.USERNAME;

    INSERT INTO t_tmp_user_lhr

      (id, username, exec_sql, create_type)

      SELECT s_t_tmp_user_lhr.nextval,

             cur.username,

             CASE

               WHEN d.grantable = 'YES' THEN

                'GRANT ' || d.privilege || ' ON ' || d.owner || '.' ||

                d.table_name || ' TO ' || d.GRANTEE ||

                ' WITH GRANT OPTION ;'

               ELSE

                'GRANT ' || d.privilege || ' ON ' || d.owner || '.' ||

                d.table_name || ' TO ' || d.GRANTEE || ';'

             END priv,

             'DBA_TAB_PRIVS'

        FROM DBA_TAB_PRIVS@old d

       WHERE D.GRANTEE = CUR.USERNAME;

  end loop;

  COMMIT;

end;

/

 

新生产权限

drop table t_tmp_user_lhr_new;

create table t_tmp_user_lhr_new( id number, username varchar2(50), exec_sql varchar2(4000),create_type varchar2(20));

drop sequence s_t_tmp_user_lhr_new;

create sequence s_t_tmp_user_lhr_new;

 

begin

  for cur in (SELECT d.username,

                     d.default_tablespace,

                     d.account_status,

                     'create user ' || d.username || ' identified by ' ||

                     d.username || ' default tablespace ' ||

                     d.default_tablespace || ' TEMPORARY TABLESPACE ' ||

                     D.temporary_tablespace || ';' CREATE_USER,

                     replace(to_char(DBMS_METADATA.GET_DDL('USER',

                                                           D.username)),

                             chr(10),

                             '') create_USER1

                FROM dba_users d

               WHERE d.username in ('DXY')) loop

    INSERT INTO t_tmp_user_lhr_new

      (id, username, exec_sql, create_type)

    values

      (s_t_tmp_user_lhr_new.nextval, cur.username, cur.CREATE_USER, 'USER');

    INSERT INTO t_tmp_user_lhr_new

      (id, username, exec_sql, create_type)

      SELECT s_t_tmp_user_lhr_new.nextval,

             cur.username,

             CASE

               WHEN D.ADMIN_OPTION = 'YES' THEN

                'GRANT ' || d.privilege || ' TO ' || d.GRANTEE ||

                ' WITH GRANT OPTION ;'

               ELSE

                'GRANT ' || d.privilege || ' TO ' || d.GRANTEE || ';'

             END priv,

             'DBA_SYS_PRIVS'

        FROM dba_sys_privs d

       WHERE D.GRANTEE = CUR.USERNAME;

    INSERT INTO t_tmp_user_lhr_new

      (id, username, exec_sql, create_type)

      SELECT s_t_tmp_user_lhr_new.nextval,

             cur.username,

             CASE

               WHEN D.ADMIN_OPTION = 'YES' THEN

                'GRANT ' || d.GRANTED_ROLE || ' TO ' || d.GRANTEE ||

                ' WITH GRANT OPTION;'

               ELSE

                'GRANT ' || d.GRANTED_ROLE || ' TO ' || d.GRANTEE || ';'

             END priv,

             'DBA_ROLE_PRIVS'

        FROM DBA_ROLE_PRIVS d

       WHERE D.GRANTEE = CUR.USERNAME;

    INSERT INTO t_tmp_user_lhr_new

      (id, username, exec_sql, create_type)

      SELECT s_t_tmp_user_lhr_new.nextval,

             cur.username,

             CASE

               WHEN d.grantable = 'YES' THEN

                'GRANT ' || d.privilege || ' ON ' || d.owner || '.' ||

                d.table_name || ' TO ' || d.GRANTEE ||

                ' WITH GRANT OPTION ;'

               ELSE

                'GRANT ' || d.privilege || ' ON ' || d.owner || '.' ||

                d.table_name || ' TO ' || d.GRANTEE || ';'

             END priv,

             'DBA_TAB_PRIVS'

        FROM DBA_TAB_PRIVS d

       WHERE D.GRANTEE = CUR.USERNAME;

  end loop;

  COMMIT;

end;

/

 

老环境的权限减去新环境的,产生的结果是新库缺少的权限,将结果赋予新环境

SELECT EXEC_SQL FROM t_tmp_user_lhr where CREATE_TYPE not in ('USER')

minus

SELECT EXEC_SQL FROM t_tmp_user_lhr_new where CREATE_TYPE not in ('USER');

 

比对慢或者失败的表

比对veridata 比对过慢以及比对失败的表的记录总数

具体根据veridata 比对结果。提前准备好脚本,例如

vi /home/oracle/mc_scripts/table_count.sql

 

set serveroutput on;

declare

  v_tablename varchar2(60);

  v_count     int;

  v_sql       varchar2(2000);

  cursor cur_tablename is

    select table_name

      from dba_tables

     where table_name in (' DXY_TEMP')

       and owner = ' DXY' order by table_name;

begin

  open cur_tablename;

  loop

    fetch cur_tablename

      into v_tablename;

    exit when cur_tablename%notfound;

    v_sql := 'select count(*) from DXY.' || v_tablename || '';

    execute immediate v_sql

      into v_count;

    dbms_output.put_line(v_tablename || ':' || v_count);

  end loop;

  close cur_tablename;

end;

/

 

set serveroutput off;

 

重导部分对象

排除的表

若存在OGG 不支持同步的表,则需要重新导入。

sysdate+0) NEXT (SYSDATE + 3600/86400);

 

@?/rdbms/admin/utlrp.sql

 

修改数据库 IP 地址

老生产库调整

注意备份,方便回退

6.3.1.1 停止双节点服务

停止两边节点数据库,监听 , 并且停止  crs

srvctl stop database -d kobra

srvctl stop asm -n zclcrac1

srvctl stop asm -n zclcrac2

srvctl stop nodeapps -n zclcrac1

srvctl stop nodeapps -n zclcrac2

 

双节点关停集群:

#crsctl stop crs

确认集群完全停止

 

6.3.1.2 修改双节点 /etc/hosts 文件

修改前:

10.0.18.8  zclcrac1

10.0.18.9  zclcrac2

10.0.18.10  zclcrac1-vip

10.0.18.11  zclcrac2-vip

10.0.18.12  zclcrac-scan

 

修改后:

10.0.105.3  zclcrac1

10.0.105.4  zclcrac2

10.0.105.5  zclcrac1-vip

10.0.105.6  zclcrac2-vip

10.0.105.7      zclcrac-scan

 

6.3.1.3public IP 修改

root 用户修改 bond0 文件:

#cd /etc/sysconfig/network-scripts/

#vi ifcfg-bond0

DEVICE=bond0

NM_CONTROLLED=no

>

IPADDR=10.0.105.3

BOOTPROTO=static

NETMASK=255.255.255.0

GATEWAY=10.0.105.254

DNS1=10.0.8.3( DNS 需确认是否要修改 )

IPV6INIT=no

USERCTL=no

PREFIX=24

DEFROUTE=yes

IPV4_FAILURE_FATAL=yes

NAME="System bond0"

 

二节点一样修改:

将10.0.18.9改成10.0.105.4
重启双节点网络服务:
#service network restart
 

双节点启动CRS,修改共享盘中信息:(该操作在一个节点上完成)
grid用户切换到root用户(带环境变量)
#启动双节点CRS:
#crsctl start crs
Root用户修改共享盘网络配置:
#oifcfg getif

bond0  10.0.18.0  global  public 

bond1  195.195.195.0  global  cluster_interconnect
 

修改

# 查看当前配置:

#oifcfg iflist

bond0 10.0.105.0

bond1 195.195.195.0

删除并添加

#oifcfg delif -global bond0 

#oifcfg setif -global bond0/10.0.105.0:public
双节点确认:

./oifcfg getif 

bond0  10.0.105.0  global  public 

bond1  195.195.195.0  global  cluster_interconnect

 

6.3.1.4 修改 VIP

关闭数据库:

srvctl stop database -d kobra

检查 vip 配置: (类似以下输出)

$ srvctl config vip -n zclcrac1 

VIP exists.: zclcrac1

VIP exists.: / zclcrac1-vip/10.0.18.10/255.255.255.0/bond0

 

$ srvctl config vip -n zclcrac2

VIP exists.: zclcrac2

VIP exists.: / zclcrac2-vip/10.0.18.11/255.255.255.0/ bond0

 

停止  vip  服务和修改  vip

$srvctl stop listener -n zclcrac1 

$srvctl stop listener -n zclcrac2 

$srvctl stop vip -n zclcrac1

$srvctl stop vip -n zclcrac2

#srvctl modify nodeapps -n zclcrac1 -A 10.0.105.5/255.255.255.0/bond0 

#srvctl modify nodeapps -n zclcrac2 -A 10.0.105.6/255.255.255.0/bond0

 

确认是否修改成功:

srvctl config vip -n zclcrac1

srvctl config vip -n zclcrac2

 

启动  vip  服务 , 监听,数据库

 

srvctl start vip -n zclcrac1

srvctl start vip -n zclcrac2 

srvctl start listener -n zclcrac1 

srvctl start listener -n zclcrac2 

srvctl start database  d kobra

 

双节点修改 local_listener  参数

alter system set local_listener='(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=10.0.105.5)(PORT=1521))))' scope=both sid='kobra1';

alter system set local_listener='(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=10.0.105.6)(PORT=1521))))' scope=both sid='kobra2';

 

6.2.1.5 修改 SCAN IP

srvctl config scan  查看当前  vip  设置

#./srvctl config scan 

SCAN name:  zclcrac-scanNetwork: 1/10.0.18.0/255.255.255.0/bond0 

SCAN VIP name: scan1, IP:  /scan-vip/10.0.18.12

 

停止  scan_listener   sacn vip

$srvctl stop scan_listener 

$srvctl stop scan 

$srvctl status scan 

SCAN VIP scan1 is enabled 

SCAN VIP scan1 is not running  

$srvctl status scan_listener 

SCAN Listener LISTENER_SCAN1 is enabled 

SCAN listener LISTENER_SCAN1 is not running

 

 root  用户修改  scan vip

#srvctl modify scan  n zclcrac-scan

 

检查 scanip 修改:

srvctl config scan

 

启动  scan   scan_listener 

srvctl start scan 

srvctl start scan_listener

 

新生产库调整

步骤与老生产库一致,注意备份,方便回退

  业务测试

由业务层面进行

  回退方案

配置OGG 反向同步。

ggsci> add extract bk_ext, tranlog, threads 2, begin now

ggsci> add exttrail ./dirdat/bk extract bk_ext

ggsci> edit param bk_ext

 

extract bk_ext

setenv (NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK")

userid odc,password odc

exttrail ./dirdat/bk

discardfile ./dirrpt/bk.dsc, append megabytes 100

discardrollover on sunday

tranlogoptions dblogreader

FETCHOPTIONS FETCHPKUPDATECOLS

ddl include objname ADT.* exclude objtype 'TRIGGER' &

include objname AIB.* exclude objtype 'TRIGGER' &

include objname BEHAVIORLOG.* exclude objtype 'TRIGGER'

ddloptions addtrandata

table ADT.*;

table AIB.*;

table BEHAVIORLOG.*;

 

只挖掘,不应用。确保挖掘正常后,可以开始正式业务。

 

修改数据库IP

 

 

 

  注意事项

1、   His 应用程序更换数据库平台需要his 厂商业务支持改造,确认his 厂商是否可以由sqlserver 数据库改造成oracle 数据库。光数据迁移到oracle 数据库his 应用将无法使用。面临这类问题一般有两种解决方案:1 his 厂商支持oracle 数据库,可以付费改造应用;2 、更换his 厂商。

两种数据库类型相差较大。故存在对象无法创建或者字段不支持的情况。