Top Banner
CSDN 社区电子杂志——Oracle 杂志》 http://emag.csdn.net 2005 5 4 总第 4 - 1 -
70

Csdn Emag(Oracle)第四期

Nov 12, 2014

Download

Documents

yiditushe

 
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 1 -

Page 2: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

目录

目录 ........................................................................................................................................................- 2 -

数据库实战 ..........................................................................................................................................- 4 -

利用errorstack event解决问题 .............................................................................................................- 4 -

数据库开发 ..........................................................................................................................................- 8 -

Oracle外部例程......................................................................................................................................- 8 -

1.1. 必要性 .................................................................................................................................- 8 -

1.2. 基本原理 .............................................................................................................................- 9 -

1.3. 使用配置 .............................................................................................................................- 9 -

1.4. 使用COM对象说明 .......................................................................................................... - 11 -

1.5. 操作Excel示例 ..................................................................................................................- 13 -

1.6. 小结 ...................................................................................................................................- 21 -

数据库复制 ........................................................................................................................................- 23 -

最简单的创建只读实体化视图站点的方法 .......................................................................................- 23 -

1.1. 主站点上创建实体化视图日志表....................................................................................- 23 -

1.2. 实体化视图站点上创建公用数据库链接........................................................................- 23 -

1.3. 实体化视图站点上创建刷新组,本例中 3 分钟刷新一次............................................- 23 -

1.4. 实体化视图站点上创建用户私有数据库链接................................................................- 24 -

1.5. 实体化视图站点上创建实体化视图................................................................................- 24 -

1.6. 实体化视图站点上将创建的视图加入刷新组................................................................- 24 -

1.7. 测试 ...................................................................................................................................- 24 -

1.8. 总结 ...................................................................................................................................- 24 -

1.9. 附录 ...................................................................................................................................- 25 -

Oracle高级复制冲突解决机制的研究................................................................................................- 27 -

数据库高可用性 ...............................................................................................................................- 37 -

SharePlex for Oracle ...........................................................................................................................- 37 -

1.1. 前言 ...................................................................................................................................- 37 -

1.2. 高可用容灾方案设计 .......................................................................................................- 37 -

2005 年 5 月 4 期 总第 4 期

- 2 -

Page 3: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

1.3. SharePlex for Oracle介绍 ..................................................................................................- 42 -

1.4. 容灾系统建立 ...................................................................................................................- 47 -

1.5. 关于Quest Software...........................................................................................................- 53 -

1.6. SharePlex for Oracle部分成功案例 ..................................................................................- 53 -

博文精品图书连载...........................................................................................................................- 55 -

《Oracle JDeveloper 10g 与 J2EE实践演练》 ...............................................................................- 55 -

1.1. J2EE 应用程序模型简介 .................................................................................................- 55 -

1.2. Oracle 应用程序开发框架(ADF) ...............................................................................- 56 -

1.3. Oracle JDeveloper 10g 功能概览.....................................................................................- 58 -

1.4. 结语 ...................................................................................................................................- 67 -

1.5. 本书相关资源 ...................................................................................................................- 67 -

关于CSDN..........................................................................................................................................- 69 -

2005 年 5 月 4 期 总第 4 期

- 3 -

Page 4: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

数据库实战

利用 errorstack event 解决问题

本文作者: Kamus ([email protected] )

摘要:在任何一种解决问题之前,必须要先知道问题的原因,才可以作到有的放矢。解决问

题的方法并不是很难找,难能可贵的是能够及时准确地定位问题。本文介绍一种利用 trace event

来定位问题所在的方法。

某天现场人员报告说 exp 的时候报权限不足的错误。

是用当前用户作的用户级别的 exp,按理说应该没有什么权限的问题。

按照现场的情况作了测试,果然重现了问题。

d:\Temp>exp parfile=exp.par

Export: Release 9.2.0.5.0 - Production on Tue Dec 21 22:27:13 2004

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

EXP-00008: ORACLE error 1031 encountered

ORA-01031: insufficient privileges

EXP-00000: Export terminated unsuccessfully

其中 exp.par 的内容如下:

userid=scott/tiger

file=.\scott.dmp

indexes=y

grants=y

rows=y

constraints=y

owner=scott

direct=n

2005 年 5 月 4 期 总第 4 期

- 4 -

Page 5: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 5 -

compress=n

feedback=10000

resumable=y

resumable_timeout=7200

log=.\export.log

没有发现什么问题,那么作一个 trace 吧,于是决定使用 errorstack event,由于 exp 是在命令行中

直接执行的,所以只能对整个数据库系统作 trace,由于只是想知道 ORA-01031 错误的发生原因,

所以用以下语句:

alter system set events '1031 trace name errorstack level 3';

如果想捕获什么错误,就直接用错误号作 trace,此处我们想获知 ORA-01031 的错误原因,

所以使用了’1031 trace name errorstack level 3’。

然后重新运行 exp,仍然报错,这时候在 udump 目录中生成了 trace 文件,检查文件内容,发现:

*** SESSION ID:(15.210) 2004-12-21 22:22:36.704

*** 2004-12-21 22:22:36.704

ksedmp: internal or fatal error

ORA-01031: insufficient privileges

Current SQL statement for this session:

ALTER SESSION ENABLE RESUMABLE TIMEOUT 7200

原来问题出在 ENABLE RESUMABLE 部分,这是 9i 的新特性,用于在出现空间不足的问题时,

挂起整个操作以等待操作人员解决空间问题。

只要确认了问题所在,就很好解决了,其实如果详细地看过 adminitrator 文档,也就不会犯这个错

误,文档里面 Enabling and Disabling Resumable Space Allocation 部分很清楚地写着:如果要使用

resumbale 特性,那么必须有 resumable 系统权限。

检查现场用户的权限,发现只有 connect 和 resource 权限。于是:

grant resumable to username;

当然如果象一些应用里面那样,用户始终是具有 DBA 角色的话,那么永远也不会发生这个错误,

因为 DBA 角色本来就具有 esumable 系统权限。不过为了安全起见,我们的应用中用户都不会具有

Page 6: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

DBA 权限。

解决问题的方法很简单,没什么好说的,本文想介绍的也是发现问题的手段,也就是利用

set events 的方法。这个方法在我们对一个错误感到莫名其妙的时候往往会成为指路明

灯。

作为本文的补充,提供几个常见的用于 Troubleshooting 或者 Tuning 或者 Interal 研究的 Oracle

Events。

10032事件:用于 dump 排序操作的统计值,Level 10 是最详细的级别。

ALTER SESSION SET EVENTS '10032 trace name context forever, level 10';

10046 事件:用于跟踪 SQL 执行过程,这是我们在调整一个 SQL 时比较常见的方法。Level 12

是最详细的级别。

ALTER SESSION SET EVENTS '10046 trace name context forever, level 12';

其中各个 Level 的含义:

1:显示 SQL 语句,执行计划和执行统计值

4:显示级别 1 的内容和绑定变量

8:显示级别 1 的那同和等待事件统计

12:显示级别 1 的内容和绑定变量、等待事件统计

10053 事件:当 Oracle 使用 CBO 进行执行计划的生成时,可以使用这个事件对于执行计划的生

成过程进行跟踪。

ALTER SESSION SET EVENTS '10053 trace name context forever, level 1';

10081事件:用于跟踪 HWM(高水位标志)的变更

ALTER SESSION SET EVENTS '10081 trace name context forever, level 1';

2005 年 5 月 4 期 总第 4 期

- 6 -

Page 7: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

作者简介: 张乐奕,网名 kamus

曾任 ITPUB Oracle认证版版主,现任 itpub Oracle管理版版主。

现任职于北京某大型软件公司,首席DBA,主要负责证券行业的全国十数处核心交易系统数据库管

理及维护工作。

热切关注Oracle技术和其它相关技术,出没于各大数据库技术论坛,目前是中国最大的Oracle技

术论坛www.itpub.net的数据库管理版版主。

阅读更多技术文章和随笔可以登录我的个人blog。

http://blog.dbform.com。

2005 年 5 月 4 期 总第 4 期

- 7 -

Page 8: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

数据库开发

Oracle 外部例程

—— PL/SQL 操作 COM 对象

本文作者: chanet ([email protected] )

PL/SQL 是由 Oracle 公司对标准 SQL 进行扩展,专用于 Oracle 数据库中程序设计的专用语言,

属第三代过程式程序设计语言。从 Oracle8 开始提供了直接从 PL/SQL 中调用外部 C 语言过程,允

许开发人员用 PL/SQL 进行使用 C 语言编制的程序模块。从 Oracle8i 开始,又引入了 Java 程序。

在本文中主要介绍外部例程的基本原理以及使用条件,介绍如何通过引用外部例程来操作

Windows 中的 COM 对象,并做了一个操作 Excel 对象的示例。

本文的运行环境全部建立在 Oracle9i 和 Windows2000。其中 ORACLE 的安装目录

(ORACLE_HOME)为 D:\oracle\ora92,SID 为 ORADB,主机名为 CHANET。

1.1. 必要性

扩展后的 PL/SQL 语言已经集成了标准 SQL,在效率和安全上非常适合设计 Oracle 数据库程

序,但对于应用的某些功能,其它的程序设计语言比 PL/SQL 更适合,如:使用操作系统资源,C

语言在计算和引用系统对象及使用设备上优于 PL/SQL,而 Java 语言在网络上的应用优于 PL/SQL。

如果在应用上要用到不适合用 PL/SQL 语言的话,这时就要使用其它语言进行编制,然后由 PL/SQL

作为外部例程进行调用。

在 Oracle8 之前的版本,PL/SQL 和其它语言的唯一通信是借助于 DBMS_PIPE 和

DBMS_ALERT 包来实现,在使用之前必需建立一个 OCI 接口或预编译器编制的监护程序,使用

比较复杂。外部例程的出现,只需在 PL/SQL 中建立一个函数映射到外部例程对应的函数,就像普

通的 PL/SQL 函数使用一样,简化了使用过程。

2005 年 5 月 4 期 总第 4 期

- 8 -

Page 9: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

1.2. 基本原理

当引用外部 C 语言例程时,Oracle 监听器将启动 extproc 进程,该进程将会动态地载入共享库

(在 Windows 下称为动态链接库,即是 DLL 文件),进程起了一个缓冲的作用,当 PL/SQL 过程

调用外部函数时,进程把命令发送到共享库,之后把结果返回给 PL/SQL 过程。

进程被调用后随着共享库的使用会话(session)而存在,如果调用完毕或者关闭数据库用户会话,

extproc 进程会自动关闭。

如下图 1-1 为调用外部例程的描述。

图 1-1 监听器与 extproc 进程

1.3. 使用配置

在调用外部例程之前,必需进行如下设置:

配置监听器。 配置 Net 组件服务。

配置监听器,打开 D:\oracle\ora92\network\admin\listener.ora 文件,修改文件参数。

LISTENER =

(DESCRIPTION_LIST =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = CHANET)(PORT = 1521))

)

(ADDRESS_LIST =

2005 年 5 月 4 期 总第 4 期

- 9 -

Page 10: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 10 -

(ADDRESS = (PROTOCOL = IPC)(KEY = extproc1))

)

)

)

SID_LIST_LISTENER =

(SID_LIST =

(SID_DESC =

(SID_NAME = PLSExtProc)

(ORACLE_HOME = D:\oracle\ora92)

(PROGRAM = extproc)

)

(SID_DESC =

(GLOBAL_DBNAME = ORADB)

(ORACLE_HOME = D:\oracle\ora92)

(SID_NAME = ORADB)

)

)

其中有两部份参数对于使用外部例程是很重要的。

(ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)(KEY = extproc1))

设置基于 IPC 协议的外部例程

(SID_DESC =(SID_NAME = PLSExtProc) (ORACLE_HOME = D:\oracle\ora92) (PROGRAM = extproc) )

记录数据库的相关属性,SID_NAME 在默认的情况下是 PLSExtproc。

配置 Net 组件服务,打开 D:\oracle\ora92\network\admin\tnsnames.ora 文件,把如下内容保存在

该文件里。

EXTPROC_CONNECTION_DATA =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))

)

(CONNECT_DATA =

(SID = PLSExtProc)

(PRESENTATION = RO)

)

)

重要参数说明:

(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1)) (CONNECT_DATA = (SID = PLSExtProc) (PRESENTATION = RO)

两设置必需与 listener.ora 里的一致。

重启监听器,并测试服务是否可用。

Page 11: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

停止监听器:lsnrctl stop

启动监听器:lsnrctl start

测试服务是否可用:

C:\>tnsping EXTPROC_CONNECTION_DATA

TNS Ping Utility for 32-bit Windows: Version 9.2.0.1.0 - Production on 07-4 月 -2

005 16:57:00

Copyright (c) 1997 Oracle Corporation. All rights reserved.

已使用的参数文件:

D:\oracle\ora92\network\admin\sqlnet.ora

已使用 TNSNAMES 适配器来解析别名

Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)

(KEY = EXTPROC1))) (CONNECT_DATA = (SID = PLSExtProc) (PRESENTATION = RO)))

OK(30 毫秒)

测试 extproc 进程是否正常:

D:\oracle\ora92\bin>extproc

Oracle Corporation --- 星期四 4 月 07 2005 17:37:18.968

Heterogeneous Agent Release 9.2.0.1.0 - Production

1.4. 使用 COM 对象说明

COM 对象设计都会提供了三个基本操作给开发人员使用,分别为:获取属性值,设置属性值

(只读属性除外),调用方法。Oracle 数据库在 Windows 的平台下提供了操作 COM 对象的接口,

属于 C 语言外部例程模式。

工作原理如下图:

2005 年 5 月 4 期 总第 4 期

- 11 -

Page 12: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

图 1-2 操作 COM 对象工作原理

在使用该功能之前,需明白如下内容:

1、创建 COM 对象操作函数。

SQL> CONNECT SYSTEM/chanet@oradb

SQL> CREATE USER chanet identified by chanet;

SQL> GRANT CREATE LIBRARY TO chanet;

SQL> CONNECT chanet/chanet@oradb;

SQL> @D:\oracle\ora92\com\comwrap.sql;

2、配置监听器。

在 listener.ora 文件里,添加如下内容,并重启监听器。

STARTUP_WAIT_TIME_LISTENER = 0

CONNECT_TIMEOUT_LISTENER = 10

TRACE_LEVEL_LISTENER = off

PASSWORDS_LINTENER = (oracle)

3、PL/SQL 数据类型与对应的 COM 对象类型。

表 1-1 数据类型比较

PL/SQL 数据类型 COM API 数据类型

VARCHAR2 BSTR BOOLEAN BOOL BINARY_INTEGER BYTE,INT,LONG DOUBLE PRECISION DOUBLE,FLOAT,CURRENCY DATE DATE

4、函数说明。

表 1-2 函数说明

名称 功能描述 CreateObject 创建对象 DestroyObject 关闭对象 GetLastError 获取错误信息

2005 年 5 月 4 期 总第 4 期

- 12 -

Page 13: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

GetProperty 获取属性值 SetProperty 设置属性值

InitArg 为 Invoke 函数初始化参数 InitOutArg 为 GetArg 初始化输出参数 GetArg 获取输出参数 SetArg 为 Invoke 函数设置参数

Invoke 调用 COM 对象的函数或过程

1.5. 操作 Excel 示例

本节介绍如何操作 COM 对象(以 Excel 对象为例),将数据库里的表记录通过 PL/SQL 语句输

出成 Excel 文件。通过对象浏览器可以查看 Excel 对象提供的属性和方法。(如:在 Excel 菜单,工

具 -> 宏 -> 打开 Visual Basic 编辑器,在编辑器里,视图 -> 对象浏览器)。

使用 Excel 对象一般针对单元格进行操作(如,设置第一个单元格字体大小的代码为:

Range("A1").Font.Size = 20)。对应的 COM 外部例程操作的步骤为:1、获取程序句柄;2、获取工

作簿句柄;3、获取工作表句柄;4、获取 Range 区句柄;5、获取 Font 类句柄;6、设置 Size 属性。

如下为操作 Excel 对象的例子,首先建立示例表,然后建立操作包(package),最后是使用包

函数的过程(procedure)。创建一个测试用表:

-- 销售表(脚本)

CREATE TABLE IT_SALE_TAB(ITS_ID VARCHAR2(5),ITS_DATE DATE,ITS_TOTAL NUMBER);

INSERT INTO IT_SALE_TAB(ITS_ID,ITS_DATE,ITS_TOTAL)

VALUES('1',TO_DATE('2004-01-01','YYYY-MM-DD'),250);

INSERT INTO IT_SALE_TAB(ITS_ID,ITS_DATE,ITS_TOTAL)

VALUES('2',TO_DATE('2004-02-01','YYYY-MM-DD'),150);

INSERT INTO IT_SALE_TAB(ITS_ID,ITS_DATE,ITS_TOTAL)

VALUES('3',TO_DATE('2004-03-01','YYYY-MM-DD'),80);

INSERT INTO IT_SALE_TAB(ITS_ID,ITS_DATE,ITS_TOTAL)

VALUES('4',TO_DATE('2004-04-01','YYYY-MM-DD'),96);

INSERT INTO IT_SALE_TAB(ITS_ID,ITS_DATE,ITS_TOTAL)

VALUES('5',TO_DATE('2004-05-01','YYYY-MM-DD'),300);

INSERT INTO IT_SALE_TAB(ITS_ID,ITS_DATE,ITS_TOTAL)

VALUES('6',TO_DATE('2004-06-01','YYYY-MM-DD'),210);

INSERT INTO IT_SALE_TAB(ITS_ID,ITS_DATE,ITS_TOTAL)

VALUES('7',TO_DATE('2004-07-01','YYYY-MM-DD'),320);

INSERT INTO IT_SALE_TAB(ITS_ID,ITS_DATE,ITS_TOTAL)

VALUES('8',TO_DATE('2004-08-01','YYYY-MM-DD'),280);

2005 年 5 月 4 期 总第 4 期

- 13 -

Page 14: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 14 -

INSERT INTO IT_SALE_TAB(ITS_ID,ITS_DATE,ITS_TOTAL)

VALUES('9',TO_DATE('2004-09-01','YYYY-MM-DD'),276);

INSERT INTO IT_SALE_TAB(ITS_ID,ITS_DATE,ITS_TOTAL)

VALUES('10',TO_DATE('2004-10-01','YYYY-MM-DD'),368);

INSERT INTO IT_SALE_TAB(ITS_ID,ITS_DATE,ITS_TOTAL)

VALUES('11',TO_DATE('2004-11-01','YYYY-MM-DD'),163);

INSERT INTO IT_SALE_TAB(ITS_ID,ITS_DATE,ITS_TOTAL)

VALUES('12',TO_DATE('2004-12-01','YYYY-MM-DD'),305);

COMMIT;

操作 Excel 对象包(Package)。

CREATE OR REPLACE PACKAGE oraExcel IS

xlThin BINARY_INTEGER DEFAULT 2;

DummyToken BINARY_INTEGER;

applicationToken BINARY_INTEGER:=-1; -- Excel对象句柄

WorkBooksToken BINARY_INTEGER:=-1; -- 工作簿句柄

WorkBookToken BINARY_INTEGER:=-1;

WorkSheetToken BINARY_INTEGER:=-1; -- 工作表句柄

WorkSheetToken1 BINARY_INTEGER:=-1;

RangeToken BINARY_INTEGER:=-1; -- Range区句柄

ChartObjectToken BINARY_INTEGER:=-1; -- 图表对象句柄

ChartObject1 BINARY_INTEGER:=-1;

Chart1Token BINARY_INTEGER:=-1;

hLines BINARY_INTEGER:=-1;

i BINARY_INTEGER;

err_src VARCHAR2(255);

err_desc VARCHAR2(255);

err_hpf VARCHAR2(255);

err_hpID BINARY_INTEGER;

-- 创建 Excel 对象

FUNCTION CreateExcelWorkSheet(servername VARCHAR2) RETURN BINARY_INTEGER;

-- 插入数据(字符型)

FUNCTION setCellValues(RANGE VARCHAR2,data VARCHAR2,TYPE VARCHAR2)

RETURN BINARY_INTEGER;

-- 插入数据(日期型)

FUNCTION setCellValues(RANGE VARCHAR2,data DATE,TYPE VARCHAR2)

RETURN BINARY_INTEGER;

-- 插入数据(整型)

FUNCTION setCellValues(RANGE VARCHAR2,data BINARY_INTEGER,TYPE VARCHAR2)

RETURN BINARY_INTEGER;

-- 插入数据(实型)

FUNCTION setCellValuesReal(RANGE VARCHAR2,data DOUBLE PRECISION,TYPE VARCHAR2)

Page 15: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 15 -

RETURN BINARY_INTEGER;

-- 设置列宽

FUNCTION setCellColWidth(RANGE VARCHAR2,width DOUBLE PRECISION,TYPE VARCHAR2) RETURN

BINARY_INTEGER;

-- 设置表格

FUNCTION setCellLines(RANGE VARCHAR2,BordersIndex BINARY_INTEGER,weight

BINARY_INTEGER DEFAULT xlThin,TYPE VARCHAR2) RETURN BINARY_INTEGER;

-- 合并单元格

FUNCTION setCellMerge(RANGE VARCHAR2,bValues BOOLEAN,TYPE VARCHAR2)

RETURN BINARY_INTEGER;

-- 设置字体属性

FUNCTION setCellFont(RANGE VARCHAR2,Property VARCHAR2,

fontValues BINARY_INTEGER,TYPE VARCHAR2) RETURN BINARY_INTEGER;

-- 调用方法

FUNCTION callMethod(RANGE VARCHAR2,MethodName VARCHAR2) RETURN BINARY_INTEGER;

-- 插入图表

FUNCTION InsertChart(xpos BINARY_INTEGER,ypos BINARY_INTEGER,

width BINARY_INTEGER,height BINARY_INTEGER,

RANGE VARCHAR2,TYPE VARCHAR2) RETURN BINARY_INTEGER;

-- 保存文件

FUNCTION SaveToFile(filename VARCHAR2) RETURN BINARY_INTEGER;

-- 关闭 Excel对象

FUNCTION CloseExcel RETURN BINARY_INTEGER;

END oraExcel;

数据包体内容(PACKAGE BODY)

CREATE OR REPLACE PACKAGE BODY oraExcel IS

FUNCTION CreateExcelWorkSheet(servername VARCHAR2) RETURN BINARY_INTEGER IS

BEGIN

-- 创建 Excel对象

i:=ordcom.CreateObject('Excel.Application', 0, servername,applicationToken);

IF (i!=0) THEN -- 创建失败,提示返回的错误信息

ordcom.GetLastError(err_src, err_desc, err_hpf, err_hpID);

raise_application_error(-20000,err_src || err_desc || err_hpf || err_hpID);

END IF;

-- 通过程序对象句柄获取工作簿句柄

i:=ordcom.GetProperty(applicationToken, 'WorkBooks', 0, WorkBooksToken);

ordcom.InitArg();

ordcom.SetArg(-4167,'I4');

i:=ordcom.Invoke(WorkBooksToken, 'Add', 1, WorkBookToken);

ordcom.InitArg();

ordcom.SetArg('Sheet 1','BSTR');

Page 16: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 16 -

-- 获取工作表句柄

i:=ordcom.GetProperty(applicationToken, 'WorkSheets', 0, WorkSheetToken1);

i:=ordcom.Invoke(WorkSheetToken1, 'Add', 0, WorkSheetToken);

RETURN i;

END CreateExcelWorkSheet;

FUNCTION setCellValues(RANGE VARCHAR2,data VARCHAR2, TYPE VARCHAR2)

RETURN BINARY_INTEGER IS

BEGIN

ordcom.InitArg();

ordcom.SetArg(RANGE,'BSTR');

-- 获取 Range区句柄,之后将数据写入到指定的单元格

i:=ordcom.GetProperty(WorkSheetToken, 'Range', 1, RangeToken);

i:=ordcom.SetProperty(RangeToken, 'Value', data, TYPE);

i:=ordcom.DestroyObject(RangeToken);

RETURN i;

END setCellValues;

FUNCTION setCellValues(RANGE VARCHAR2,data BINARY_INTEGER,TYPE VARCHAR2)

RETURN BINARY_INTEGER IS

BEGIN

ordcom.InitArg();

ordcom.SetArg(RANGE, 'BSTR');

i:=ordcom.GetProperty(WorkSheetToken, 'Range', 1, RangeToken);

i:=ordcom.SetProperty(RangeToken, 'Value', data, type);

i:=ordcom.DestroyObject(RangeToken);

RETURN i;

END setCellValues;

FUNCTION setCellValuesReal(RANGE VARCHAR2,data DOUBLE PRECISION,TYPE VARCHAR2)

RETURN BINARY_INTEGER IS

BEGIN

ordcom.InitArg();

ordcom.SetArg(RANGE, 'BSTR');

i:=ordcom.GetProperty(WorkSheetToken, 'Range', 1, RangeToken);

i:=ordcom.SetProperty(RangeToken, 'Value', data, type);

i:=ordcom.DestroyObject(RangeToken);

RETURN i;

END setCellValuesReal;

FUNCTION setCellValues(RANGE VARCHAR2,data DATE,TYPE VARCHAR2)

RETURN BINARY_INTEGER IS

BEGIN

ordcom.InitArg();

ordcom.SetArg(RANGE, 'BSTR');

i:=ordcom.GetProperty(WorkSheetToken, 'Range', 1, RangeToken);

i:=ordcom.SetProperty(RangeToken, 'Value', data, TYPE);

i:=ordcom.DestroyObject(RangeToken);

Page 17: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 17 -

RETURN i;

END setCellValues;

FUNCTION setCellColWidth(RANGE VARCHAR2,width DOUBLE PRECISION,TYPE VARCHAR2)

RETURN BINARY_INTEGER IS

BEGIN

ordcom.InitArg();

ordcom.SetArg(RANGE,'BSTR');

i:=ordcom.GetProperty(WorkSheetToken,'Range',1,RangeToken);

i:=ordcom.SetProperty(RangeToken,'ColumnWidth',width,TYPE);

i:=ordcom.DestroyObject(RangeToken);

RETURN i;

END setCellColWidth;

FUNCTION setCellMerge(RANGE VARCHAR2,bValues BOOLEAN,TYPE VARCHAR2)

RETURN BINARY_INTEGER IS

BEGIN

ordcom.InitArg();

ordcom.SetArg(RANGE,'BSTR');

i:=ordcom.GetProperty(WorkSheetToken,'Range',1,RangeToken);

i:=ordcom.SetProperty(RangeToken,'MergeCells',bValues,'BOOLEAN');

i:=ordcom.DestroyObject(RangeToken);

RETURN i;

END setCellMerge;

FUNCTION setCellLines(RANGE VARCHAR2,BordersIndex BINARY_INTEGER,

weight BINARY_INTEGER DEFAULT xlThin,TYPE VARCHAR2) RETURN BINARY_INTEGER IS

BEGIN

ordcom.InitArg();

ordcom.SetArg(RANGE,'BSTR');

i:=ordcom.GetProperty(WorkSheetToken,'Range',1,RangeToken);

ordcom.InitArg();

ordcom.SetArg(BordersIndex,TYPE); -- 画表格的具体载入参数

i:=ordcom.GetProperty(RangeToken,'Borders',1,hLines);

i:=ordcom.SetProperty(hLines,'weight',weight,TYPE);

i:=ordcom.DestroyObject(hLines);

i:=ordcom.DestroyObject(RangeToken);

RETURN i;

END setCellLines;

FUNCTION setCellFont(RANGE VARCHAR2,Property VARCHAR2,fontValues BINARY_INTEGER,TYPE

VARCHAR2) RETURN BINARY_INTEGER IS

BEGIN

ordcom.InitArg();

ordcom.SetArg(RANGE,'BSTR');

i:=ordcom.GetProperty(WorkSheetToken,'Range',1,RangeToken);

ordcom.InitArg();

ordcom.SetArg(Property,TYPE);

Page 18: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 18 -

i:=ordcom.GetProperty(RangeToken,'Font',0,hLines); -- 获取字体对象

i:=ordcom.SetProperty(hLines,Property,fontValues,TYPE);

i:=ordcom.DestroyObject(hLines);

i:=ordcom.DestroyObject(RangeToken);

RETURN i;

END;

FUNCTION callMethod(RANGE VARCHAR2,MethodName VARCHAR2) RETURN BINARY_INTEGER IS

reti BINARY_INTEGER := -1;

BEGIN

ordcom.InitArg();

ordcom.SetArg(RANGE,'BSTR');

i:=ordcom.GetProperty(WorkSheetToken,'Range',1,RangeToken);

ordcom.InitArg();

i:=ordcom.Invoke(RangeToken,MethodName,0,reti); -- 调用对象的方法

i:=ordcom.DestroyObject(RangeToken);

RETURN reti;

END;

FUNCTION InsertChart(xpos BINARY_INTEGER, ypos BINARY_INTEGER,

width BINARY_INTEGER, height BINARY_INTEGER,

RANGE VARCHAR2, TYPE VARCHAR2)

RETURN BINARY_INTEGER IS

charttype BINARY_INTEGER:= -4099;

BEGIN

ordcom.InitArg();

i:=ordcom.GetProperty(WorkSheetToken, 'ChartObjects', 0, ChartObjectToken);

ordcom.InitArg();

ordcom.SetArg(xpos,'I2'); -- 载入图表对象位置参数

ordcom.SetArg(ypos,'I2');

ordcom.SetArg(width,'I2');

ordcom.SetArg(height,'I2');

i:=ordcom.Invoke(ChartObjectToken, 'Add', 4, ChartObject1); -- 添加图表

i:=ordcom.GetProperty(ChartObject1, 'Chart', 0,Chart1Token);

ordcom.InitArg();

ordcom.SetArg(RANGE, 'BSTR');

i:=ordcom.GetProperty(WorkSheetToken,'Range', 1, RangeToken); -- 选取区域

ordcom.InitArg();

ordcom.SetArg(RangeToken, 'DISPATCH');

IF TYPE='xlPie' THEN

charttype := -4102;

ELSIF TYPE='xl3DBar' THEN

charttype := -4099;

ELSIF TYPE='xlBar' THEN

charttype := 2;

ELSIF TYPE='xl3dLine' THEN

Page 19: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 19 -

charttype:= -4101;

END IF;

ordcom.SetArg(charttype,'I4');

i:=ordcom.Invoke(Chart1Token,'ChartWizard', 2, DummyToken);

i:=ordcom.DestroyObject(RangeToken);

i:=ordcom.DestroyObject(ChartObjectToken);

i:=ordcom.DestroyObject(ChartObject1);

i:=ordcom.DestroyObject(Chart1Token);

RETURN i;

END InsertChart;

FUNCTION SaveToFile(filename VARCHAR2) RETURN BINARY_INTEGER IS

BEGIN

ordcom.InitArg();

ordcom.SetArg(filename,'BSTR');

i:=ordcom.Invoke(WorkBookToken, 'SaveAs', 1, DummyToken); -- 保存文件

IF (i!=0) THEN

ordcom.GetLastError(err_src, err_desc, err_hpf, err_hpID);

raise_application_error(-20000,err_src || err_desc || err_hpf || err_hpID);

END IF;

RETURN i;

END SaveToFile;

FUNCTION CloseExcel RETURN BINARY_INTEGER IS

BEGIN

ordcom.InitArg();

ordcom.InitArg();

ordcom.SetArg(FALSE,'BOOL');

i:=ordcom.Invoke(WorkBookToken, 'Close', 0, DummyToken);

i:=ordcom.DestroyObject(WorkBookToken);

ordcom.InitArg();

i:=ordcom.Invoke(WorkBooksToken, 'Close', 0, DummyToken);

i:=ordcom.DestroyObject(WorkBooksToken);

i:=ordcom.Invoke(applicationToken, 'Quit', 0, DummyToken);

-- 关闭所有句柄

i:=ordcom.DestroyObject(WorkSheetToken);

i:=ordcom.DestroyObject(WorkSheetToken1);

i:=ordcom.DestroyObject(applicationToken);

i:=ordcom.DestroyObject(ChartObjectToken);

i:=ordcom.DestroyObject(Chart1Token);

i:=ordcom.DestroyObject(hLines);

i:=ordcom.DestroyObject(ChartObject1);

i:=ordcom.DestroyObject(dummyToken);

RETURN i;

END CloseExcel;

END oraExcel;

Page 20: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

成功创建 oraExcel 包后,最后创建使用包的存储过程,实现把数据表里的字符型、日期型和

数值型分别传到 Excel 工作表里,对数值型数据进行统计和使用 Excel 中的图表。该过程具体操作

步骤为:

创建 Excel 对象。

建立表头,设置列宽。

将游标数据传到工作表。

画表格。

设置字体属性。

插入图表。

保存为 Excel 格式文件,关闭 Excel 对象。

如下为 dp_toExcel 存储过程:

CREATE OR REPLACE PROCEDURE dp_ToExcel IS

CURSOR c1 IS SELECT ITS_ID,ITS_DATE,ITS_TOTAL FROM IT_SALE_TAB;

n BINARY_INTEGER:=2;

i BINARY_INTEGER;

filename VARCHAR2(255);

cellIndex VARCHAR2(40);

cellValue VARCHAR2(40);

cellColumn VARCHAR2(10);

returnedTime VARCHAR2(20);

currencyvalue DOUBLE PRECISION;

dateValue DATE;

xlThin BINARY_INTEGER:=2;

xlEdgeLeft BINARY_INTEGER:=7;

xlEdgeTop BINARY_INTEGER:=8;

xlEdgeBottom BINARY_INTEGER:=9;

xlEdgeRight BINARY_INTEGER:=10;

xlInsideVertical BINARY_INTEGER:=11;

xlInsideHorizontal BINARY_INTEGER:=12;

BEGIN

i:=oraExcel.CreateExcelWorkSheet('');

i:=oraExcel.setCellValues('A2', '序号', 'BSTR');

i:=oraExcel.setCellValues('B2', '日期', 'BSTR');

i:=oraExcel.setCellValues('C2', '销售', 'BSTR');

2005 年 5 月 4 期 总第 4 期

- 20 -

Page 21: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 21 -

i:=oraExcel.setCellColWidth('B:B', 12.75,'CY'); -- 设置列宽

i:=oraExcel.setCellColWidth('C:C', 12.75,'CY');

n:=3;

For c1_rec IN c1 LOOP

cellColumn:=TO_CHAR(n);

cellIndex:= 'A'||cellColumn;

cellValue:= TO_CHAR(c1_rec.ITS_ID);

i:=oraExcel.setCellValues(cellIndex, cellValue, 'BSTR');

cellIndex:= 'B' || cellColumn;

dateValue:=c1_rec.ITS_DATE;

i:=oraExcel.setCellValues(cellIndex, dateValue, 'DATE');

cellIndex:= 'C' || cellColumn;

cellValue:=c1_rec.ITS_TOTAL;

currencyValue:=cellValue;

i:=oraExcel.setCellValuesReal(cellIndex, currencyValue, 'CY');

n:=n+1;

END LOOP;

i:=oraExcel.setCellValues('A'||n,'合计','BSTR');

i:=oraExcel.setCellValues('C'||n,'=SUM(C3:C'||to_char(n-1)||')','BSTR');

-- 画表格

i:=oraExcel.setCellLines('A1:C'||n,xlEdgeLeft,xlThin,'I2');

i:=oraExcel.setCellLines('A1:C'||n,xlEdgeTop,xlThin,'I2');

i:=oraExcel.setCellLines('A1:C'||n,xlEdgeBottom,xlThin,'I2');

i:=oraExcel.setCellLines('A1:C'||n,xlEdgeRight,xlThin,'I2');

i:=oraExcel.setCellLines('A1:C'||n,xlInsideVertical,xlThin,'I2');

i:=oraExcel.setCellLines('A1:C'||n,xlInsideHorizontal,xlThin,'I2');

-- 设置字体属性

i:=oraExcel.setCellFont('A1:C1','Size',20,'I2');

i:=oraExcel.setCellFont('A1:C1','Bold',1,'I2');

i:=oraExcel.callMethod('A1:C1','Merge'); -- 合并单元格

i:=oraExcel.setCellValues('A1:C1','合计','BSTR');

-- 插入图表

i:=oraExcel.InsertChart(350,200,250,250,'C3:C'||TO_CHAR(n-1),'xlPie');

SELECT TO_CHAR(SYSDATE, 'HH24MISS') INTO returnedTime FROM dual;

filename:='D:\testExcel' || returnedTime || '.xls';

i:=oraExcel.SaveToFile(filename); -- 保存文件

i:=oraExcel.closeExcel(); -- 关闭对象

END;

1.6. 小结

本文介绍如何从 PL/SQL 中直接调用 C 程序的外部例程,并以操作 Excel 对象为示例。在调用

Page 22: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

该外部例程时,有如下相关的限制:

操作系统必需支持动态链接库(DLL)和共享库功能。 监听器和 extproc 进程必须运行在数据库所在的同一台机子上,不支持远程数据库。 extproc 唯一支持的是 C 例程,但可以通过先调用 C 外部例程去使用其它对象(如:COM

对象)。

除了限制外,调用外部例程会引起额外的系统资源开销,在使用外部例程之前要考虑是否一

定要用到外部例程。

作者简介:

姓名:陈思童

网名:chanet

CSDN社区 Oracle开发版主;

熟悉数据库开发、Oracle数据库接口设计、数据库管理。

个人教育和成长经历:

信息管理专业;大学毕业后一直从事以 Oracle为主的开发工作。

擅长的技术领域:

数据库开发、软件规划、系统分析。

研究方向:

数据库管理、数据仓库、电子商务。

目前的工作动态:

广州某软件公司;负责后台设计、数据库接口技术支持、数据库开发与维护工作。

个人Blog:http://blog.csdn.net/chanet

MSN:[email protected]

E-mail:[email protected] OR [email protected]

2005 年 5 月 4 期 总第 4 期

- 22 -

Page 23: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

数据库复制

最简单的创建只读实体化视图站点的方法

本文作者: Kamus ([email protected] )

摘要:由于支持异构这一特点,Oracle 的高级复制通常被作为一种性价比超群的数据库同步

方案,但是由于 Oracle 高级复制的功能比较强大,所以配置步骤也显得有些麻烦。但是如果我们

的要求比较简单,比如说只有一个数据库用作日常业务,支持数据更新,另外一个数据库只需要

作一个同步的备份,最多支持只读的查询,那么其实只需要非常简单的步骤就可以实现这个目的。

本文给出最简单的步骤用以创建一个实体化视图站点,定时刷新,获取主站点中指定表的变

化,这个实体化站点可以作为查询服务器使用。

完整的配置步骤如下。对于支持数据更新的数据库我们称为主站点,对于同步的数据库我们

称为实体化站点。

1.1. 主站点上创建实体化视图日志表

CREATE MATERIALIZED VIEW LOG ON kamus.account2004;

1.2. 实体化视图站点上创建公用数据库链接

conn system/password

CREATE PUBLIC DATABASE LINK orcl using 'ORCL';

2005 年 5 月 4 期 总第 4 期

- 23 -

1.3. 实体化视图站点上创建刷新组,本例中 3 分钟刷新

一次

conn system/password

BEGIN

Page 24: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 24 -

DBMS_REFRESH.MAKE (

name => 'kamus.test_repg',

list => '',

next_date => SYSDATE,

interval => 'SYSDATE + 3/(24*60)', --此处的刷新时间可以根据需求调整

implicit_destroy => FALSE,

rollback_seg => '',

push_deferred_rpc => TRUE,

refresh_after_errors => FALSE);

END;

/

1.4. 实体化视图站点上创建用户私有数据库链接

conn kamus/password

CREATE DATABASE LINK orcl CONNECT TO kamus IDENTIFIED BY password;

1.5. 实体化视图站点上创建实体化视图

conn kamus/password

CREATE MATERIALIZED VIEW KAMUS.ACCOUNT2004 REFRESH FAST WITH PRIMARY KEY AS SELECT

* FROM KAMUS.ACCOUNT2004@orcl;

1.6. 实体化视图站点上将创建的视图加入刷新组

conn kamus/password

exec DBMS_REFRESH.ADD(name => 'kamus.TEST_REPG', list => 'kamus.ACCOUNT2004', lax

=> TRUE);

1.7. 测试

在主站点中更新 ACCOUNT2004 表,过 3 分钟检查实体化试图站点中的视图,发现更新已经

复制成功。

1.8. 总结

总结一下建立只读实体化视图站点的最简单方法:

Page 25: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

不需要创建其它的任何用户,比如复制环境中需要的传播者,刷新者,接收者等等

不需要创建任何复制组

不需要生成任何复制对象,不需要生成任何对象的复制支持

1.9. 附录

创建实体化视图产生ORA-600 [ksmovrflow], [kkznxddl.begin]错误的解决方法

如果测试环境中的 master site 是 Oracle10g,MV site 是 Oracle9.x 或者 8.1.x,当在 MV site 上创建

快速刷新的实体化视图时,可能会报 ORA-600 错误。

SQL> CREATE MATERIALIZED VIEW KAMUS.ACCOUNT2004 REFRESH FAST WITH PRIMARY KEY AS

SELECT * FROM KAMUS.ACCOUNT2004@orcl;

CREATE MATERIALIZED VIEW KAMUS.ACCOUNT2004 REFRESH FAST WITH PRIMARY KEY AS SELECT

* FROM KAMUS.ACCOUNT2004@orcl

ORA-00600: internal error code, arguments: [ksmovrflow], [kkznxddl.begin], [], [],

[], [], [], []

这是Oracle10g的一个bug(Bug编号:3508674),只有当在Oracle8 或者 9 中创建基于Oracle10g的

实体化视图时才会发生。这个Bug在 10.1.0.3 Server Patch Set中被修复。

原因:

Oracle10g 的 master table 中创建主键时候显式指定了主键的名称。比如执行了类似下面的命令

alter table table_name add constraint < constraint name> primary key (< col>);

解决方法:

删除这个主键,然后创建一个不指定名称的主键,由 Oracle 自动命名,如下:

alter table ACCOUNT2004 add primary key(OCCURTIME, ACCTID, CURRENCYID);

这样产生的主键名称就变成 SYS_CXXXX。之后重新在 MV site 上创建实体化视图即可。

2005 年 5 月 4 期 总第 4 期

- 25 -

Page 26: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

作者简介:

张乐奕,网名 kamus

曾任 ITPUB Oracle认证版版主,现任 itpub Oracle管理版版主。

现任职于北京某大型软件公司,首席DBA,主要负责证券行业的全国十数处核心交易系统数据库管

理及维护工作。

热切关注Oracle技术和其它相关技术,出没于各大数据库技术论坛,目前是中国最大的Oracle技

术论坛www.itpub.net的数据库管理版版主。

阅读更多技术文章和随笔可以登录我的个人blog。

http://blog.dbform.com。

2005 年 5 月 4 期 总第 4 期

- 26 -

Page 27: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

Oracle 高级复制冲突解决机制的研究

—— dbms_rectifier_diff 及手动解决 Oracle 高级复制中的冲突

本文作者: eygle ([email protected] )

摘要:本文简要探讨 dbms_rectifier_diff 包的机制及如何手动解决 Oracle 高级复制中的冲突。

关于 dbms_rectifier_diff 的使用请参考:

http://www.eygle.com/archives/2005/01/eoadbms_rectifi.html

实际上 Oracle 的 dbms_rectifier_diff.DIFFERENCES 过程,内部操作就是执行两个 minus 操作

把两边的差异记录下来,作为冲突解决的数据。

这部分后台操作可以通过跟踪 Oracle 进程得到:

SQL> alter session set events '10046 trace name context forever,level 12';

Session altered.

Elapsed: 00:00:00.02

SQL> begin dbms_rectifier_diff.DIFFERENCES(

2 SNAME1 =>'HAWA',

3 ONAME1 =>'TEST',

4 REFERENCE_SITE =>'AVATAR.COOLYOUNG.COM.CN',

4 SNAME2 =>'HAWA',

6 ONAME2 =>'TEST',

7 COMPARISON_SITE =>'AUTHAA.COOLYOUNG.COM.CN',

8 WHERE_CLAUSE =>NULL,

9 COLUMN_LIST =>NULL,

10 MISSING_ROWS_SNAME =>'HAWA',

11 MISSING_ROWS_ONAME1 =>'MISSING_ROWS_TEST',

12 MISSING_ROWS_ONAME2 =>'MISSING_LOCATION_TEST',

2005 年 5 月 4 期 总第 4 期

- 27 -

Page 28: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 28 -

13 MISSING_ROWS_SITE =>'AVATAR.COOLYOUNG.COM.CN',

14 MAX_MISSING =>500,

15 COMMIT_ROWS =>100

16 );

17 end;

18 /

PL/SQL procedure successfully completed.

Elapsed: 00:00:01.97

SQL> alter session set events '10046 trace name context off';

从跟踪文件中我们可以清晰的看到(注意你所定义的所有参数在此都会有所体现):

首先是一个正向 Minus

DECLARE

row_count BINARY_INTEGER := 0;

missing_rows BINARY_INTEGER := 0;

arowid ROWID;

CURSOR c

IS

SELECT "DATLOGONTIME", "NUMGENDER", "NUMSTATUS", "NUMUSERID", "VC2IP",

"VC2USERNAME"

FROM "HAWA"."TEST"

MINUS

SELECT "DATLOGONTIME", "NUMGENDER", "NUMSTATUS", "NUMUSERID", "VC2IP",

"VC2USERNAME"

FROM "HAWA"."TEST"@authaa.coolyoung.com.cn;

BEGIN

FOR r IN c

LOOP

missing_rows := missing_rows + 1;

IF missing_rows > 500

THEN

COMMIT;

EXIT;

END IF;

INSERT INTO "HAWA"."MISSING_ROWS_TEST"

("DATLOGONTIME", "NUMGENDER", "NUMSTATUS",

"NUMUSERID", "VC2IP", "VC2USERNAME"

)

Page 29: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 29 -

VALUES (r."DATLOGONTIME", r."NUMGENDER", r."NUMSTATUS",

r."NUMUSERID", r."VC2IP", r."VC2USERNAME"

);

SELECT ROWID

INTO arowid

FROM "HAWA"."MISSING_ROWS_TEST"

WHERE ( datlogontime = r."DATLOGONTIME"

OR (datlogontime IS NULL AND r."DATLOGONTIME" IS NULL)

)

AND ( numgender = r."NUMGENDER"

OR (numgender IS NULL AND r."NUMGENDER" IS NULL)

)

AND ( numstatus = r."NUMSTATUS"

OR (numstatus IS NULL AND r."NUMSTATUS" IS NULL)

)

AND (numuserid = r."NUMUSERID")

AND (vc2ip = r."VC2IP" OR (vc2ip IS NULL AND r."VC2IP" IS NULL))

AND ( vc2username = r."VC2USERNAME"

OR (vc2username IS NULL AND r."VC2USERNAME" IS NULL)

);

INSERT INTO "HAWA"."MISSING_LOCATION_TEST"

(present, absent, r_id

)

VALUES ('AVATAR.COOLYOUNG.COM.CN', 'AUTHAA.COOLYOUNG.COM.CN',

arowid

);

row_count := row_count + 1;

IF row_count >= 100

THEN

COMMIT;

row_count := 0;

END IF;

END LOOP;

COMMIT;

END;

其次是一个反向 Minus

DECLARE

row_count BINARY_INTEGER := 0;

missing_rows BINARY_INTEGER := 0;

Page 30: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 30 -

arowid ROWID;

CURSOR c

IS

SELECT "DATLOGONTIME", "NUMGENDER", "NUMSTATUS", "NUMUSERID", "VC2IP",

"VC2USERNAME"

FROM "HAWA"."TEST"@authaa.coolyoung.com.cn

MINUS

SELECT "DATLOGONTIME", "NUMGENDER", "NUMSTATUS", "NUMUSERID", "VC2IP",

"VC2USERNAME"

FROM "HAWA"."TEST";

BEGIN

FOR r IN c

LOOP

missing_rows := missing_rows + 1;

IF missing_rows > 500

THEN

COMMIT;

EXIT;

END IF;

INSERT INTO "HAWA"."MISSING_ROWS_TEST"

("DATLOGONTIME", "NUMGENDER", "NUMSTATUS",

"NUMUSERID", "VC2IP", "VC2USERNAME"

)

VALUES (r."DATLOGONTIME", r."NUMGENDER", r."NUMSTATUS",

r."NUMUSERID", r."VC2IP", r."VC2USERNAME"

);

SELECT ROWID

INTO arowid

FROM "HAWA"."MISSING_ROWS_TEST"

WHERE ( datlogontime = r."DATLOGONTIME"

OR (datlogontime IS NULL AND r."DATLOGONTIME" IS NULL)

)

AND ( numgender = r."NUMGENDER"

OR (numgender IS NULL AND r."NUMGENDER" IS NULL)

)

AND ( numstatus = r."NUMSTATUS"

OR (numstatus IS NULL AND r."NUMSTATUS" IS NULL)

)

AND (numuserid = r."NUMUSERID")

AND (vc2ip = r."VC2IP" OR (vc2ip IS NULL AND r."VC2IP" IS NULL))

AND ( vc2username = r."VC2USERNAME"

Page 31: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 31 -

OR (vc2username IS NULL AND r."VC2USERNAME" IS NULL)

);

INSERT INTO "HAWA"."MISSING_LOCATION_TEST"

(present, absent,

r_id

)

VALUES ('AUTHAA.COOLYOUNG.COM.CN', 'AVATAR.COOLYOUNG.COM.CN',

arowid

);

row_count := row_count + 1;

IF row_count >= 100

THEN

COMMIT;

row_count := 0;

END IF;

END LOOP;

COMMIT;

END;

经过这两个步骤的操作,Oracle 定位了冲突数据。

可是注意,如果在解决这个问题时你没有挂起复制,Oracle 得到的数据可能是存在问题的。

而且,如果你不指定 column list,那么两边的数据可能会因为某些特殊字段(如时间字段)的特殊

处理而存在差异。

那么这时候手工介入不可避免。

我们首先先把两个重要参数的用法说明一下。

一个是 WHERE_CLAUSE,另外一个是 COLUMN_LIST。

WHERE_CLAUSE 用于限定进行差异比较的范围,这可以极大的缩减结果集的数量,使用索

引加快访问速度等。

比如我这里使用 NUMGENDER=1,只比较性别为"女"这一部分用户数据。

Page 32: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

COLUMN_LIST 用于限定比较字段,如果你能通过某个字段,如主键等确定数据差异,那么

你完全可以只比较单个字段。

而且显然可以轻易通过全索引扫描来完成比较,加快比较速度。

我这里使用 NUMUSERID,用户 ID 来比较。

但是注意,这样的比较结果中将只包含 NUMUSERID 信息,当然我们可以轻易通过

NUMUSERID 和原表的比较补全 MISSING_ROWS_TEST 表的信息。

begin dbms_rectifier_diff.DIFFERENCES(

SNAME1 =>'HAWA',

ONAME1 =>'TEST',

REFERENCE_SITE =>'AVATAR.COOLYOUNG.COM.CN',

SNAME2 =>'HAWA',

ONAME2 =>'TEST',

COMPARISON_SITE =>'AUTHAA.COOLYOUNG.COM.CN',

WHERE_CLAUSE =>'NUMGENDER=1',

COLUMN_LIST =>'NUMUSERID',

MISSING_ROWS_SNAME =>'HAWA',

MISSING_ROWS_ONAME1 =>'MISSING_ROWS_TEST',

MISSING_ROWS_ONAME2 =>'MISSING_LOCATION_TEST',

MISSING_ROWS_SITE =>'AVATAR.COOLYOUNG.COM.CN',

MAX_MISSING =>500,

COMMIT_ROWS =>100

);

end;

/

这段代码供参考。

Ok,我们继续前面的讨论。

我们提到,如果存在差异,通常需要手工介入。

清楚了 DIFFERENCES 的原理,实际上我们完全可以手工来完成这个过程。

以下是我的手工操作步骤,目的是为了准确性及减轻数据库压力:

2005 年 5 月 4 期 总第 4 期

- 32 -

Page 33: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

首先创建一个 ID 差异表

这个表不是必须的,这里是为了清晰

SQL> create table hawa.prof as select NUMUSERID from hawa.hw_user where 1=0;

Table created.

Elapsed: 00:00:00.16

根据主键找到差异记录

注意这里取决于你的数据库产生差异的原因,我的差异由于初始数据不同步,即 A 全包含 B

并且,A>B。

SQL> insert into hawa.prof

2 select * from

3 (

4 select NUMUSERID from hawa.HW_USERPROFILE

5 minus

6 select NUMUSERID from hawa.HW_USERPROFILE@authaa)

7 /

263 rows created.

Elapsed: 00:00:32.49

创建记录表

SQL> create table hawa.missing_rows_hw_userprofile

2 as

3 select * from hawa.hw_userprofile where 1=0;

Table created.

Elapsed: 00:00:00.12

创建位置(Location)表

2005 年 5 月 4 期 总第 4 期

- 33 -

注意这里 Oracle 需要记录缺失方向,和具体记录的 ROWID,这个 ROWID 来自

missing_rows_hw_userprofile。

SQL> create table hawa.MISSING_LOC_hw_userprofile (

2 present VARCHAR2(128),

3 absent VARCHAR2(128),

Page 34: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 34 -

4 r_id ROWID);

Table created.

Elapsed: 00:00:00.04

根据差异信息查询到完整信息

SQL> insert into hawa.missing_rows_hw_userprofile

2 select * from hawa.hw_userprofile where NUMUSERID in

3 (select * from hawa.prof);

263 rows created.

Elapsed: 00:00:00.06

SQL> commit;

Commit complete.

Elapsed: 00:00:00.02

构造位置信息

注意这里的方向信息及 ROWID 信息。

SQL> insert into hawa.MISSING_LOC_hw_userprofile

2 select 'AVATAR.COOLYOUNG.COM.CN','AUTHAA.COOLYOUNG.COM.CN',rowid from

hawa.missing_rows_hw_userprofile;

263 rows created.

Elapsed: 00:00:00.00

SQL> commit;

Commit complete.

Elapsed: 00:00:00.06

纠正数据冲突

SQL> BEGIN DBMS_RECTIFIER_DIFF.RECTIFY(

2 SNAME1 =>'HAWA',

3 ONAME1 =>'HW_USERPROFILE',

Page 35: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 35 -

4 REFERENCE_SITE =>'AVATAR.COOLYOUNG.COM.CN',

5 SNAME2 =>'HAWA',

6 ONAME2 =>'HW_USERPROFILE',

7 COMPARISON_SITE =>'AUTHAA.COOLYOUNG.COM.CN',

8 COLUMN_LIST =>NULL,

9 MISSING_ROWS_SNAME =>'HAWA',

10 MISSING_ROWS_ONAME1 =>'MISSING_ROWS_HW_USERPROFILE',

11 MISSING_ROWS_ONAME2 =>'MISSING_LOC_HW_USERPROFILE',

12 MISSING_ROWS_SITE =>'AVATAR.COOLYOUNG.COM.CN',

13 COMMIT_ROWS =>100

14 );

15 END;

16 /

PL/SQL procedure successfully completed.

Elapsed: 00:00:03.53

验证结果

SQL> select count(*) from hawa.HW_USERPROFILE;

COUNT(*)

----------

1746300

Elapsed: 00:00:02.22

SQL> select count(*) from hawa.HW_USERPROFILE@authaa;

COUNT(*)

----------

1746300

Elapsed: 00:00:00.21

SQL> select count(*) from hawa.HW_USERPROFILE;

COUNT(*)

----------

1746300

Elapsed: 00:00:00.59

SQL>select count(*) from hawa.HW_USERPROFILE@authaa;

Page 36: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 36 -

COUNT(*)

----------

1746300

Elapsed: 00:00:00.20

SQL> select NUMUSERID from hawa.HW_USERPROFILE

2 minus

3 select NUMUSERID from hawa.HW_USERPROFILE@authaa ;

no rows selected

Elapsed: 00:00:23.51

SQL>

作者简介:

盖国强,网名 eygle

曾任 ITPUB MS版版主,现任 itpub Oracle管理版版主.

曾任职于某国家大型企业,服务于烟草行业,开发过基于 Oracle 数据库的大型 ERP 系

统,属国家信息产业部重点工程.同时负责 Oracle 数据库管理及优化,并为多家烟草企业提供

Oracle数据库管理、优化及技术支持.

目前任职于北京某电信增值业务系统提供商企业,首席 DBA,负责数据库业务.管理全国

30多个数据库系统。项目经验丰富,曾设计规划及支持中国联通增值业务等大型数据库系统.

实践经验丰富,长于数据库诊断、性能调整与 SQL优化等。对于 Oracle内部技术具有

深入研究。

高级培训讲师,培训经验丰富,曾主讲 itpub dba培训及 itpub高级性能调整等主要课

程.

《Oracle数据库 DBA专题技术精粹》一书的主编及主要作者.

你可以在http://www.eygle.com上找到关于作者的更多信息.

Page 37: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

数据库高可用性

SharePlex for Oracle

本文作者: Quest Software China

1.1. 前言

在企业信息化进程不断加快的今天,保持业务的连续性是企业用户进行数据存储时必须考虑

的重要方面。灾难的出现可能导致生产停顿、客户满意度降低,减少企业的竞争力。如何安全、

可靠、完整地保存数据,实现系统的灾难恢复是市场竞争的需要,更是进一步提高服务水平和改

善服务质量、提升业务支撑能力的重要技术手段。

目前,很多厂家都提供容灾保护的产品,主要包括基于存储、逻辑卷、主机、数据库物理方

式和数据库逻辑方式的各种复制技术。根据复制层面的不同,实现的技术以及容灾效果各不相同。

Quest Software 的 SharePlex for Oracle 通过数据库逻辑层的复制技术,可以方便地实现基于 Oracle

数据库的容灾保护,具有对源系统资源占用少,对网络资源占用少,支持异构环境和不同的复制

拓扑,保持事物一致性的特点。在开放异构环境、异地容灾、容灾系统可访问的环境中具有非常

大的优势。

通过 SharePlex for Oracle,可以帮助企业建立一个全面的、整体的容灾方案,最大限度地保证

业务系统的连续性和业务数据的可恢复性。

1.2. 高可用容灾方案设计

1.2.1. 高可用容灾系统的影响因素

影响应用系统可用性主要有三方面的因素,计划外的系统停机、计划内的维护操作和灾难恢

复。

2005 年 5 月 4 期 总第 4 期

- 37 -

Page 38: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

1.2.2. 计划外的系统停机

计划外的系统停机指由于应用系统故障导致的系统不可用。减少计划外的停机时间是应用系

统设计人员和管理人员面临的主要任务,虽然每个业务系统都在硬件、软件和人员方面投入很多,

但每年计划外的停机时间还是不可避免的发生,造成了很多不可避免的经济损失。一般来说,计

划外的系统停机主要是由于以下原因引起的。

人为错误。如用户具有过多的权限,从而可以访问没有被授权的一些数据。或者数据库管理

人员过度劳累导致的错误。

硬件/软件出错。硬件和软件失败是不可避免的现象,而且随着数据库系统使用年限的增加而

变得更加脆弱。通常由于硬件/软件出错所引起的故障包括应用程序出错、数据库出错、操作

系统故障,如操作系统死机等以及硬件故障,如硬盘或网卡损坏等。

环境失败。环境失败指由于外部环境改变导致系统不可用或无法有效地进行数据库管理。如

断电,工人罢工等等。

1.2.2.1. 计划内的维护操作

系统操作人员经常提到的一个术语就是“维护”。大多数维护操作会影响到系统的可用性和性

能。由于进行主动系统维护所引起的停机时间被称为计划内停机时间。对于每个数据库应用来说,

每年或每月都需要一定的计划内停机时间,因为停机时间可以控制,停机操作对系统的影响也可

以预先通知到用户,因而计划内停机时间虽然发生频繁,对系统的影响可以控制在一定范围。

1.2.2.2. 灾难恢复

对于高可用需求的应用系统来说,自然灾害与人为灾害始终存在。自然原因引起的灾难包括

地震、洪水、火灾、飓风、恐怖活动、战争、暴乱活动等,人为因素导致的数据库不可用包括故

意破坏。这些灾难发生的概率非常低,但是如果一旦发生,对严重依赖于数据的企业是致命的打

击,甚至导致企业无法继续运营。

在灾难发生的情况下,数据恢复成为高可用性管理的首要任务,数据备份、特别是异地数据

备份是成功实现灾难恢复的核心。企业需要在保证业务数据恢复的情况下保持业务系统的连续性。

2005 年 5 月 4 期 总第 4 期

- 38 -

Page 39: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

1.2.3. 高可用容灾系统的建设目标

系统的容灾和高可用方案必须能够应付所有可能引起计算机系统失效的问题。应用系统高可

用性和容灾方案需要满足两方面的要求:

1.业务系统的连续性

保持业务系统的连续性,意味着无论是由于硬件,软件或电源的失效都不应中断信息中心的

处理工作;实现业务的连续性需要减少或消除计划外停机时间,控制计划外停机时间对系统的影

响,在灾难发生时间进行业务系统的快速接管,这些主要通过各个层次的冗余技术实现的。

2.业务数据的可恢复性

业务数据的可恢复性从本质上来说是业务系统连续性的一个子集。如果数据出现问题而不能恢复,

业务系统的连续性无从谈起。因为数据对严重依赖于信息系统的企业非常重要,数据的可恢复性

一直是高可用性系统的一个重点考虑因素。业务数据的可恢复性是通过数据备份和冗余的数据拷

贝完成的。数据库复制和硬件复制都是用于这个环境的一些成熟技术。业务数据的可恢复性主要

考虑因素为备份数据的安全性,需要确保在任何情况下,包括容灾发生时备份数据都可以有效地

进行恢复。同时,数据丢失也是一个非常重要的评价指标。

1.2.4. 建设容灾系统的考虑因素

因为要建立整个应用系统的冗余备份,容灾系统是一个非常昂贵的系统,在容灾系统建设时

需要考虑以下因素:

容灾距离:

根据灾备中心建设的目的不同,灾备中心的建设需要考虑灾备中心的距离。一般来说,容灾

距离有本地和同城、异地三种方式。

异地容灾方案中,灾备中心和主中心的距离较远,如北京到上海。异地容灾可以有效地防止

由于本地灾难发生引起数据损失,但是实施成本很高、为了保障业务系统的性能一般采用同步数

据拷贝方式,这样会存在一定的数据损失,同时将应用系统切换到灾备中心的工作也非常繁琐。

一般来说,异地灾备中心建设的主要目的提供业务数据的恢复能力。

同城容灾方案中,灾备中心和主中心距离在几十公里以内。同城容灾可以有效地提供业务数

据的恢复能力以及应用快速接管能力。根据业务系统对数据访问以及数据丢失的需求,数据复制

可以采用同步或异步两种方式。

同地容灾指灾备系统和主中心在一个地理位置。一般来说,它可以和现有的其他可用性技术,

如 Cluster 结合,提供更高级别的高可用性。同时,很多同地容灾解决方案提供灾备中心的数据访

2005 年 5 月 4 期 总第 4 期

- 39 -

Page 40: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

问能力。

为了有效地进行容灾,很多关键的业务系统建立两个系统,同城灾备中心和异地灾备中心,

同城灾备中心由生产系统采用同步方式进行数据复制,异地灾备中心由同城灾备中心采用异步方

式进行数据复制。

数据丢失

企业能忍受的数据丢失和具体处理的业务有关。例如:财务系统的数据很难承受任何损失,

而电信营帐系统在灾难发生时可以允许少量的数据丢失。目前,虽然有很多方案可以做到“零数据

丢失“,但企业往往为此支付高昂的费用,生产系统的性能也会受到很大影响。从业务的角度企业

能够承受德考虑数据丢失问题可以帮助企业在容灾方案上做出适合企业自身特点的选择。

应用切换时间

容灾系统建设的一个重要目的是保障业务系统的连续性。在灾难发生或业务系统出现问题时

间,将应用快速地切换到灾备系统可以最大程度地减少系统的停计时间。当灾难发生,启用灾备

中心需要采取一系列的措施。如将网络、电话线路切换到新的地点,启动操作系统、数据库,进

行应用程序的切换等等。一般来说,容灾系统的切换时间应该控制到 30 分钟以内。

主系统的可恢复性

主系统的可恢复性主要指数据的恢复,将应用切换灾备系统后,业务的连续性得以保持,主

系统的恢复时间应该控制在一天到几天之内。数据恢复的关键问题在于数据的可恢复性,以及恢

复过程中如何和灾备中心的数据保持一致。

目标系统的可访问性

目标数据可访问能够提高容灾系统的投资回报,增加容灾系统的利用价值。企业可以将目标

系统作为报表查询、统计分析等系统的数据源,减轻源系统的压力,使投资变为可用,而不是单

存的冷备闲置。同时,目标数据的在线使用可以保障数据的准确性,从而避免容灾系统长期冷备,

数据错误而无人发现的情况,能够确保容灾系统在灾难发生时被有效接管,进行数据恢复。

对源系统的影响。

灾备中心的建设是对现有系统的扩展和补充,不能因为灾备中心影响当前业务系统的性能,

导致系统的可用性降低。

网络资源的使用。

网络资源的使用对于容灾系统特别是异地容灾系统非常重要。在网络上传输的数据量大小直

接决定数据传输的实时性,同时,网络资源占用会影响灾备中心后期的网络使用费用。

容灾环境的开放性。

组成数据库应用系统的环境非常复杂,主机、存储、数据库是容灾环境的三个主要组件,支

持开放环境,例如容灾系统支持不同的操作系统和数据库、不同的磁盘阵列、不同的主机系统会

有效地适应未来的扩展需求,充分保护投资。 2005 年 5 月 4 期 总第 4 期

- 40 -

Page 41: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

实施成本是在充分评估了上述内容后需要考虑的又一个重要因素。事实上,在建立容灾系统时,

一个对业务系统没有任何影响、没有任何数据损失、容灾距离足够远的方案是很难实现的。企业

需要了解自己的需求,建立适合自身特点的容灾系统。双数据中心环境下的有效冗余和网络结构

1.2.5. 容灾系统的实现技术

1.2.5.1. 基于磁带拷贝的传统灾难备份方式

利用磁带拷贝进行数据备份和恢复是最常见的传统灾难备份方式。这些磁带拷贝通常都是按

天,按周或按月进行组合保存的。

使用这种方式的数据拷贝通常是存储在盘式磁带或盒式磁带上,并存放在远离基本处理系统

的某个安全地点。存储到安全地点的磁带拷贝,其上的数据已有数小时的延迟,而在灾难或各种

故障出现系统需要立即恢复,必须将磁带提取出来,并运送到恢复地点,通常还要滞延几个小时。

基于磁带拷贝方式的传统灾难备份方式有着明显的缺陷,越来越不适合用户不断发展的业务系统

的需要。其备份和恢复过程非常复杂,数据延迟较大,磁带管理困难,数据恢复必须按照正确的

顺序,出错的可能性也较大。

1.2.5.2. 数据库方式

数据库复制是目前最流行的高可用解决方案。每种数据库系统来实现的机制和方式略有不同,

但都包括逻辑复制和物理复制两种方式:

逻辑复制指针对数据库的逻辑层数据进行复制,复制的基本单位为数据库表以及表中所有的

数据,复制时采用标准的 TCP/IP 协议。这种复制方法的好处是复制的数据量少,网络资源占用低,

在复制的过程中目标数据库可以被访问,企业可以将目标系统用于报表和查询系统。同时因为目

标数据库处于启动状态,接管时不需要重新启动数据库,接管可以接近实时。

物理复制方法主要通过日志文件的传送和应用实现的。数据库交易的复制机制利用日志的这

种特性,在生产中心将日志传输到灾备中心;如果灾备中心的数据库结构和生产中心的数据库结

构保持一致,则灾备中心的数据库对日志中记载的交易执行前滚操作,即实现了对灾备中心数据

库数据的更新。

数据库级别的复制可以支持计划内停机时间、计划外的停机时间和应用可以允许一些损失的

情况下进行灾难恢复。

2005 年 5 月 4 期 总第 4 期

- 41 -

Page 42: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

1.2.5.3. 服务器卷方式

服务器卷方式复制嵌入到操作系统的卷管理系统中,卷发生的变化分为结构的变化和卷内容

的变化。这种复制方式可以复制卷内容的变化。

服务器卷方式有两种复制方式,同步方式和异步方式。同步方式采用数据库两阶段提交的方

法,对源系统的影响非常大。异步方式从数据的一致性保障方面存在问题。

由于卷复制部件使用服务器 CPU、Memory 资源,使用标准的 TCP/IP 网络,对业务的正常运

行产生的较大的性能影响。

使用服务器卷方式进行复制,必须使用专用的卷管理软件,整个应用系统的结构需要根据卷

管理的要求经过严格的设计和重新划分,同时,在后期的维护过程中也需要对卷结构的变化进行

同步的维护,从而增加实施和维护方面的一些困难。

服务器卷方式复制对服务器的硬件平台、数据库版本有严格限制,局限于主机同构环境。

1.2.5.4. 智能存储系统方式

智能存储方式利用磁盘系统自身的处理能力,通过磁盘系统之间的通道连接复制磁盘系统内

的数据更新,从而在异地中心保存生产数据的记录。利用磁盘复制可以独立于服务器、操作系统、

卷管理系统、数据库、文件系统、中间件、应用程序。

和服务器卷方式一样,智能存储两种复制方式,同步方式和异步方式。同步方式采用数据库

两阶段提交的方法,对源系统的影响非常大。异步方式从数据的一致性保障方面存在问题。

智能存储系统方式复制使用存储上的 CPU 资源,但对 IO 资源的消耗比较大。这种方式复制

速度很快,但这种复制方式对存储依赖非常强,主备服务器必须使用同样的存储设备,依赖于专

有网络。因为在存储级进行复制,目标数据库处于不可用状态。当需要应用切换时,必须停止复

制过程,Mount 复制卷组,将操作系统启动,启动数据库,进行数据库恢复。所有这些工作一般

手工进行,需要花费一定的时间。

采用智能存储系统方式进行复制,源系统和目标系统的硬件平台、操作系统、数据库版本必

须一致。复制的内容包括所有底层数据,占用的网络带宽较高。而且目标系统无法访问。

1.3. SharePlex for Oracle 介绍

目前,很多厂家都提供容灾保护的产品,主要包括基于存储、逻辑卷、主机、数据库物理方

式和数据库逻辑方式的各种复制技术。根据复制层面的不同,实现的技术以及容灾效果各不相同。

Quest Software 的 SharePlex for Oracle 通过数据库逻辑层的复制技术,可以方便地实现基于 Oracle

2005 年 5 月 4 期 总第 4 期

- 42 -

Page 43: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

数据库的容灾保护,具有对源系统资源占用少,对网络资源占用少,支持异构环境和不同的复制

拓扑,保持事物一致性的特点。在开放异构环境、异地容灾、容灾系统可访问的环境中具有非常

大的优势。

1.3.1. SharePlex for Oracle 结构

基本结构

下图所示为 SharePlex for Oracle 的基本结构,其中涉及较多的技术细节。

图 1-1 Shareplex 基本结构

数据捕获

SharePlex for Oracle 中由捕获进程来收集发生变化的数据,此进程的独特之处在于它几乎不对

生产数据库带来任何开销。

数据传输

SharePlex 结合其自己的网络协议和 TCP/IP 协议来完成源和目标系统之间的数据传输。其相

关的进程确保数据的正确接收和网络数据包的正确顺序,从而提供网络传输冗余,确保数据的完

整。整个数据传输过程无需其它的中间件。

应用数据

应用进程将传送到目标系统中的信息转化为SQL语句,然后采用标准的SQL*Plus方式将SQL

语句发送给 Oracle 执行。

SharePlex 能够实现精确复制的一个重要原因就是其能保证从源数据库到目标数据库的 Oracle

读一致性,不但按顺序复制事务,而且也复制上下文信息。由于 SharePlex 将源数据库中发生变化

2005 年 5 月 4 期 总第 4 期

- 43 -

Page 44: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

的全部事务信息都复制到目标数据库中,因此 SharePlex 复制方案用于灾难恢复系统中是足够可靠

的。

1.3.2. SharePlex for Oracle 配置方案

SharePlex 提供多种不同的配置方式以满足高可用性和负载均衡需求。主要包括:

单向复制

SharePlex 可以将源系统的数据实时复制到目标系统,从而建立一个可以被访问的即席查询和

报表系统。目标系统可以是源系统的全集和子集。通过将查询和报表系统放在不同的数据库实例

中运行,可以平衡服务器负载并提高 OLTP 类生产系统的性能。

高可用性

保证数据高可用性和数据库系统能够从灾难中迅速恢复是一个非常具有挑战性的工作。

SharePlex for Oracle 可以通过 LAN 或 WAN 进行复制,这样当生产环境出现紧急事件或要进行例

行维护时,可以将应用切换到复制数据库中。有了生产数据库的实时拷贝,用户可以保证应用系

统 7*24 不间断运行的情况下进行维护工作,如进行操作系统和数据库的升级等等。

分布处理

多数据源配置允许你将不同的用户分布到不同的服务器,让每个数据库能够反映其他数据库

的变化。在这种配置模式下,SharePlex 采用必要的冲突处理机制来解决可能发生的冲突。

广播和集中复制

SharePlex for Oracle 通过 LAN 或 WAN 进行实时复制,将生产数据库中的数据拷贝到需要它

们的地方。对广播复制来说,远程用户可以访问这些实时数据而不用登录生产服务器。因此,提

高了网络性能和生产环境下的 OLTP 应用的性能。

2005 年 5 月 4 期 总第 4 期

- 44 -

Page 45: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

企业环境的数据分布

SharePlex 支持层叠复制,可以向不是直接相连的数据库复制数据。使用这种配置,可以在远

程数据库间进行复制(如从北京到上海)。SharePlex 支持多种复杂的场景来满足复制需求。

1.3.3. Shareplex for Oracle 特点

1.3.3.1. 快速精确和低负载

SharePlex 是非常快速的,同时保证了复制数据的精确性。在源数据库一端,SharePlex 严格地

遵守读一致性模式。在目标数据库一端,SharePlex 使用标准 SQL 提交事务,并保证操作次序和会

话上下文的一致。

基于 Log 的复制方式对源数据库和系统所带来资源开销非常小,因为复制操作只是读取操作

系统的日志文件,同时通过 TCP/IP 方式而不是采用中间件方式传输只发生改变的数据也使网络负

载降至最低。

1.3.3.2. 可扩展及全面

每秒钟可针对数千个表复制超过一千个以上事务的处理能力意味着 SharePlex可以处理企业级

的业务数据,可以满足企业大数据量的吞吐需求。实际环境中的吞吐速率是受服务器性能、网络

带宽和事务的复杂程度所影响的。

SharePlex 提供的完全复制程度是其它软件复制工具所不具备的。SharePlex 支持带长列的表、

2005 年 5 月 4 期 总第 4 期

- 45 -

Page 46: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

带参照完整性约束的表、没有主键的表、序列等等的复制。此外,SharePlex 复制 ALTER TABLE

等命令,使它可以不需要其它软件复制工具就复制 DDL 活动。

1.3.3.3. 灾难恢复

SharePlex 在设计时已经将性能和容灾因素考虑在内。SharePlex 可以容忍实例失败、系统失败

和网络失败。一般情况下,在源系统中运行的事务一旦被写入 log,SharePlex 立即将其发送到目标

系统。然而,如果发生问题,SharePlex 可以在源系统或目标系统进行事务排队(为了最小化对源系

统的影响,排队位于 Oracle 源实例之外)。例如,如果网络宕掉或目标系统宕掉,SharePlex 将源系

统中的事务排队。当网络或系统恢复后,SharePlex 将自动提交被排队的数据并清空队列文件。

1.3.3.4. 灵活配置和简洁管理

SharePlex 可以被灵活配置,以支持各种复制策略。包括单向复制、双向复制、广播复制、集

中复制及多层复制等。

SharePlex 是独立的软件,不需要修改与数据库进行交互的应用程序和数据库本身。因此,安

装非常简洁。配置和改变复制策略不影响源数据库系统中的生产活动。管理员可以用 Windows 界

面或服务器端的命令行管理和监控复制操作的各个方面。

1.3.4. SharePlex for Oracle 适用场合

应用容灾

企业开始比以往任何时候更注重对关键业务数据进行及时的保护,因为关键业务数据的丢失

可能会给企业带来不可估量的损失。

SharePlex 为业务系统提供灾难恢复能力,容灾系统中的硬件环境又可用来降低系统维护工作

中的停机时间。这并不与企业的容灾方案相矛盾,因为事务可被发送到系统中的远程节点上。

SharePlex 支持多种配置方案,包括对等配置方案,在这种配置方案中,两个数据库都处于可

用状态,因而可实现快速的失败接管。在容灾发方案中没有比这种失败接管更快的方法了。

减少有计划的停机时间

有计划的停机也可能对企业的服务水平、客户满意程度甚至股价等带来影响,而据估计企业

80%的停机是有计划的行为。

利用 SharePlex,企业可几乎完全消除系统的停机时间而不用考虑在此期间进行何种维护工

2005 年 5 月 4 期 总第 4 期

- 46 -

Page 47: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

作、哪个操作系统会受到影响,甚至不用考虑数据库版本的问题及对硬件环境进行何种操作。

负载平衡

SharePlex 可以将源系统的数据实时复制到目标系统,从而建立一个可以被访问的即席查询和

报表系统。目标系统可以是源系统的全集和子集。通过将查询和报表系统放在不同的数据库实例

中运行,可以平衡服务器负载并提高 OLTP 类生产系统的性能。一方面,可以减少 OLTP 应用和查

询报表应用之间的磁盘 I/O 冲突,提高 OLTP 应用的效率。另一方面,SharePlex 支持不同模式间

的复制。可以分别面向 OLTP 和查询系统的使用特点来进行设计,如建立索引,设置数据库表的参

数等等。

在这种配置环境下,SharePlex 在线事务处理可以获得很好的性能,而决策支持和报表处理可

在不影响正常业务的情况下进行。

当一种单一的数据复制模式不能满足企业的业务扩展需求和系统性能时,很容易利用

SharePlex 建立另外的复制模式,从而进一步扩展系统和提高报表处理的性能。

系统移植

尽管企业从规划设计良好的业务系统中收益,但也不得不面临系统移植和升级这一挑战。数

据集中、技术的推陈出新和服务器的移植都是导致必须进行系统移植的原因之一。

SharePlex 可确保在进行以上工作时正常的事务处理得以继续进行。源系统的功能不受到任何

影响,SharePlex 只捕捉移植过程中发生变化的事务并将它们排队保存。当移植工作结束后,这些

被保存的事务将被应用到新系统中并进行数据同步工作。一旦数据同步后,用户活动会有非常短

暂的停顿,在此瞬间将完成系统的切换动作。

数据集中和广播

SharePlex 通过非常有效的管理控制机制来实现数据集中和广播。SharePlex 提供细化的数据筛

选功能,可按业务需要定制需要传输的数据,从而缓解和消除了数据传输过程中的安全和带宽问

题。例如,如果远程节点只需要有关本地员工的基本信息而无需薪水信息,那么只需利用 SharePlex

传输相关的数据行和字段即可。

支持数据仓库应用、实现更好的决策支持

越来越多的公司在建设决策支持系统。传统的数据抽取、转换和装载工具按照时间段处理数据而

不能进行实时的数据处理,因而决策支持系统就不能真正体现出太大的价值。SharePlex 可以实时

捕捉、转换数据到决策支持系统中。

1.4. 容灾系统建立

2005 年 5 月 4 期 总第 4 期

- 47 -

Page 48: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

1.4.1. 容灾系统状态定义

为方便论述,本节模拟地点 A 和 B,两地各有一套运行在 Oracle 上的应用系统。通过 SharePlex

for Oracle 建立数据复制,以 B 地点的系统作为 A 地点的备份。

正常情况下:

业务系统运行在地点 A,包括数据库实例、有关的文件、数据库数据、应用软件。

A 节点对外提供服务。

A 节点所有的有关的数据通过 SharePlex for Oracle 实时复制到 B 节点。

灾难发生的情况下,整个 A 地点无法正常提供服务:

A 地点的业务将在 B 地点正常提供服务。当灾难发生时,主中心的数据库服务、

应用软件切换到灾备中心的灾备节点。灾备节点对外提供服务。

数据复制暂停。

对主中心的数据库和应用系统进行恢复。

计划内维护操作

当进行计划内的维护时,主中心的数据库服务、应用软件切换到灾备中心的灾备

节点。灾备节点对外提供服务。

SharePlex for Oracle 记录进行维护期间数据的变化,存储到灾备节点的队列。

当计划内的维护操作时完成时,将维护过程中的数据复制到 A 地点,将应用切换

到 A 地点系统。

1.4.2. 容灾系统的的配置过程

1.4.2.1. 初始化高可用及容灾环境

使用 SharePlex for Oracle 进行数据复制的前提是在主中心和灾备中心具有相同的数据。根据

用户对停机时间的要求、容灾环境和数据量的大小。可以采用 Oracle 自身提供的方法进行初始化

同步,包括:Oracle Cold Backup,Oracle Hot Backup,Export/import,Transprant tablespace 等等。

为了保证初始化同步过程中源系统的可用性,SharePlex 提供 Reconcile 功能,当使用 Oracle

Hot backup 机制进行初始化同步时,通过 SharePlex 队列记录数据的变化。并在进行 post 的过程中

确认哪些数据通过 Recovery 进行恢复,把没有恢复的数据装载到数据库中。从而保证初始化同步

过程中源系统没有停机时间。

2005 年 5 月 4 期 总第 4 期

- 48 -

Page 49: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

1.4.2.2. 配置 Shareplex 的 Fail-over ready 状态

为保证灾难发生时快速进行应用接管,需要配置 Fail-over ready 状态。

确保源系统和目标系统 SharePlex for Oracle 启动。

源系统中建立配置文件,目标系统建立反向配置文件。两个配置文件都处于激活状态。

在 Secondary 端保证没有对复制表的 DML 操作;

在 Secondary 端停止 export 进程,防止意外的数据操作改变源系统的数据。

运行脚本取消 secondary 系统用户(除了 splex)的 insert,update 和 delete 权限;

禁止 Secondary 中使用 trigger,cascade delete constraints,foreign-key constraints,check

constrants,schedule jobs 等等。

定期备份 Shareplex 相关的文件,文件包括

Shareplex 的工作目录

/var/adm/.splex/Shareplex.mark

oratab file

/etc/services

/etc/system

/etc/group

操作系统 Shareplex 用户(默认为 Oracle 用户)的.profile 文件

1.4.2.3. 灾难发生时应用切换到灾备中心

灾难发生时的接管工作由以下步骤组成:

确认 Secondary 系统的 export 进程处于停止状态;

确保在队列中的所有数据复制到 Secondary 系统中。用 qstatus 命令查看 Secondary 系统

中的 post 进程,直到 backlog messages 一项为 0;

在 Secondary 系统上运行 SQL 脚本给用户赋权,包括 insert, update 和 delete;

在 Secondary 系统上运行 SQL 脚本 enable triggers 和 contraints;

切换应用系统到 Secondary 系统;

确保 Secondary 系统上的 Shareplex export 进程处于停止状态。

切换过程所需要的时间主要是上述 6 个步骤所需要的时间的总和。正常情况下能够充分满足

30 分钟以内的切换要求。 2005 年 5 月 4 期 总第 4 期

- 49 -

Page 50: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

1.4.2.4. 容灾中心的数据恢复到主中心

从容灾中心的数据恢复到主中心的过程分为如下阶段:

阶段 1:在 Primary System 中恢复复制环境。

阶段 2:Purge 队列, 在 Primary System 中 Purge Capture,Export 和 Post 队列。因为

Primary System 的复制环境是通过备份的软件进行恢复的。队列的内容已经过期。 在

Secondary System 中 Purge Post 队列。原则上 Capture 和 Export 队列没有内容,而在 Post

队列中需要清除没有被提交的部分数据。

阶段 3:开始从 Secondary system 复制到 Primary System,保证 Primary System 的数据存

储在 Post 队列中,但不加载到数据库中。

阶段 4:同步数据,即在 Primary System 中重新建立新的数据库拷贝。

阶段 5:在 Primary System 中进行 Activate。

阶段 6:恢复 Object Cache。

阶段 7:将用户切换到 Primary System。

系统的恢复时间由上述的 7 个阶段构成,其中阶段 4 的时间较长,根据系统的数据量、目标

系统硬件选型不同,正常切换时间在 10-38 个小时之间。

1.4.2.5. 计划内系统维护

计划内的 Shareplex failover 接管

在 Primary 系统上停止用户对数据对象的访问;

在 Primary 系统,运行 flush 命令,此命令停机目标机器上的 post 进程,并将队列中的

内容装载到数据库中。

关闭 Primary 中的 SharePlex 和 Oracle 数据库。

运行脚本为 Secondary 系统的 oracle 用户赋 insert, update 和 delete 的权限;

运行脚本激活 Secondary 系统的 oracle trigger 和 contraints;

按照相应步骤重新部署用户和应用到 Secondary 系统;

切换用户到 Secondary 系统,但不要启动 export 进程;

计划内的 Shareplex failback 接管

打开 Primary 系统的 Oracle 数据库;在 Primary 系统上对 Triggers、Foreign-key constraints、

Cascading delete constriants、Check constraints、Scheduled jobs that perform DML 进行修

2005 年 5 月 4 期 总第 4 期

- 50 -

Page 51: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

改并使之无效。

将 Secondary 系统中 SharePlex 队列中的数据装载到 Primary 系统中。

在 Secondary 系统上,运行 flush 命令;此命令停机 Priamry 机器上的 post 进程,并将队

列中的内容装载到数据库中。

在 Secondary 系统关闭 shareplex 和 Oracle 数据库。;

运行脚本为 Primary 系统的 oracle 用户赋 insert, update 和 delete 的权限;

运行脚本激活 Primary 系统的 oracle trigger 和 contraints;

按照相应步骤重新部署用户和应用到 Primary 系统;

切换用户到 Primary 系统,但不要启动 export 进程;

运行脚本取消 secondary 系统用户(除了 splex)的 insert,update 和 delete 权限;

在 Secondary 系统上对对 Triggers、Foreign-key constraints、Cascading delete constriants、

Check constraints、Scheduled jobs that perform DML 进行修改并使之无效。

启动 Secondary 系统的 Shareplex,但停止 export 进程;

在 Primary 系统 Shareplex 控制台上启动 export 进程;

1.4.3. SharePlex 关键技术指标

1.4.3.1. 数据延迟

SharePlex for Oracle 是一种异步准实时的复制技术,其数据延迟非常小。在生产系统中,数据

延迟和源系统复制事物的多少,事物的处理方式有关。在复制数据量正常的 OLTP 系统中,数据延

迟在几秒钟。

1.4.3.2. 目标数据可访问

SharePlex 独特的实现机制使用户可以对目标系统进行查询操作,因此,可以作为报表查询、

统计分析等系统的数据源,减轻源系统的压力,使投资变为可用,而不是单存的冷备闲置。目标

数据可访问能够提高容灾系统的投资回报,增加容灾系统的利用价值。同时,目标数据的在线使

用实际上是对数据的一个长期在线使用,保障数据的准确性,从而避免容灾系统长期冷备,数据

错误而无人发现的情况,能够确保容灾系统在灾难发生时被有效接管,进行数据恢复。

2005 年 5 月 4 期 总第 4 期

- 51 -

Page 52: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

1.4.3.3. 支持异构环境

源数据库和目标数据库可以运行在不同类型的操作系统和同一 Oracle 数据库的不同版本上。

同时,也能够支持不同类型的磁盘阵列(包括 SAN)。这不仅能够满足目前异构环境,还能适应未

来的扩展需求。很多复制方案的软件产品也宣称能够支持多种主机、操作系统、磁盘阵列,但是

他们实际上还是要求主中心和灾备中心的设备是同一类型的。而 Share Plex 完全满足主备中心的

异构。这样,系统建设是可以选择多种产品参与竞标,大大降低硬件投资,随着公司规模的不断

扩大,在硬件升级时,新旧硬件产品可以随意调换,不受限制。

1.4.3.4. 强大的冗错能力

复制环境能够提供网络失败、数据库失败、主机失败的容错能力。当灾备中心暂停或传输异

常中断导致复制停止时,主中心的业务不受影响,容灾数据可以在主中心暂时存放,当系统恢复

后,暂存数据可自动完整复制到灾备中心,数据完整性一致性不被破坏;

1.4.3.5. 对源系统的影响

SharePlex for Oracle 通过 Oracle 日志获得数据的变化信息,它独特的技术优势使得它对源系统

的资源占用很小。在生产系统中,实际对源系统的影响和源系统复制事物的多少,事物的处理方

式有关。在复制数据量正常的 OLTP 系统中,正常状态下对 CPU 资源的占用小于 6 个百分点,对

内存资源的占用为几十 M。

1.4.3.6. 网络资源的使用

因为 Shareplex 复制操作只是读取操作系统的日志文件,同时通过 TCP/IP 方式而不是采用中

间件方式传输只发生改变的数据也使网络负载降至最低。Shareplex 只将日志的三分之一的内容通

过网络进行传输。实际每小时传输的数据量=每小时日志文件切换的数量*日志文件的大小*1/3 。

例如用户峰值每小时生成的日志量为 720M。

实际峰值期间每小时传输的数据量=每小时日志文件切换的数量*日志文件的大小

*1/3=720/3=240M

每秒传输的数据量=240/3600 M=1/15 M

考虑 20%的传输开销,所需要的带宽为 1*1.2/15=80KB/S,系统对传输带宽的要求为 640kbps。 2005 年 5 月 4 期 总第 4 期

- 52 -

Page 53: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

1.5. 关于 Quest Software

Quest Software(http://www.quest.com)是一家致力于提供保证信息系统和应用程序高性能及

高可用性的公司。其产品专业化强,设计细腻,易于使用,被全世界广大用户所使用,在同类产

品中具有绝对领先的技术和市场优势。正因为Quest产品的优良性能,Quest Software从公司创立开

始,每个季度都盈利,公司发展相当稳健。在针对Oracle数据库管理方面,还没有任何其他公司的

产品在功能上、性能上和产品的易用性上和Quest Software的上述产品相媲美。

Quest Software, Inc. (NASDAQ: QSFT) 是业界领先的应用管理解决方案供应商。致力于通过

改善企业关键应用的性能和可用性,降低其运行成本,帮助 IT 专业人员高效率地完成关键业务

数据和数据库的管理工作。

Quest Software 成立于 1987 年,总部位于加州 Irvine,全球员工总数超过 2000 名,产品用户

达到 120000 多个。

Quest Software 的全线产品不仅可以管理包括 Oracle,、IBM 和 Microsoft 在内的数据库应用,

也为包括 Oracle E-Business Suite,、Siebel eBusiness Applications、mySAP.com、Microsoft Exchange 及

PeopleSoft 等企业级应用系统提供了最佳的管理方案。

Quest 产品专业化强,设计细腻,易于使用,被全世界广大用户所使用,在同类产品中具有绝

对领先的技术和市场优势。相关产品系列包括:

应用监控解决方案,包括系统、数据库和应用监控。

数据库管理解决方案。

Microsoft 解决方案。

Quest 在中国拥有了大量的客户,其中包括贵州联通,北京移动,福建移动,北京电信,哈尔滨电信,

湖南电信,湖北电信,新疆移动,天津电信,大唐电信等一大批企业级电信用户。而且以其产品

的适用性和高品质博得了用户的赞誉。

1.6. SharePlex for Oracle 部分成功案例

贵州联通

实现了电信级生产数据库的实时灾难备份功能,提供应用的快速接管以及强大的数据恢复功

能;同时在容灾数据库上分担了报表业务。

天津地税

实现了天津地税内外网业务数据的交换,以及内外网数据在报表数据库的汇总。使企业用户

可以自由选择网上或营业厅报税,已成为天津地税业务逻辑中的关键环节。

2005 年 5 月 4 期 总第 4 期

- 53 -

Page 54: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

澳大利亚 NEMMCO 公司

12 个大型生产数据库的实时容灾,将计划内和计划外停机时间降到最低。

eBay

关键数据的容灾以及与 F5 集成的解决方案,实现了大型在线交易系统中数据读写分离的负载

均衡。

Honeywell 公司

实现报表数据的实时抽取,彻底改变了原来需要停机进行报表数据复制的状况。

作者简介:

姓名:李聪

网名:lc7888

擅长的技术领域:Oracle 数据库容灾、复制及优化

目前的工作动态:现供职于 Quest Software China

MSN:[email protected]

QQ:3401743

E-mail:[email protected]

2005 年 5 月 4 期 总第 4 期

- 54 -

Page 55: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

博文精品图书连载

《Oracle JDeveloper 10g 与 J2EE 实践演练》

第一章 Oracle 应用程序开发框架(ADF)简介

本文供稿:博文视点资讯有限公司(http://www.broadview.com.cn)

Oracle JDeveloper 10g 推出革命性的 J2EE 开发框架 —— Oracle Application Development

Framework(ADF)。由于 Oracle ADF 是以 J2EE 设计模式为基础的,不仅可以帮助程序设计师

开发更稳固的 J2EE 应用系统,也可以大幅提升程序撰写效率,缩短开发时间。本章将简介 Oracle

ADF 的基本观念,以及 Oracle JDeveloper 10g 的重要开发特性。

介绍 Oracle ADF 之前,笔者先说明 J2EE 应用程序模型的基本架构。

1.1. J2EE 应用程序模型简介

在开发企业级应用系统时,除了要考虑如何集成企业内部流程,也要思考如何集成企业间的宝

贵资源。因此,企业级运算环境必须具备下列特性:

高稳定性与可用性。

严密的安全性。

高扩展性(扩充性)。

执行性能佳。

换言之,企业级应用系统的首要条件应为:“最具扩展性的多层式架构”加上“跨平台系统集

成能力”。事实证明,由 Sun 主导的 J2EE 架构正是企业级应用系统的完美典范。构筑在 J2EE 架

构之上,企业级应用系统的两大核心部分 —— “数据库”与“业务逻辑”得以独立,并可各自

搭配适当的操作平台与系统,其中:

数据库:存放企业内部所有数据。可搭配的关系型数据库包括:Oracle、DB2、Sybase 与 SQL Server。执行平台则有 Sun Solaris、IBM AIX、HP-UX、Microsoft Windows 与 Linux 等。

业务逻辑:泛指数据处理与运算技术,可撰写成独立组件运行于特定应用程序服务器上。

这部分涵盖的技术主要有:JSP、Servlet、EJB、JDBC 等。主要的执行环境则有:BEA Weblogic、IBM WebSphere、Oracle Application Server、Sun Java System Application Server

2005 年 5 月 4 期 总第 4 期

- 55 -

Page 56: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

与 Borland Enterprise Server 等应用程序服务器

J2EE 应用程序模型如图 1-1 所示。

图 1-1 J2EE 应用程序模型(数据来源:http://java.sum.com/j2ee)

1.2. Oracle 应用程序开发框架(ADF)

在遵循 Sun 所主导的 J2EE 运算架构之下,程序设计师们得以建构健壮的 Java 应用系统,

但是免不了需要撰写大量程序代码。为此,JDeveloper 10g 提出 Oracle Application Development

Framework(ADF)技术(如图 1-2 所示)。Oracle ADF 是以 Model-View-Controller(MVC)为主

轴的 J2EE 应用程序开发框架。凭借着 Oracle ADF,开发人员将更容易掌握 J2EE 架构内各种程

序组件,也可以利用 JDeveloper 可视化开发环境撰写 J2EE 应用程序,快速部署至 J2EE 应用程

序服务器。

从应用系统架构的角度来看,Oracle ADF 分为四层:

1.2.1. Business Services(业务服务层)

“业务服务层”提供应用程序与数据库之间的存取机制,包括:数据持久储存(data persistence)、

对象关联映射(object/relational mapping)、事务处理以及业务逻辑定义。

2005 年 5 月 4 期 总第 4 期

- 56 -

Page 57: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

1.2.2. Model(数据模型层)

在“业务服务层”之上提供抽象的数据存取接口。撰写 View 或 Controller 组件时,开发人

员可经由一致的数据绑定机制存取“业务服务层”的各项服务。

图 1-2 Oracle ADF 架构

1.2.3. Controller(控制层)

“控制层”可以控管 Web 应用程序的网页执行流程。在以 Java 为基础的 Web 应用程序中,

通常是以 Servlet 来实现控制层组件。Oracle ADF 是以 Jakarta Struts 来实现“控制层”架构的。

1.2.4. View(展示层)

提供应用系统的“用户操作接口”,可以是 JSP、XML、UIX 或是一般 Swing Client 应用程

序。

表 1-1 整理出 Oracle ADF 所涵盖的开发技术与应用程序组件。

表 1-1 Oracle ADF 涵盖的开发技术

ADF Layer 涵盖的开发技术 / 应用程序组件

Business Services ADF Business Components、TopLink Objects、Web Services、EJB、Java Bean

Model ADF Databindings、ADF Data Controls

Controller Struts

2005 年 5 月 4 期 总第 4 期

- 57 -

Page 58: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

View JSP、UIX、XML、Swing Client

1.3. Oracle JDeveloper 10g 功能概览

Oracle JDeveloper 10g 集成了 UML 建模设计、可视化程序开发、程序代码调试,以及软件配

置管理等功能,让程序开发者能够在 J2EE 架构下快速建构出 JavaBean、Servlets、JavaServer

Pages、EJB 与 CORBA 对象,是一个全方位的 J2EE 开发环境。本节将简介 JDeveloper 较重要

的开发特性。

1.3.1. 可视化的 Oracle ADF 开发环境

针对 Oracle ADF 的四个级别,JDeveloper 10g 提供各种可视化开发环境,可协助您完成下列

工作:

开发“业务服务层”组件(例如 EJB 或 ADF 业务组件)。

在 JSP 与 JClient 应用程序内实现数据绑定功能。

设计 Web 应用程序的网页执行流程。

1.3.1.1. 开发“业务服务层”组件

JDeveloper 提供可视化的 UML 建模功能。藉由 Drag & Drop 方式,您可以将 EJB、Web

Services 或是 ADF 业务组件(Business Components)加入 UML 图形,JDeveloper 将自动配置

并产生相对应的文件。

以图 1-3 为例,Business Component 组件面板提供各种 Oracle ADF Business Components 相

关图标,您可以利用它来建构“业务服务层”的 ADF 业务组件,包括:Entity Object、View Object

与 Application Module(本书第 11 章将介绍如何创建 ADF 业务组件)。

针对 Oracle ADF 业务组件,JDeveloper 10g 的 Business Component Browser 允许您直接浏览

与存取 ADF 业务组件所对应的数据,不用等到程序撰写好才能测试数据库存取功能。这一点在

开发数据库应用程序时显得格外便利(图 1-4)。

2005 年 5 月 4 期 总第 4 期

- 58 -

Page 59: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

1.3.1.2. Oracle ADF 数据绑定功能

如前所述,“数据模型层”提供一致的数据存取接口。只要创建适当的 ADF 业务组件,

JDeveloper 便会自动配置其“数据控制项”(Data Controls)。藉由 ADF 数据控制项的数据绑定

功能,开发人员可以直接将数据对象拖曳至 JSP 或 Swing Client 应用程序,使其具备动态数据存

取功能(图 1-5)。

图 1-3 ADF 业务组件的 UML 建模功能

图 1-4 利用 Oracle Business Component Browser 测试 ADF 业务组件

2005 年 5 月 4 期 总第 4 期

- 59 -

Page 60: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

图 1-5 利用 ADF 数据控制项的数据绑定功能开发 JSP

1.3.1.3. 设计 Web 应用程序网页流程

在 Oracle ADF 中,“控制层”是以 Jakarta Struts 来实现的,这意味着 JDeveloper 已完全支

持 Struts 开发框架。您可以通过可视化的 Struts Page Flow Diagram 定义网页流程(图 1-6),或

是利用 Struts Config Editor (图 1-7)配置各种 Struts 组件(例如 Action、Form Bean、Forward)。

如此一来,Web 应用程序的网页流程将更容易操控与维护。

1.3.2. 全面涵盖 J2EE 开发生命周期

完整的 J2EE 应用程序开发周期需包含:系统分析与设计、程序代码撰写、测试与调试、应

用程序部署以及性能调校等阶段。JDeveloper 针对上述各项均提供全面支持,例如:UML 建模工

具(图 1-8)可协助您进行系统设计与对象模型设置,UI Editor (图 1-9)可进行可视化的组件配

置;Deployment Profiles 节点(位于[New Gallery]对话框)提供各种应用程序的部署方法(图 1-10、

图 1-11)。

2005 年 5 月 4 期 总第 4 期

- 60 -

Page 61: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

图 1-6 可视化 Struts 开发环境

图 1-7 利用 Struts Config Editor 编辑 struts-config.xml

2005 年 5 月 4 期 总第 4 期

- 61 -

Page 62: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

图 1-8 利用 UML 类图建模 EJB 应用程序

图 1-9 可视化开发环境 —— UI Editor

2005 年 5 月 4 期 总第 4 期

- 62 -

Page 63: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

图 1-10 包含各种调试窗口的 JDeveloper 调试器

图 1-11 支持多种应用程序部署方法

1.3.3. 功能完整的 Java 程序编辑器

针对一般 Java 应用程序,JDeveloper 提供三种编辑环境:

Code Editor:Java 程序代码编辑器,提供 Code Insight 与 Code Templates 等编辑功能。

2005 年 5 月 4 期 总第 4 期

- 63 -

Page 64: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

Class Editor:类编辑器,可快速创建 Java 类的属性、方法或事件(图 1-12)。

UI Editor:用户接口编辑器,可经由可视化方式配置各种 UI 组件。

图 1-12 利用 Class Editor 管理 Java 类的方法

1.3.4. 高效率的 Web 应用程序开发环境

JDeveloper 提供了多种 Web 应用程序开发向导,不仅可协助您快速创建 Servlet (图 1-13)

与 JSP,也会自动编辑 web.xml 部署描述文件。更特别的是,JDeveloper 内建 Oracle Application

Server 的核心引擎 —— OC4J。这意味着您可以在 JDeveloper 开发与测试 Web 应用程序,确认

所有功能均运行正常后,再将它部署至正式环境。

2005 年 5 月 4 期 总第 4 期

- 64 -

Page 65: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

图 1-13 利用 Create HTTP Servlet Wizard 开发 Servlet

1.3.5. 内建 Oracle 数据库客户端工具

JDeveloper 与 Oracle 数据库紧密地结合,除了内建 PL/SQL Editor 与 SQL Worksheet(图

1-14),也允许开发人员直接管理数据库对象(需具备适当权限),包括:

创建表(table)或视图(view)。

执行 SQL 查询指令。

将 Java 程序部署至数据库(例如执行 loadjava 指令)。

撰写 PL/SQL 程序,例如存储过程(procedure)、函数(function)、包(package)等。

针对 PL/SQL 存储过程进行调试。

2005 年 5 月 4 期 总第 4 期

- 65 -

Page 66: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

图 1-14 利用 SQL Worksheet 执行 SELECT 指令

1.3.6. 提供 XML 语法检查功能

JDeveloper 集成了 Oracle XML Developer Kit(XDK),可以让 Java 程序设计师撰写各种 XML

应用程序、创建与转换 XML 文件,或是自动检查 XML 语法是否正确(图 1-15)。

图 1-15 JDeveloper 内建的 XML 语法检查功能

1.3.7. Web Services 集成开发环境

为提高 Web Services 开发效率,JDeveloper 10g 提供可视化的 Web Services 建模环境 ——

Web Service Diagram (图 1-16),可用来建模 Web Services 架构、产生 WSDL 文件,或是创建

客户端测试程序。

2005 年 5 月 4 期 总第 4 期

- 66 -

Page 67: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

图 1-16 可视化的 Web Services 开发环境

1.4. 结语

本章简单介绍了 Oracle Application Development Framework(ADF)的基本概念,以及 Oracle

JDeveloper 10g 的开发特性。藉由 JDeveloper 10g 优异的可视化开发环境,您将更容易建构与自

定义 J2EE 应用系统,打造企业级运算环境。

为了实际演练 J2EE 应用程序开发过程,第 2 章与第 3 章会带领您安装 JDeveloper 10g、Oracle

Application Server Containers for J2EE(OC4J)以及 Oracle 10g 数据库服务器。从第 4 章开始,笔

者将逐一展示 JDeveloper 10g 卓越的开发功能。

1.5. 本书相关资源

作者: 何致亿

出版社: 电子工业出版社

ISBN 书

号:

7-121-00501-8

相 关 链

接:

http://www.dearbook.com/book/viewbook.aspx?pno=TS0027476

2005 年 5 月 4 期 总第 4 期

- 67 -

Page 68: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

博文视点简介:

成立

博文视点资讯有限公司(BROADVIEW Information Co.,Ltd.)于 2003 年 6 月 18 日正式成立 ,

是信息产业部直属中央一级科技与教育出版社——电子工业出版社(PHEI)与国内最大的

IT 技术网站 CSDN.NET 和最具专业水准的 IT 杂志社《程序员》合资成立的以 IT 图书出

版为主业、开展相关信息和知识增值服务的资讯公司。

理念

创新专业出版体制;培养职业出版队伍;打造精品出版品牌;完善全面出版服务。

目标

秉承博文视点的理念,博文视点的产品线为面向 IT 专业人员的出版物和相关服务。博文

视点将重点做好以下工作:

(1) 在技术领域开发专业作(译)者群体和高质量的原创图书。

(2) 在图书领域建立专业的选题策划和审读机制。

(3) 在市场领域开创有效的宣传手段和营销渠道。

博文视点有效地综合了电子工业出版社、《程序员》杂志社和 CSDN.NET 的资源和人才,

建立全新专业的立体出版机制,确立独特的出版特色和优势。博文视点将力争打造出 IT

出版领域的著名品牌,并成为中国最具影响力的专业 IT 出版和服务提供商。

团队

作为合资公司,博文视点团队融合了各方面的精英力量:原代表电子工业出版社 IT 图书

专业部的团队——计算机图书事业部的团队;《程序员》杂志和 CSDN 网站的主创人员;

著名 IT 专业图书策划人周筠女士及其创作群。这是一个整合专业技术人员和专业出版人

员的精锐团队;这是一个充满创新意识和创业激情的团队;这是一个不断进取、追求卓越

的团队。

实力

电子工业出版社与《程序员》杂志和 CSDN 网站的合作以最有效率的方式形成了出版资源、

媒体资源、网络资源的整合和互动,成为 2003 年 IT 出版界倍受瞩目的事件。

技术凝聚实力 专业创新出版

2005 年 5 月 4 期 总第 4 期

- 68 -

Page 69: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 5 月 4 期 总第 4 期

- 69 -

关关于于 CCSSDDNN

eMag 代表着 CSDN 社区电子杂志项目。其含义是:由 CSDN 发起并组织的,以社区为

依托并服务于社区的,电子杂志项目。项目所需的资源主要都是来源于社区,而且做出的各

种杂志也会以各种方式无偿的向社区发布。《Oracle 杂志》属于 eMag 电子杂志项目的成

员之一,由 CSDN 主办。

中国软件开发网www.csdn.net,是北京百联美达美数码科技有限公司旗下的,

面向中文地区IT专业技术人员的门户网站,拥有最大的中文IT专业综合社区,其个人

及企业会员遍及中国大陆、台湾、香港、新加坡、马来西亚等地区;截至 2005 年 3

月,拥有 100 万个人注册会员、来自 2.0 万家企业单位。

北京百联美达美数码科技有限公司,是面向职业软件开发人员和企业的专业技术

资讯服务平台。自 1999 年成立,公司就以提高中国软件技术水平、关注技术人才发

展为己任,针对国内缺乏技术交流平台和人才培养体系的现状,以 CSDN 网站为中心,

面向职业软件开发人员,整合了多种业务,包括网站、期刊杂志、图书出版、电子商

务、教育培训、会展活动等,建立了完整的专业知识传播链,形成了独特的立体式互

动运营模式,致力于提供权威的、前沿的、全面的技术资讯服务,同时满足职业软件

开发者个人成长和软件企业发展的多种需求,打造出全面的专业技术信息服务平台。

Page 70: Csdn Emag(Oracle)第四期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

公司旗下业务群包括:

中 国 软 件 开 发 网

www.csdn.net

软件开发领域的专业门户网站,专注 IT 技术,传

播技术资讯,服务于职业软件开发者及企业;

《程序员》杂志 国内唯一关注职业程序员发展的 IT 技术杂志;

《MSDN 开发精选》杂志 面向微软技术开发人员的国际化技术权威杂志;

北京博文视点资讯有限公司 面向 IT 专业出版的图书出版公司;

第 二 书 店

www.dearbook.com

最具权威性的 IT 专业商务网站,销售 IT 专业图书

期刊;

2005 年 5 月 4 期 总第 4 期

- 70 -