TIMESTEN内存数据库-最佳实践(已翻译)

TimesTen内存数据库

第一章 Cache Connect to Oracle概念

TimesTen数据交换技术提供在Oracle数据库和TimesTen数据管理器之间进行连接和双向数据传送。数据交换技术也使得能够方便的捕获和处理进入到TimesTen数据管理器的大流量事件流,并且能进行并发传送数据到Oracle数据库。

TimesTen允许通过创建cache group来高速缓存Oracle数据,以在TimesTen中映射一个或多个Oracle表。

允许高速缓存Oracle数据的TimesTen联合特征就作为Cache Connect to Oracle

关于高速缓存集合

一个cache group就是描述被高速缓存到TimesTen数据存储中的Oracle数据。高速缓存集合可以创建来高速缓存一个单表的所有或部分数据,或一个相关的Oracle数据表集。

高速缓存集合可以使用CREATE CACHE GROUP SQL语句或基于浏览器的Cache Administrator(Chapter 6, “CacheAdministrator.”)来创建。

图 1.1 显示名为target_customers高速缓存集合缓存Oracle表table customer。高速缓存集合中的数据是存储在Oracle数据库中所有用户的大数据集的一个子集。

1.1 高速缓存一个表

TIMESTEN内存数据库-最佳实践(已翻译)_第1张图片

如果定义一个root table和多个child tables,则可以在同一个高速缓存集合中缓存多个Oracle表。在一个高速缓存集合中只能有一个root table

在拥有多个表的高速缓存集合中,每个子表必须通过一个外键约束连接到高速缓存集合中的根表或另一个子表。尽管TimesTen中缓存的表必须使用外键连接约束,但这些表在Oracle实例中不一定必须有连接。缓存集合中的根表不能通过外键约束来引用缓存集合中的任何其它表。所有缓存集合中的其它表都是子表

从Oracle加载到TimesTen缓存集合中的基本单位是cache instance,用来描述通过外键与根表特定行相关联的行集。缓存集合中每个表中粗体显示的是由根表中主键为122标识的缓存实例。此cache instance key确定根表中的行和引用此行的子表中所有的行。

图 1.2显示缓存集合target_customers中的表。根表是customerordersorder_item是子表。

1.2 高速缓存多个表

TIMESTEN内存数据库-最佳实践(已翻译)_第2张图片

在TimesTen缓存和Oracle之间交换数据

如图 1.3所示,flushpropagate表示从TimesTen缓存拷贝表数据到Oracle,loadrefresh表示从Oracle拷贝数据到TimesTen缓存。

1.3 TimesTenOracle之间交换数据

TIMESTEN内存数据库-最佳实践(已翻译)_第3张图片

至于怎样将缓存集合中的数据传送到Oracle和从Oracle刷新数据,将依据所选择的缓存集合的类型。

缓存集合类型

缓存集合的基本类型为:

• READONLY缓存集合。

READONLY缓存集合通过AUTOREFRESH机制来将Oracle表中的更新进行强制缓存以应用到TimesTen。

• SYNCHRONOUS WRITETHROUGH (SWT) 缓存集合。

SYNCHRONOUS WRITETHROUGH (SWT)缓存集合将强制把集合中的缓存数据更新至TimesTen,并且发送到Oracle。SWT缓存集合的更新将被进行同步提交(Oracle)。

• ASYNCHRONOUS WRITETHROUGH (AWT)缓存集合。

ASYNCHROUNOUS WRITETHROUGH (AWT)缓存集合将强制把集合中的缓存数据更新至TimesTen,并且发送到Oracle。AWT缓存集合的更新将被进行异步提交(Oracle)。

• USERMANAGED缓存集合。

USERMANAGED缓存集合可以进行自定义。例如,USERMANAGED缓存集合中的表可以拥有READONLY或PROPAGATE属性。

第二章 快速开始

这章将讨论怎样使用SQL语句来创建并管理简单的缓存集合。也可使用基于浏览器的Cache Administrator来创建缓存集合。

安装TimesTen和Oracle

在能够创建缓存集合之前,必须安装TimesTen和Oracle环境。完成以下任务:

1. 在TimesTen主机上安装Oracle Client。

2. 创建必需的Oracle帐号。

3. 创建一个TimesTen帐号。

4. 创建TimesTen DSN。

在TimesTen主机上安装Oracle Client

Cache Connect to Oracle特性使用Oracle共享库来与Oracle数据库进行通信。可以通过在安装了TimesTen的机器上安装Oracle Client来安装这些库文件。安装Oracle 9i Client或Oracle Database 10g。Oracle客户端的版本不必与Oracle服务器端的版本相同。Cache Connect支持下面的Oracle客户端和服务器端的版本:

• Oracle 10g Release 2 (Oracle 10.2.0.1.0 或之后)

• Oracle 10g Release 1 (Oracle 10.1.0.5.0或之后)

• Oracle 9i Release 2 (Oracle 9.2.0.8.0或之后)

安装Oracle Client时,选择Application User Installation Type。不必专门配置一个服务目录来用于Cache Connect to Oracle,所以可以跳过安装过程的这一步。

安装Oracle Client以后,安装TimesTen。

注意:如果在安装Oracle Client之前安装了TimesTen,必须重新启动操作系统(Windows)或TimesTenUNIX)。

创建必需的Oracle帐号

在能够使用Cache Connect to Oracle之前,必须从数据库管理员处获得一个Oracle帐号。如果操作者实际拥有数据库管理权限,则在Oracle服务器上打开命令窗口并启动SQL*Plus,以系统管理员身份登录:

sqlplus system/password@Oracle_Service_Name

例如,为了在由连接串、system1确定的Oracle数据库上给testuser创建一个新Oracle帐号,操作如下:

sqlplus system/manager@system1

SQL> CREATE USER testuser IDENTIFIED BY 11;

SQL> GRANT connect, resource, create any trigger TO cddbo;

SQL> COMMIT;

SQL> EXIT

为了与本章余下的部分讨论的一些示例缓存集合操作保持一致,Oracle用户为cddbo,口令为11,并且是system1中的一个Oracle帐号。

在TimesTen上创建一个帐号

作为实例管理者,使用ttIsql工具来连接到数据存储TT_tt70_32.。数据存储实例由TimesTen在安装时定义,用来使实例管理者能够执行数据存储连接管理任务。

然后使用CREATE USER和GRANT语句来创建一个名为cddbo的用户,拥有ADMIN和DDL权限:

ttIsql TT_tt70_32.

Command> CREATE USER pgmrnew IDENTIFIED BY 'pgmrnew';

Command> GRANT ADMIN, DDL TO pgmrnew;

注意:此帐号必须与Oracle数据库帐号和口令相同

创建TimesTen DSN

在Window系统中,创建一简单的TimesTen系统数据存储(System DSN),名称为cddboDSN。

关于cddboDSN,设置如下:

• Data Store Path and Name:c:/temp/ cddbods

• Permanent Data Sz (MB):16

• Temporary Data Sz (MB):16

• User ID:pgmrnew(此ID也用作Oracle User ID)

• Oracle ID:orcl

• Oracle Password:pgmrnew

• DatabaseCharacterSet:ZHS16GBK。此数据库字符集必须与Oracle数据库字符集相同。为了得到Oracle数据库字符集信息,在Oracle数据库上输入下列查询:

SELECT value FROM nls_database_parameters

WHERE parameter='NLS_CHARACTERSET';

对于其余设置,使用缺省值。

创建READONLY缓存集合

在已经安装TimesTen和Oracle并进行配置以后,就可以创建缓存集合。

这部分将讨论怎样创建一个简单READONLY缓存集合,以缓存Oracle数据库中单一表中的内容。尽管一个缓存集合可以由多个表组成,这里只缓存一个Oracle表以保持示例的简单。

图 2.1 显示一个缓存一单个Oracle表的READONLY缓存集合。

2.1 简单READONLY缓存集合

TIMESTEN内存数据库-最佳实践(已翻译)_第4张图片

第1步:创建一Oracle表

2.2 创建一Oracle

TIMESTEN内存数据库-最佳实践(已翻译)_第5张图片

连接到新帐号并创建一数据表:

sqlplus testuser/mypsswrd@system1

SQL> CREATE TABLE readtab (a NUMBER NOT NULL PRIMARY KEY,

b VARCHAR2(31));

然后插入一些记录并进行提交:

SQL> INSERT INTO readtab VALUES (1, 'hello');

1 row created.

SQL> INSERT INTO readtab VALUES (2, 'world');

1 row created.

SQL> COMMIT;

Commit completed.

第2步:创建缓存集合

2.3 创建READONLY缓存集合

TIMESTEN内存数据库-最佳实践(已翻译)_第6张图片

使用ttIsql工具来连接cddboDSN数据存储。在命令提示符下,使用ttCacheUidPwdSet程序来传递缓存管理用户ID和口令作为参数。然后调用ttCacheStart程序来为数据存储启动缓存代理。在这个示例中,缓存管理用户ID是cddbo,并且口令为11:

> ttIsql cddboDSN

Command> call ttCacheUidPwdSet('pgmrnew','pgmrnew');

Command> call ttCacheStart;

接下来,使用CREATE CACHE GROUP语句来创建名为readcache的READONLY缓存集合,用来在TimesTen中缓存Oracle表tsr20_user的内容:

Command> CREATE READONLY CACHE GROUP readcache

> AUTOREFRESH INTERVAL 5 SECONDS

> FROM tsr20_user

>(code char(5) NOT NULL PRIMARY KEY, name VARCHAR(20) NOT NULL);

第3步:加载缓存集合

加载Oracle表中的内容到缓存集合表中。

Command> LOAD CACHE GROUP readcache COMMIT EVERY 256 ROWS;

185 cache instances affected.

检查tsr20_user表的内容:

Command> SELECT * FROM tsr20_user;

< -000, test >

……………………

< 05999, 系统管理员05999 >

185 rows found

使用ttIsql cachegroups命令来检查READCACHE缓存集合的定义:

Command> cachegroups;

Cache Group TESTUSER.READCACHE:

Cache Group Type: Read Only

Autorefresh: Yes

Autorefresh Mode: Incremental

Autorefresh State: On

Autorefresh Interval: 5 Seconds

Root Table: PGMRNEW.TSR20_USER

Table Type: Read Only

1 cache group found.

第4步:更新Oracle表

2.4 使用Oracle更新自动刷新TimesTen

TIMESTEN内存数据库-最佳实践(已翻译)_第7张图片

使用SQL*Plus,插入多行到READTAB并提交事务:

SQL> INSERT INTO readtab VALUES (3, 'Hello');

1 row created.

SQL> INSERT INTO readtab VALUES (4, 'Again');

1 row created.

SQL> COMMIT;

Commit completed.

5秒之后,TimesTen将从Oracle自动刷新缓存数据。在ttIsql中检查READTAB表的内容:

Command> SELECT * FROM readtab;

< 1, hello >

< 2, world >

< 3, Hello >

< 4, Again >

4 rows found

第5步:删除缓存集合

在TimesTen窗口中,使用DROP CACHE GROUP语句从TimesTen数据存储中删除缓存集合:

Command> DROP CACHE GROUP readcache;

第6步:停止缓存集合

调用ttCacheStop程序停止数据存储的缓存代理:

Command> call ttCacheStop;

激活SQL passthrough特性

这部分将讨论怎样在DSN中设置PassThrough属性来命令TimesTen通过SQL定向到Oracle。

图 2.5 显示从一个应用将SQL传递到Oracle表。缓存表通过自动刷新机制从Oracle接收更新。

2.5 Cache Group to Oracle传递SQL

TIMESTEN内存数据库-最佳实践(已翻译)_第8张图片

第1步:创建新的TimesTen DSN

在Window系统中,创建一新的TimesTen系统数据源(System DSN),名称为cddboPT,使用与指定给cddboDSN的相同的属性。另外,设置PassThrough属性值为‘2’,以直接传递不在缓存集合中的Oracle表的查询和程序调用到Oracle。

对于cddboPT,设置如下:

• Data Store Path and Name: c:/temp/cgPT2d

• Permanent Data Sz (MB): 16

• Temporary Data Sz (MB): 16

• User ID: pgmrnew (此ID也用作Oracle User ID)

• Oracle ID: orcl

• Oracle Password: pgmrnew

• PassThrough: 2

• DatabaseCharacterSet: ZHS16GBK。此数据库字符集必须与Oracle数据库字符集相同。为了得到Oracle数据库字符集信息,在Oracle数据库上输入下列查询:

SELECT value FROM nls_database_parameters

WHERE parameter='NLS_CHARACTERSET';

对于其余设置,使用缺省值。

第2步:创建READONLY缓存集合

2.6 创建READONLY缓相聚集合

TIMESTEN内存数据库-最佳实践(已翻译)_第9张图片

在TimesTen窗口中,连接到DSN cddboPT,设置缓存管理用户ID和口令,启动缓存代理,并创建READONLY缓存集合:

ttIsql cgPT2

Command> call ttCacheUidPwdSet('pgmrnew','pgmrnew');

Command> call ttCacheStart;

Command> CREATE READONLY CACHE GROUP readcache

> AUTOREFRESH INTERVAL 5 SECONDS

> FROM tsr20_user

> (code char(5) NOT NULL PRIMARY KEY, name VARCHAR(20) NOT NULL);

第3步:加载缓存集合

加载Oracle表的内容到缓存集合表中。

Command> LOAD CACHE GROUP readcache COMMIT EVERY 256 ROWS;

4 cache instances affected.

第4步:更新缓存集合表

2.7 更新TimesTen缓存集合表

TIMESTEN内存数据库-最佳实践(已翻译)_第10张图片

使用ttIsql,插入一些行到tsr20_user:

Command> INSERT INTO tsr20_user VALUES ('0001','Just','00000', 'dd','0000','1',NULL);

1 row inserted.

Command> INSERT INTO tsr20_user VALUES ('0002',' Passing ','00000', 'dd','0000','1',NULL);

1 row inserted.

Command> INSERT INTO tsr20_user VALUES ('0002',' Through ','00000', 'dd','0000','1',NULL);

1 row inserted.

使用SQL*Plus检查 check the contents of the readtab table on Oracle:

SQL> SELECT * FROM tsr20_user;

CODE NAME

---------- -------------------------------

-000 test

……………………

05999 系统管理员05999

187 rows selected.

然后使用ttIsql检查TimesTen中表tsr20_user的内容:

Command> SELECT * FROM tsr20_user;

< -000, test >

……………………

< 05999, 系统管理员05999 >

187 rows found

第5步:删除缓存集合

使用ttIsql,输入DROP CACHE GROUP语句来从TimesTen数据存储中删除缓存集合:

Command> DROP CACHE GROUP readcache;

第6步:停止缓存代理

调用ttCacheStop程序来停止数据存储的缓存代理:

Command> call ttCacheStop;

创建缓存集合任务列表

表 2.1 创建缓存集合任务列表

任务序号

1

确保已经安装Cache Connect to Oracle。使用ttIsql来验证:

connect “uid=myuid;pwd=mypwd;OraclePWD=mypwd;passthrough=3”;

SELECT COUNT(*) FROM DUAL;

exit

此查询应该返回1。如果不是,则检查以下内容:

• 设置以下环境变更:ORACLE_HOME、LD_LIBRARY_PATH、SHLIB_PATH

• 缓存管理用户ID和口令,以及Oracle ID

• Oracle服务器的状态

2

对所有要创建的缓存集合设计缓存集合计划。可能使用Cache

Administrator。

3

确保有足够的资源来加载所有的缓存集合。

设置First Connection属性:

PermSize – 可以首先创建缓存集合,然后使用ttSize工具来估算PermSize属性的值。必须估算要使用ttSize工具进行缓存的行数。

TempSize – 没有必要的意义。

DatabaseCharacterSet – 确保它与Oracle数据库字符集相匹配。

文件系统大小推荐:

• 数据存储目录应足够大以处理两个检查点文件。每个检查点文件的最大值为20 MB + PermSize

• 日志目录应足够大以处理积累在检查点之间的日志文件。注意,如果在自动刷新间隔期间Oracle表中有大量的更新,自动刷新事务可能相当大。 一个对于日志目录大小的处理规则是使它等于数据存储的大小加上3倍的LogFileSize的3倍。

• 临时目录应放在快速文件系统中,以提高执行大事务的速度。可以通过设置TMPDIR环境变量(UNIX)或TEMP环境变更(Window)来指定临时目录用于自动刷新操作。在设置环境变量之后,重新启动TimesTen

Daemon(UNIX)或机器(Window)。一个很大自动刷新事务在临时目录中要求很大空间。

4

如果缓存集合是自动刷新或异步写方式,要设置缓存管理用户ID和口令。缓存管理用户ID必须是一个Oracle用户,并且必须有相应的权限。

5

启动缓存代理。如果计划使用非日志模式(参阅第7步),则跳过此步。

6

创建并提交所有的缓存集合。

7

(选项)使用非日志模式加载缓存集合。

为了更快执行和降低资源使用,可以在非日志模式中加载缓存集合。非日志模式的缺点是:

• 所有到TimesTen数据存储已存在的连接必须停止。

• 加载操作不能进行复制。

执行下列任务来使用非日志模式加载缓存集合:

a. 如果正在运行的话,停止缓存代理、复制代理以及TimesTen服务。

b. 断开所有连接到TimesTen数据存储的应用。

c. 使用First Connection attributes Logging=0、DurableCommits=0、LockLevel=1属性连接到数据存储。.

d. 为每个集合发送下列SQL语句:LOAD CACHE GROUP

cache_group_name COMMIT EVERY 0 ROWS。

e. 在加载每个缓存集合之后,提交事务并发送一个检查点。

f. 使用日志重新将应用连接到TimesTen数据存储。

g. 启动缓存代理。

8

如果需要复制,则在缓存集合表上创建TimesTen复制计划。

9

如果要复制缓存集合表或缓存集合是异步写(AWT)方式,则启动复制代理。

注意:当复制代理正在运行时,不能创建或删除AWT缓存集合。

10

加载缓存集合并提交(如果不执行第7步)。使用LOAD

CACHE GROUP cache_group_name COMMIT EVERY n ROWS。对于n的推荐值为256。

第三章 定义缓存集合

这章将讨论不同的缓存集合类型以及怎样进行定义。

创建缓存集合定义

可以使用CREATE CACHE GROUP语句来创建一个缓存集合定义,包括为每个将被缓存的Oracle表分别定义缓存表。

表 3.1 显示一个简单缓存集合定义的组成。缓存集合定义的每个部分将在下面部分讨论。

表 3.1 缓存集合定义的组成

组 成

CREATE type CACHE GROUP

owner.name

Cache group and table

attributes

FROM table definition

[WHERE ...]

[AGING ...]

也可以使用Web浏览器通过Cache Administrator来创建缓存集合。

缓存集合命名

在CREATE CACHE GROUP语句中,缓存集合的名称标识使用如下形式:

owner.name

如果在缓存集合的名称中不指定owner,则ID或当前会话用户将作为owner。

选择缓存集合类型

缓存集合类型可以是系统管理用户管理系统管理缓存集合强制指定数据操作,而用户管理缓存集合的数据操作可以自定义。系统管理缓存集合包括:

• READONLY cache groups

• SYNCHRONOUS WRITETHROUGH (SWT) cache groups

• ASYNCHRONOUS WRITETHROUGH (AWT) cache groups

READONLY缓存集合

A READONLY缓存集合通过AUTOREFRESH机制进行强制缓存操作,将Oracle表中的更新应用到TimesTen。此缓存不能进行直接更新。

图 3.1 显示一个READONLY缓存集合

3.1 READONLY缓存集合

TIMESTEN内存数据库-最佳实践(已翻译)_第11张图片

使用CREATE READONLY CACHE GROUP语句来创建READONLY缓存集合。缺省的:

• AUTOREFRESH缓存集合属性被设置为INCREMENTAL模式。

• AUTOREFRESH INTERVAL值为5 MINUTES。

• AUTOREFRESH STATE为PAUSED。

可以使用ALTER CACHE GROUP语句来改变任何AUTOREFRESH缓存集合属性的缺省设置或完全阻止Oracle表中的更新应用到缓存中。

在创建READONLY缓存集合之前,通过使用ttCacheUidPwdSet内部程序来设置缓存管理用户ID和口令或使用带有-cacheUidPwdSet选项的ttAdmin工具。缓存管理用户将在Oracle上创建一个触发器,所以它必须拥有显示在表 4.1中关于CREATE READONLY CACHE GROUP的Oracle权限。

对于每个数据存储,缓存管理用户ID和口令只需设置一次。如果数据存储被重写或破坏,则需要重新设置缓存管理用户ID和口令。

试图在READONLY缓存集合中更新缓存的表,将导致TimesTen错误8225 “Table is read only”。但是,如果PassThrough属性被设置为2或3,DML语句也可以通过缓存传递到Oracle,并通过AUTOREFRESH再从Oracle传回到缓存集合中。在READONLY缓存集合中的passed-through语句的效果不会在包含此语句的事务中产生。只有在此事务被提交到Oracle,然后在下一次缓存的AUTOREFRESH完成时才会体现。

使用READONLY缓存集合时的限制

当使用READONLY缓存集合时,有下列限制:

• READONLY缓存集合中的表不能直接更新。

• 缓存集合和其中的表可以使用下列属性:

– AUTOREFRESH

– UNIQUE HASH ON

– ON DELETE CASCADE

• 不允许使用手动FLUSH操作。

• TRUNCATE TABLE语句不能自动刷新。

• 当使用LOAD CACHE GROUP语句时缓存集合必须为空。

• 当使用LOAD CACHE GROUP或REFRESH CACHE GROUP语句时,AUTOREFRESH STATE必须为PAUSED。

• WHERE子句中的所有字段(列和表)的引用必须完全合法。例如:user.table user.table.column

• LOAD CACHE GROUP和REFRESH CACHE GROUP语句不能包含WHERE子句。

• 不能指定Least recently used (LRU)老化。

示例:创建READONLY缓存集合

此例创建一个包含customerordertab表的READONLY缓存集合,名为customer_orders

CREATE READONLY CACHE GROUP customer_orders

FROM

user1.customer (custid INTEGER NOT NULL,

name VARCHAR2(100) NOT NULL,

addr VARCHAR2(100),

zip VARCHAR2(10),

region VARCHAR2(10),

PRIMARY KEY(custid)),

user1.ordertab (orderid NUMBER NOT NULL,

custid INTEGER NOT NULL,

PRIMARY KEY (orderid),

FOREIGN KEY (custid) REFERENCES CUSTOMER(custid));

SYNCHRONOUS WRITETHROUGH (SWT)缓存集合

SYNCHRONOUS WRITETHROUGH (SWT)缓存集合将进行强制执行:把TimesTen中被更新的缓存数据传送到Oracle。当使用CREATE SYNCHRONOUS WRITETHROUGH CACHE GROUP语句创建SWT缓存集合时,在创建缓存集合之后,缓存集合中的内容必须手动从Oracle表加载。SWT缓存集合的内容可以在需要时进行手动加载、卸载或刷新。

对SWT缓存集合的更新将被同步提交。当应用提交一个事务时,在它提交到TimesTen之前先被提交到Oracle。应用将被锁定,并且表中的行也同进被锁定,直到事务完成到TimesTen的提交。

如果到Oracle的事务提交失败,则到TimesTen的事务提交必须被回滚。如果Oracle事务成功但TimesTen事务失败,则缓存集合的数据将与Oracle数据不同步。如果产生这种情况,必须手动将缓存集合与Oracle重同步。这可能通过调用ttCachePropagateFlagSet程序先停止到Oracle的数据传递,然后重新应用此事务到TimesTen缓存集合。作为另一选择,也可以重新从Oracle加载数据。

图 3.2 显示一个SYNCHRONOUS WRITETHROUGH缓存集合。

3.2 SYNCHRONOUS WRITETHROUGH缓存集合

TIMESTEN内存数据库-最佳实践(已翻译)_第12张图片

使用SWT缓存集合的限制

当使用SWT缓存集合时,有如下限期完成:

• 缓存集合和其中的表属性中,可以使用UNIQUE HASH ON和ON DELETE CASCADE属性。

• 不允许使用手动FLUSH操作。

• 在此类型的缓存集合定义中不能显示使用WHERE子句。

• TRUNCATE TABLE语句不能应用到缓存集合的表中。

示例:创建SWT缓存集合

此示例为一单独Oracle表vendor创建一个SYNCHRONOUS WRITETHROUGH缓存集合,名为vendors。在缓存集合中的vendor表的更新将自动传送到Oracle。

CREATE SYNCHRONOUS WRITETHROUGH CACHE GROUP vendors

FROM

user1.vendor (vendor_id INTEGER NOT NULL,

vendor_name VARCHAR2(100) NOT NULL,

contact_name VARCHAR2(100) NOT NULL,

phone VARCHAR2(15),

street VARCHAR2(100),

city VARCHAR2(30),

state VARCHAR2(30),

zip VARCHAR2(10),

PRIMARY KEY(vendor_id));

ASYNCHRONOUS WRITETHROUGH (AWT)缓存集合

ASYNCHRONOUS WRITETHROUGH (AWT)缓存集合与SWT缓耻集合一样强制执行同样的操作:更新TimesTen中的缓存数据,并传送到Oracle。AWT缓存集合可以提供比SWT缓存集合理快的时间响应,因为TimesTen提交的产生与Oracle的提交不同步。这就允许应用持续执行,而不必等待Oracle事务的提交完成。而且也可在Oracle数据库关闭后更新AWT缓存集合。当Oracle数据库返回到操作时,此更新将被应用到Oracle数据库。

图 3.3 显示TimesTen缓存集合的更新被异步复制到Oracle。

3.3 ASYNCHRONOUS WRITETHROUGH缓存集合

TIMESTEN内存数据库-最佳实践(已翻译)_第13张图片

AWT缓存集合要求包含此缓存集合的数据存储的缓存代理和复制代理都要启动。缓存代理可能加载和刷新缓存内容。缓存代理不必运行卸载此缓存。

AWT缓存集合通过CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP语句创建。

为了使用AWT缓存集合,必须有相应的Oracle权限,并在启动缓存代理和复制代理之前使用ttCacheUidPwdSet程序设置缓存管理用户ID和口令。

当使用AWT缓存集合时,提交到TimesTen和Oracle的事务是异步的。所以当更新提交到Oracle时,应用不一定可靠。

AWT缓存集合能保证什么

AWT缓存集合可以如下保证:

• 不会因为TimesTen和Oracle这间的通信失败而丢失事务。

– 如果复制代理丢失到Oracle的连接,则在代理可能连接到Oracle之后,AWT将重新启动。

– 如果数据存储上的复制代理与缓存集合一起关闭,则代理将从备份重新开始并再次启动事务。

• 对于一个单独TimesTen数据存储被提交的事务被提交到Oracle的顺序与被提交到TimesTen的顺序相同。

• 如果到Oracle的事务失败,则失败将被报告在dataStoreName.awterr错误文件中。

AWT缓存集合不能保证什么

AWT缓存集合不能保证:

• 所有在TimesTen中执行的事务都将被应用到Oracle。Oracle上执行错误将引起整个事务被回滚。例如,可能因为违反唯一约束而引起Oracle上的插入失败。产生执行错误的事务将不会再试。

• 要绝对保证Oracle的更新顺序,因为AWT不能解决更新冲突。这儿有一些例子:

– 一行首先被更新到一个AWT表并被提交。然后一些被更新的行通过Oracle传送操作并提交。AWT代理最后应用到此行的第一次更新并重新覆盖传送操作。

– 在两个独立的数据存储中(DS1, DS2),都有一个拥有相同Oracle基表的AWT表。一行在DS1中被更新并提交。一行在DS2中被更新并提交。因为缓存集合的动作是异步的,DS2中的更新也许先于DS1中的更新应用到Oracle数据库,结果是DS1中的更新覆盖DS2中的更新。

使用AWT缓存集合的限制

关于SWT缓存集合的限制讨论也适用于AWT缓存集合:

• 缓存集合和表的属性可以使用UNIQUE HASH ON和ON DELETE CASCADE属性。

• 不允许使用手动FLUSH操作。

• WHERE子句不能出现在此类型的缓存集合的表定义中。

• TRUNCATE TABLE语句不能应用于缓存集合的表中。

• AWT缓存表中的VARCHAR2、NVARCHAR2、VARBINARY和TT_VARCHAR列必须限制为256K字节。

下面是只对AWT缓存集合适用的另外限制:

• 在AWT缓存集合中数据存储路径名的最大长度不能超过248字符。

• 在传送更新到Oracle的过程中产生的错误和警告,将记录在一个特殊的错误文件中,并且在提交到TimesTen以后都可以一直报告。

• AWT缓存集合不允许使用在日志被关闭的数据存储中(Logging=0)。

• 在创建或删除AWT缓存集合之前,必须停止复制代理。

• 在复制代理启动之前,更新将不会从TimesTen传送到Oracle。

• 在Oracle上的更新冲突将不会被发觉并解决。当从TimesTen传送更新时将覆盖直接到Oracle基表的更新。

• 与单一条相关的SQL语句的约束检查将立即进行。例如,假设在一个AWT表中有一个唯一索引integer字段。有10条记录,并且此字段的值的范围是从1到10。发布一条增加此字段的更新语句。此语句在TimesTen中成功,但当应用到Oracle时很可能失败。原因就是TimesTen在语句结束之后检查此唯一索引约束,但当更新应用到Oracle时,此约束是在每一行都被更新之后进行检查。所以当值为1的记录被设置为2时,它将与此字段已经为2的其它行发生冲突。

• 在一个返回twosafe服务的复制计划中不能包含AWT缓存集合。

示例:创建一个AWT缓存集合

此示例为一单独表customer创建一个ASYNCHRONOUS WRITETHROUGH缓存集合,名为customers

CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP customers

FROM

user1.customer (custid INTEGER NOT NULL,

name VARCHAR2(100) NOT NULL,

addr VARCHAR2(100),

zip VARCHAR2(10),

PRIMARY KEY(custid));

为AWT创建Oracle对象

TimesTen需要在Oracle中创建一个状态表来支持AWT。此表用来跟踪状态和最近应用到Oracle的事务。此表由CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP语句自动创建。作为选择,也可以在创建AWT缓存集合之前,手工创建此Oracle表。

设置AWT缓存集合

当设置AWT缓存集合时,执行下列任务:

1. 设置缓存管理用户ID和口令。

通过使用ttCacheUidPwdSet内部程序或使用带有-cacheUidPwdSet选项的ttAdmin工具来设置缓存管理用户ID和口令。

缓存管理用户将应用更新到Oracle。所以缓存管理用户帐号必须拥有相应的Oracle权限。

对于每个数据存储,缓存管理用户ID和口令只需设置一次。如果数据存储被覆盖或被破坏,则必须重新设置缓存管理用户ID和口令。

2. 创建AWT缓存集合。

使用CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP SQL语句。

3. 启动缓存代理。

4. 启动复制代理。

创建AWT缓存集合时将自动创建复制计划以允许数据存储与Oracle数据库进行通信。此复制计划完全由TimesTen管理,并不需要用户干涉。当使用DROP CACHE GROUP来删除AWT缓存集合时,此复制计划也将被删除。

在加载缓存集合之前,不必启动复制代理,但是如果复制代理已经首先启动,最好让它执行完毕。

5. 加载缓存集合。

使用LOAD CACHE GROUP语句。

USERMANAGED缓存集合

如果系统管理缓存集合(READONLY、AWT和SWT)不适合工作需要,可以使用CREATE USERMANAGED CACHE GROUP语句来创建缓存集合以实现自定义缓存操作:

• 可以通过设置AUTOREFRESH和PROPAGATE属性来定义USERMANAGED缓存集合在Oracle和TimesTen之间进行自动刷新和传送更新。两个属性同时设置以激活双向传送,这样就可以在两者之间通过互相传送即可以更新TimesTen,又可更新Oracle。

• 可以使用SQL语句来控制Oracle和TimesTen之间的数据传送。例如,可以:

– 在应用中使用FLUSH CACHE GROUP SQL语句来将TimesTen缓存集合中的更新发送至Oracle。

– 使用LOAD CACHE GROUP或REFRESH CACHE GROUP语句来将Oracle中的更新加载或刷新到TimesTen缓存中。

• 可能通过使用UNLOAD CACHE GROUP语句从用户管理缓存集合中删除所有数据或选择的数据。

• 可以在用户管理缓存集合中为每个表指定PROPAGATE或READONLY属性,以在表级上定义可写或只读操作。

示例:创建USERMANAGED缓存集合

这部分显示使用EATE USERMANAGED CACHE GROUP语句创建自定义缓存集合的一些示例。

例 3.1 此例为一单独表customer创建一个USERMANAGED缓存集合,名为update_anywhere_customerscustomer表中的更新通过“双向”彼此传送来更新TimesTen或Oracle。图 3.4 显示update_anywhere_customers USERMANAGED缓存集合。

3.4 简单USERMANAGED缓存集合

TIMESTEN内存数据库-最佳实践(已翻译)_第14张图片

在此例中,设置了AUTOREFRESH属性,以使此缓存集合可以每隔30秒从Oracle进行增量更新。用户是user1。表中描述的PROPAGATE属性显示TimesTen缓存中的customer表的更新将被传送到Oracle:

CREATE USERMANAGED CACHE GROUP update_anywhere_customers

AUTOREFRESH

MODE INCREMENTAL

INTERVAL 30 SECONDS

FROM

user1.customer (custid INTEGER NOT NULL,

name VARCHAR2(100) NOT NULL,

addr VARCHAR2(100),

zip VARCHAR2(10),

PRIMARY KEY(custid),

PROPAGATE);

例 3.2 此例创建一个USERMANAGED缓存集合,名为western_customers,包含四个相关联的表:customerordertaborder_detailscust_interest。图 3.5 显示此缓存集合和它的表。

3.5 复杂USERMANAGED缓存集合

TIMESTEN内存数据库-最佳实践(已翻译)_第15张图片

western_customers缓存集合中的每个表都有一个主键。缓存集合中的表通过关联的外键相互连接。customer表为根表,所以在缓存集合它不能引用其它表。根表包含一条WHERE子句以限制缓存中表的行数。

指定了PROPAGATE属性,以使缓存中表的任何变化在提交时将被自动传送到相应的Oracle表。

CREATE USERMANAGED CACHE GROUP western_customers

FROM

user1.customer (custid INTEGER NOT NULL,

name VARCHAR2(100) NOT NULL,

addr VARCHAR2(100),

zip VARCHAR2(10),

region VARCHAR2(10),

PRIMARY KEY(custid),

PROPAGATE)

WHERE (customer.region = 'Western'),

user1.ordertab(orderid NUMBER NOT NULL,

custid INTEGER NOT NULL,

PRIMARY KEY (orderid),

FOREIGN KEY (custid) REFERENCES customer(custid),

PROPAGATE),

user1.order_details(orderid NUMBER NOT NULL,

itemit NUMBER NOT NULL,

quantity NUMBER NOT NULL,

PRIMARY KEY (orderid, itemid),

FOREIGN KEY (orderid) REFERENCES ordertab(orderid),

PROPAGATE),

user1.cust_interest(custid INTEGER NOT NULL,

interest VARCHAR2(10) NOT NULL,

PRIMARY KEY (custid, interest),

FOREIGN KEY (custid) REFERENCES customer(custid),

PROPAGATE);

定义缓存集合和表属性

下表总结可用于CREATE CACHE GROUP语句的属性。

表 3.2 总结AUTOREFRESH缓存集合属性。

表 3.3 列出了可应用于缓存集合中单个表定义的属性。

表 3.2 完整缓存集合的属性

缓存集合属性

AUTOREFRESH

将Oracle表中产生的更新变化自动应用到TimesTen缓存。此属性可以在READONLY和USERMANAGED缓存集合中设置。

表 3.3 缓存集合中表的属性

缓存表属性

UNIQUE HASH ON

为被创建的表指定一个哈希索引。可以为任何类型缓存集合中的表进行设置。

PROPAGATE

在提交时自动地将缓存表中的更新传送到相应的Oracle表。只能为USERMANAGED缓存类型中的表进行设置。

READONLY

指定缓存集合中的表不能更新到TimesTen。只能为USERMANAGED缓存集合中的表进行设置。

ON DELETE CASCADE

指定当包含被引用键的值从父表中删除时,子表中依靠外键连接的行也要被删除。可以为任何类型的缓存集合中的表进行设置。限制:

• 使用PROPAGATE属性的缓存集合表。

• SWT和AWT缓存集合表。

AUTOREFRESH缓存集合属性

AUTOREFRESH属性是READONLY和USERMANAGED缓存集合的一个选项属性。

AUTOREFRESH自动将Oracle表中的变化应用到TimesTen缓存。

TimesTen支持两种AUTOREFRESH模式:

• FULL:通过卸载内容然后再从Oracle表重新加载来刷新整个缓存集合。

• INCREMENTAL:Oracle跟踪更新情况并周期性地只更新Oracle中已经变化行到缓存集合中。此模式将使用Oracle中的专用对象来跟踪变化情况。

缺省值:

• AUTOREFRESH MODE了为 INCREMENTAL。

• AUTOREFRESH STATE 为 PAUSED。

• AUTOREFRESH INTERVAL 值为5 MINUTES。

缓存集合使用相同的自动刷新间隔在相同的时间被刷新。

AUTOREFRESH 以 INCREMENTAL模式对于Oracle中的每个更新将产生一些额外的花销来刷新缓存集合。而使用AUTOREFRESH 和 FULL模式时则没有额外的花销。

在使用AUTOREFRESH属性创建缓存集合之前,要使用ttCacheUidPwdSet内部程序或带有-cacheUidPwdSet选项的ttAdmin工具来设置缓存管理用户ID和口令。缓存管理用户将在Oracle上创建一触发器,所以它必须拥有使用AUTOREFRESH属性的READONLY缓存集合和USERMANAGED缓存集合相应的Oracle权限。

对于每个数据存储,缓存管理用户ID和口令只需要设置一次。如果数据存储被覆盖或破坏,则必须重新设置缓存管理用户ID和口令。

指定AUTOREFRESH缓存集合属性

当使用CREATE CACHE GROUP语句创建缓存集合时,可以指定AUTOREFRESH。在创建缓存集合之后,可以使用ALTER CACHE GROUP来改变MODE、STATE和INTERVAL的设置。ALTER CACHE GROUP语句不能用于没有使用AUTOREFRESH 属性创建的缓存集合。

AUTOREFRESH产生的频率将取决于INTERVAL值。可以使用CREATE CACHE GROUP 或ALTER CACHE GROUP语句来设置AUTOREFRESH STATE为ON、OFF或PAUSED。当提交STATE设置为ON的事务时,AUTOREFRESH将由TimesTen管理。

当STATE被设置为OFF时,到Oracle表的更新将不会被捕获或记录。当状态为PAUSED时,Oracle表中的更新将被捕获并记录在Oracle中,但不会应用到TimesTen缓存集合的表中。

当一个AUTOREFRESH操作在处理中,并且试图将STATE改变为OFF或删除缓存集合时:

• 如果LockWait普通连接属性大于0,则AUTOREFRESH操作将停止。ALTER CACHE GROUP SET AUTOREFRESH STATE OFF 和 DROP CACHE GROUP 语句将优先于AUTOREFRESH操作。

• 如果LockWait普通连接属性为0,则AUTOREFRESH操作将继续。ALTER CACHE GROUP SET AUTOREFRESH STATE OFF 和 DROP CACHE GROUP 语句将失败,并产生一个锁定终止错误。

当以INCREMENTAL模式使用AUTOREFRESH时,在Oracle中发生的变化将在change log table中进行维护。在确定的环境下,在应用到TimesTen缓存集合之前,事务中的一些记录可能将从更新日志表中被清除。如果发生这种情况,Cache Connect to Oracle启动缓存集合的完全自动更新。

使用AUTOREFRESH的限制

当使用AUTOREFRESH时有如下限制:

• 如果在Oracle基表上使用了TRUNCATE TABLE语句,则增量AUTOREFRESH将不会工作。如果Oracle基表上使用了TRUNCATE,则必须重新设置AUTOREFRESH。使用ALTER CACHE GROUP语句来将AUTOREFRESH STATE设置为PAUSED,然后手工刷新缓存集合。再发送另一条ALTER CACHE GROUP来将AUTOREFRESH STATE重新设置为ON。

• 为了使用AUTOREFRESH特性,缓存集合中的所有表必须指定为PROPAGATE或READONLY。不能使用NOT PROPAGATE属性指定AUTOREFRESH。

• 当手工加载或刷新缓存集合时,AUTOREFRESH STATE必须为PAUSED。

• 当使用LOAD CACHE GROUP语句时,缓存集合必须为空。

• WHERE 子句中引用的所有字段(列和表)必须完全合法。例如:user.table user.table.column

• 对于AUTOREFRESH的缓存集合的LOAD CACHE GROUP和REFRESH CACHE GROUP语句不能包含WHERE子句。

• 不能在AUTOREFRESH缓存集合中实现LRU老化。

缓存表属性

这部分包括下列缓存表属性:

• PROPAGATE

• READONLY

• ON DELETE CASCADE

• UNIQUE HASH ON

PROPAGATE

PROPAGATE属性只能为USERMANAGED缓存集合中的表进行指定。但是,这里讨论的传送操作与同步写(SWT)缓存集合相似。

PROPAGATE指定在提交时TimesTen缓存集合中表的任何变化将被自动传送到相应的Oracle表。NOT PROPAGATE将取传送能力。

如果缓存表使用PROPAGATE属性定义,到缓存表中的更新在TimesTen提交过程中将被传送回Oracle。是以同步的方式:

1. 提交首先尝试到Oracle。如果向Oracle提交失败,则不会再向TimesTen提交,并且TimesTen事务被作上需要回滚的标记。这种方式,Oracle数据库不会遗失数据更新。

2. 如果向Oracle提交成功,将尝试向TimesTen提交。如果向TimesTen提交失败,将收到一条说明失败原因的TimesTen错误信息。

用户的操作通过连接到Oracle的应用进行提交。对于用户的登录和口令必须指定在DSN中或到TimesTen的连接串中的UIDOraclePWD属性中。

关于传送提交到Oracle,必需满足下列要求:

• 被缓存在TimesTen中的Oracle表的列必须包括此Oracle表中至少一个唯一键或主键中的所有列。组成唯一键或主键的列在Oracle必须为非NULL值的列,并且在TimesTen缓存集合中它们必须申明为主键。

这个要求的目的就是要确保在TimesTen中被更新的行之间和Oracle中原来的数据保持一对一的映射关系。确定此一对一的映射,就不会担心应用的更新会受到非缓存行的影响。

• 表的缓存版本必须有一个主键申明。

缺省地,缓存表使用NOT PROPAGATE属性被创建,以使表中的更新不会传送到Oracle。当PROPAGATE被激活时,应用有时候偶尔需要更新缓存表,但不向Oracle提交。使用ttCachePropagateFlagSet内部程序来取消它,然后重新激活传送。

当传送被取消时,可以使用FLUSH CACHE GROUP语句来选择传送插入并更新到Oracle。

当使用PROPAGATE时有如下限制:

• 如果使用PROPAGATE,它必须为缓存集合中的所有表进行指定。

• 在同一个缓存集合中,不能同时使用PROPAGATE和READONLY缓存表。

• TimesTen不会检查冲突以防止覆盖多个当前到Oracle更新的操作。基于这个原因,更新将分别在TimesTen缓存或Oracle中进行,但不是同时。

• 如果缓存集合的AUTOREFRESH被激活或在AUTOREFRESH缓存集合的拷贝中,不能为表设置NOT PROPAGATE。

• 在缓存集合被指定为PROPAGATE之后,就不能再改变此属性。

注意:对于表使用PROPAGATE属性的缓存集合,TimesTen将不会检查向表的插入和更新是否与定义缓存集合时的WHERE子句有无约束。因此不会阻止插入和更新,并且将传送到Oracle。

READONLY

READONLY表属性只能为USERMANAGED缓存集合中的表进行指定。

注意:不要混淆READONLY表属性和READONLY缓存集合类型。READONLY缓存集合类型包含只读表,但READONLY表只能显示地为USERMANAGED缓存集合指定。

可以为每个缓存集合表指定READONLY表属性,以禁止TimesTen应用更新这些表。

下面是使用READONLY表属性时的限制:

• 如果使用READONLY,它必须为缓存集合中的所有表进行指定。

• 不能与PROPAGATE表属性一起指定READONLY表属性。

ON DELETE CASCADE

当创建缓存集合时,ON DELETE CASCADE表属性可以为所有缓存集合类型的表进行指定。也可以为不在缓存集合中后进行指定。

ON DELETE CASCADE表属性指定当从父表中删除包含引用键值的行时,通过外键相关联的子表中插也将被删除。根表是缓存集合中所有其它表的父表。

所有从父表到子表的方式必须是要么是“删除”或要么是“不删除”。不能父表到子表一些是删除,而另一些是不删除。对于子表的删除方式是指定ON DELETE CASCADE。

下面是使用ON DELETE CASCADE的限制:

• 对于AWT和SWT缓存集合和使用PROPAGATE属性的缓存集合表,有ON DELETE CASCADE属性的TimesTen表的外键必须是Oracle中有ON DELETE CASCADE属性的表中的外键相的相应的一个子集。在Oracle表上的ON DELETE CASCADE动作应用到TimesTen时将作为单独的删除动作。TimesTen中的ON DELETE CASCADE动作应用到Oracle时将作为一个级联操作。

• TimesTen和Oracle之间的外键匹配只是在创建缓存集合时强制进行。如果Oracle上的外键后来进行过修改,ON DELETE CASCADE将不会正常的工作。

UNIQUE HASH ON

UNIQUE HASH ON属性可以为所有缓存集合类型中的表进行指定。也可以为不在缓存集合中的表进行指定。

UNIQUE HASH ON指定在缓存集合中的一个表上创建一个哈希索引。指定在哈希索引中的列必须同样是主键中的列。

定义缓存集合表

绝大多数缓存集合的基本类型是在TimesTen中缓存一个单一的Oracle表。在一个缓存集合中缓存多个表复杂的多,并要求理解另外的Cache Connect to Oracle概念。

通常情况下,每个被缓存的Oracle表至少有一个主键或非空值的唯一索引。另外,在TimesTen缓存集合表中定义的主键和唯一索引将与那些Oracle表中的相匹配。例如,如果Oracle表有主键或唯一索引列C1C2C3,则相应的TimesTen缓存表中的主键也应该有列C1C2C3

可以为TimesTen缓存表创建任意多个非唯一索引。增加缓存表的索引将提高同样查询非缓存TimesTen表的SQL速度。不要创建与Oracle表不匹配唯一索引,因为将起唯一约束失败。

注意:Oracle临时表不能被缓存。

定义一单一的缓存集合表

如下创建一个简单缓存集合定义来缓存一单一表:

CREATE TYPE CACHE GROUP owner.name

FROM

owner.root_table(column_list,

PRIMARY KEY(primary_key_column_list));

说明:

owner.root_table 是Oracle表或一个Oracle表私有同义词的拥有者和表名。

column_list 是一个被缓存的表的列清单和它们的数据类型。

primary_key_column_list 是一个组成主键的列的清单。

当为列选择数据类型时,要考虑Oracle列中的数据类型并为缓存集合中的表选择相应的数据类型映射。

例 3.3 图 3.6 显示一个单表READONLY缓存集合,名为target_customers,缓存Oracle表customer。TimesTen缓存集合中的数据是一个更大的存储在Oracle数据中所有用户数据集的子集。

3.6 TimesTen中缓存单个Oracle

TIMESTEN内存数据库-最佳实践(已翻译)_第16张图片

使用CREATE READONLY CACHE GROUP语句来创建单表缓存集合target_customers

CREATE READONLY CACHE GROUP target_customers

FROM

user1.customer (cust_num NUMBER NOT NULL PRIMARY KEY,

region VARCHAR2(5) NOT NULL,

name VARCHAR2(80),

address VARCHAR2(255) NOT NULL);

定义多个缓存集合表

如果多个Oracle表被缓存在同一个缓存集合中,必须定义一个根表和多个子表。在一个缓存集合中只能有一个根表。

在有多表的缓存集合中,缓存集合中的每个子表必须通过外键约束与缓存集合中的根表或另一个子表相关联。尽管在TimesTen中缓存集合中的表必须通过外键约束关联,但在Oracle实例中,这些表不一定要关联起来。缓存集合中的根表不能通过外键约束引用缓存集合中另外的任何表。缓存集合中另外所有表都是子表。

每个表的定义必须包含一个主键。每个子表也必须包括一个引用到它父表主键的外键。缓存集合中表层次可以指定子表到父表或其它子表,但缓存集合中的表不能是一个在此缓存集合中有多个父表的子表。参阅图 3.7 关于一个正确缓存集合表配置的示例。图 3.8 显示一个不正确的表配置,图 3.9 显示如何工作来解决问题。

必须在缓存集合中为每个将被包括在缓存中的Oracle表创建单独的表定义。定义在缓存集合中的表的所有者和名称必须与Oracle表的所有者和名称相匹配。可以创建一个表定义来缓存Oracle表中列的所有数据或它的一个子集。

注意:每个Oracle表可以只被定义在一个缓存集合中。不能创建多个缓存集合来缓存相同的Oracle表。

例 3.4 创建一简单缓存集合定义来缓存一个根表和一个子表如下:

CREATE TYPE CACHE GROUP owner.name

FROM

owner.root_table(column_list,

PRIMARY KEY(primary_key_column_list)),

owner.child_table(column_list,

PRIMARY KEY(primary_key_column_list),

FOREIGN KEY(reference_column_list)

REFERENCES owner.root_table(primary_key_column_list));

说明:

owner.root_table 是Oracle表或Oracle表的私有同义词的所有者和表名。

owner.child_table 是Oracle表或Oracle表的私有同义词的所有者和表名。

column_list 是一个被缓存表中的列清单。

primary_key_column_list 是一个组成主键的列的清单。

reference_column_list 是一个child_table中引用一个外键的列的清单。

图 3.7 显示先前显示在图 3.6中的target_customers缓存集合的多表版本。

3.7 多表缓存集合

TIMESTEN内存数据库-最佳实践(已翻译)_第17张图片

在此例中,缓存集合被扩展到缓存三个Oracle表:customerordersorder_item。缓存集合中的数据是一个更大的存储在Oracle数据库中所有用户数据集的一个子集。target_customers缓存集合中的每个父表有一个主键(显示为粗体),通过一个相关的外键(显示为箭头)被子表引用。表customer是根表,它不能缓存集合中任何另外的表。customer表的主键是对于target_customers缓存集合的主键。ordersorder_item表是子表。

例 3.5 使用CREATE READONLY CACHE GROUP语句来创建target_customers多表缓存集合:

CREATE READONLY CACHE GROUP target_customers

FROM

user1.customer (cust_num NUMBER NOT NULL PRIMARY KEY,

region VARCHAR2(10) NOT NULL,

name VARCHAR2(80),

address VARCHAR2(255) NOT NULL),

user1.orders (ord_num NUMBER NOT NULL PRIMARY KEY,

cust_num NUMBER NOT NULL,

when_placed TIMESTAMP NOT NULL,

when_shipped TIMESTAMP,

FOREIGN KEY (cust_num) REFERENCES user1.customer (cust_num)),

user1.order_item (ord_num NUMBER NOT NULL,

prod_num NUMBER NOT NULL,

quantity NUMBER NOT NULL,

PRIMARY KEY (ord_num, prod_num),

FOREIGN KEY (ord_num) REFERENCES user1.orders (ord_num));

图igure 3.8 显示缓存集合中不正确的表配置。

3.8 问题:两个根表

TIMESTEN内存数据库-最佳实践(已翻译)_第18张图片

不能在拥有customerordersorder_item表的同一个缓存集合中定义productsinventory表。这是因为products表没有引用(直接或间接)到根表customer的外键。这就意谓着products表也被认为是一个根表,因为一个缓存集合不能同时拥有多个根表,因此无效。

为了缓存所有表,可以为productsinventory表创建第二个缓存集合,如图 3.9所示。

3.9 解决:两个独立的缓存集合

TIMESTEN内存数据库-最佳实践(已翻译)_第19张图片

缓存Oracle分区表

当缓存常规Oracle表时,可以在缓存集合中根据规则规定定义Oracle分区表。例如,在只读缓存集合中的分区表在Oracle中必须有一个相应的唯一非NULL值索引。用于缓存集合的分区表可以是任何样式(哈希、列表、排列或合成)的分区或子分区表。

下面是缓存Oracle分区表时的限制:

• 除非有数据丢失,在分区上的DDL操作不会影响缓存集合。例如,如果一个分区的数据被截短,AUTOREFRESH不会从相应的缓存表中删除数据。

• 缓存集合中的WHERE子句操作不引用单独的分区或子分区。例如,试图定义下列分区表user1.partitioned_table,将返回一个错误:

CREATE READONLY CACHE GROUP badcachegroup

FROM

user1.partitioned_table(ii NUMBER NOT NULL PRIMARY KEY, jj NUMBER)

WHERE ii IN (SELECT ii

FROM user1.partitioned_table PARTITION(F200402));

注意:在离线分区上试图缓存操作(如LOAD CACHE GROUP、UNLOAD

CACHE GROUP或REFRESH CACHE GROUP)将导致ORA-00376或ORA-01110错误。但是,如果分区将离线(如在一个备份操作期间),则不会产生错误,除非这时试图访问分区。

关于Oracle同义词

一个定义在缓存集合中的表可以引用Oracle其表的私有的Oracle同义词。实际的Oracle基表可以存在于另一个Oracle帐号中,并有一个不同的名称,但作为同义词它必须驻留在同一个Oracle服务器上。缓存集合中的表名必须是私有同义词名称,但同义词可以指向另一个公有或私有的同义词。同义词最终必须指向(直接或间接)一个表、分区表或物化视图。

包含为Oracle同义词的表定义的缓存集合可以是一个USERMANAGED、SWT或AWT缓存集合。USERMANAGED缓存集合支持LOAD CACHE GROUP、UNLOAD CACHE GROUP、REFRESH CACHE GROUP和FLUSH CACHE GROUP 操作,但不能使用AUTOREFRESH或READONLY属性配置此缓存集合。不能在READONLY缓存集合中为Oracle同义词定义表。

使用WHERE子句

在使用CREATE CACHE GROUP语句为用户管理和READONLY缓存集合中的表的定义可以包含一条WHERE子句来指定搜索条件来将Oracle数据拷贝到缓存中。

另外,可以在LOAD CACHE GROUP、UNLOAD CACHE GROUP、MERGE和FLUSH CACHE GROUP语句中指定WHERE子句。一些语句,如LOAD CACHE GROUP和REFRESH CACHE GROUP,将导致连接的WHERE子句中缓存集合中的WHERE子句将先于语句中的WHERE进行计算。所有的WHERE子句将通过TimesTen解析。不要使用TimesTen不支持的Oracle SQL语法。

例 3.6 此例创建一个名为western_customers的缓存集合,指定一条WHERE子句来从Oracle表customer中只缓存那些西部地区中有邮政编码的用户的相关数据:

CREATE USERMANAGED CACHE GROUP western_customers

FROM

user1.customer (custid INTEGER NOT NULL,

name VARCHAR(2100) NOT NULL,

addr VARCHAR2(100),

zip VARCHAR2(10),

region VARCHAR2(10),

PRIMARY KEY(custid),PROPAGATE)

WHERE (user1.customer.region = 'Western');

然后在LOAD CACHE GROUP语句中指定另外一条WHERE子句来只缓存来自西部地区的ID小于或等于100的用户:

LOAD CACHE GROUP western_customers WHERE (custid <= 100)

COMMIT EVERY 256 ROWS;

CREATE CACHE GROUP和LOAD CACHE GROUP 语句中的WHERE子句,在数据被加载到缓存集合之前,在Oracle上进行计算。

表 3.4 显示LOAD CACHE GROUP, UNLOAD CACHE GROUP、REFRESH CACHE GROUP和FLUSH CACHE GROUP语句的WHERE子句是否在TimesTen、Oracle或两者上都要计算。如果CREATE CACHE GROUP语句也包含一条WHERE子句,此表显示在Oracle上计算的另外的WHERE子句。

表 3.4 WHERE子句的计算

SQL语句

语句的WHERE子句的计算处...

CREATE CACHE

GROUP WHERE 子句计算处...

LOAD

Oracle

Oracle

UNLOAD

TimesTen

-

REFRESH

TimesTen和Oracle

Oracle

FLUSH

TimesTen

-

表 3.5 显示对每一条SQL语句的WHERE子句是否只由TimesTen或同时由TimesTen和Oracle解析。

表 3.5 WHERE子句解析

SQL语句

TimesTen解析

Oracle解析

LOAD

Yes

Yes

UNLOAD

Yes

No

REFRESH

Yes

Yes

FLUSH

Yes

No

CREATE

Yes

Yes

与详细日志一起,所有面对Oracle执行的SQL语句将记录在Oracle服务器日志中。查看此日志以更好的理解缓存集合操作的机制和执行。

下面是Cache Connect to Oracle使用WHERE子句的限制:

• CREATE CACHE GROUP语句中的WHERE子句不能指定子查询,所以它们不能引用任何当前的其它表。LOAD CACHE GROUP, UNLOAD CACHE GROUP、REFRESH CACHE GROUP和FLUSH CACHE GROUP语句中的WHERE子句可以指定子查询。

• WHERE子句不能包含Oracle PARTITION扩展名。

• LOAD CACHE GROUP、REFRESH CACHE GROUP、FLUSH CACHE GROUP语句(表和同义词)中的WHERE子句只可以引用根表,除非WHERE子句包含一个子查询。

• 当创建一个多表缓存集合时,所有WHERE子句中的列名必须合法,如:user.table.column

WHERE子句中本地中立性

在缓存集合和Oracle Database之间的操作将继承此会话中使用的TimesTen全球支持的连接属性值。这些操作包括传送、加载、刷新、更新和同步写。

不直接与指定用户会话相关联的缓存集合操作将缺省使用全球支持的连接属性设置。这些操作包括自动刷新、老化和异步写。例如,这此操作使用BINARY作为NLS_SORT的值。

如果缓存集合操作使用了与全球支持的连接属性不同的值,将产生矛盾。例如,考虑下面的语句:

CREATE CACHE GROUP cachegroup1 FROM table1(

column1 NUMBER NOT NULL PRIMARY KEY,

column2 NCHAR(30))

WHERE column2 < 'string';

WHERE子句中的字符串将使用这些字符的二进制值来进行比较。这将在基于本地组装缓存集合表时,可能导致非预期结果。

为了保证WHERE子句中的字符串使用它们语言学的值来进行比较,使用CREATE CACHE GROUP语句时使用一条与面相似的WHERE子句:

CREATE CACHE GROUP cachegroup1 FROM table1(

column1 NUMBER NOT NULL PRIMARY KEY,

column2 NCHAR(30))

WHERE

NLSSORT(column2,'NLS_SORT=TCHINESE_RADICAL')

< NLSSORT('string','NLS_SORT=TCHINESE_RADICAL');

在缓存集合中实现老化

可以为缓存集合中的根表定义一个老化性质。老化性质引用老化类型和老化属性,也就是老化状态(ON或OFF)。可以指定下列之一的老化类型:基于使用基于时间基于使用老化将删除指定数据存储使用范围内最近使用过(LRU)的数据。基于时间老化将根据指定的数据生存期和老化处理频率来删除数据。在相同的数据存储中,可以在同一个数据存储定义基于使用基于时间的老化,但在指定的缓存集合或表中只能定义一种老化类型。

CREATE CACHE GROUP语句中使用表定义来为新缓存集合的根表指定一个老化性质。如果表中没有定义老化性质,可以使用ALTER TABLE语句来为已存在的缓存集合中的根表增加老化性质。可以通过先删除老化性质然后再添加老化性质来改变老化性质。

老化性质只能定义在缓存集合的根表上,因为老化是基于缓存实例的。

可以为那些没在缓存集合中的表定义老化性质。

基于使用老化

基于使用老化将保证在指定的极限范围内通过删除最近使用过(LRU)的数据来保持数据存储中可使用内存的大小。LRU老化可用于除了使用AUTOREFRESH属性的缓存集合以外的所有类型的缓存集合。

通过在CREATE CACHE GROUP语句中的表定义中使用AGING LRU子句来为一个缓存集合定义LRU老化。如果状态是ON,老化将自动开始。如果根表是数据存储中第一个拥有LRU老化性质定义的表,老化将立即开始。否则,老化将在已有LRU老化性质定义的表上发生老化时在根表上同时发生。

使用ttAgingLRUConfig内部程序来为数据存储中的所有表指定LRU老化属性。此属性将应用到有LRU老化性质的数据存储中所有的表。如果不调用ttAgingLRUConfig内部程序,则将使用属性的缺省值。

下表总结LRU老化属性:

LRU老化属性

描述

LowUsageThreshhold

LRU老化被解除时数据存储PermSize的百分比。

HighUsageThreshhold

LRU老化激活时数据存储PermSize的百分比。

AgingCycle

在两个老化周期之间的分钟数。

在定义LRU老化性质之后,如果为AgingCycle设置了一个新值,老化的产生将基于当前时间和新的周期。例如,如果原来的周期是15分钟,并且LRU在10分钟之前已经产生,则老化预计将在5分钟之后再次发生。但是,如果将AgingCycle参数改变为30分钟,则老化将从使用新的AgingCycle值调用ttAgingLRUConfig程序之时起30分钟后发生。

如果自从上一次老化周期后一行被访问或引用,它就不符合LRU老化的条件。如果下列之一为真时,行就认为被访问或引用过:

• 行被用来建立一条SELECT语句的结果集。

• 行已经作上被更新或删除的标记。

• 行被用来建立一条INSERT SELECT语句的结果集。

使用ALTER TABLE语句来执行下列任务:

• 通过在缓存集合的根表上使用带有SET AGING {ON|OFF}子句的ALTER TABLE语句来激活或非激活老化状态。

• 通过使用带有ADD AGING LRU [ON|OFF]子句的ALTER TABLE语句来在为已存在的根表增加一LRU老化性质。

• 通过使用带有DROP AGING子句的ALTER TABLE语句来删除根表上的老化。

使用ttAgingScheduleNow内部程序来确定老化的开始。

为了将缓存集合的老化从LRU改变为基于时间,首先使用带有DROP AGING子句的ALTER TABLE语句来删除根表上的老化。然后通过使用带有ADD AGING USE子句的ALTER TABLE语句来为根表增加基于时间的老化。

基于时间老化

基于时间老化将根据指定的数据生存期和老化处理频率从缓存集合的根表中删除数据。在CREATE CACHE GROUP语句的表定义中的AGING USE子句中定义基于时间的老化。使用带有AGING USE子句的ALTER TABLE语句来为已存在缓存集合中的根表增加一基于时间的老化性质。

AGING USE子句有一个ColumnName参数。ColumnName是用于基于时间老化的列的名称。作为简化,称呼此列为timestamp列。timestamp列必须定义如下:

• TIMESTAMP或DATE数据类型

• NOT NULL

应用将更新timestamp列的值。如果此列的值对于某些行来说是未知的,并且不想这些行被老化,则使用一个较大的缺省值来定义此例。可以在timestamp列上创建一个索引,以提高老化处理的执行速度。

注意:不能在已存在的表中增加或修改一个列,然后将它用作timestamp列,因为不能增加或修改一个列并定义它为NOT NULL。

不能从已经有基于时间老化性质的表中删除timestamp列。

在CREATE CACHE GROUP语句中的LIFETIME子句中以days、hours或minutes指定生存期。

timestamp列中的值将从SYSDATE中被减去。被截短的结果使用指定单位(minute、hour、day),并与指定的LIFETIME值进行比较。如果结果大于LIFETIME值,则行将成为老化的候选行。

使用CYCLE子句来指定系统检查行的周期以删除超过指定的生存期的数据。如果没有指定CYCLE,则每隔五分钟产生一次老化。如果指定CYCLE为0,则老化将持续产生。如果状态为ON,老化将自动开始。

使用ALTER TABLE语句来执行下列任务:

•通过使用SET AGING {ON|OFF}子句来在使用基于时间老化性质的根表上激活或非激活老化状态。

• 通过使用SET AGING CYCLE子句来在使用基于时间老化性质的根表上改变老化周期。

• 通过使用SET AGING LIFETIME子句来改变根表中生存期。

• 通过使用ADD AGING USE子句来为没有老化性质的已存在的根表增加基于时间老化。

• 通过使用DROP AGING子句来删除根表上的老化。

当老化开始时使用ttAgingScheduleNow内部程序来安排时序。

为了将缓存集合的老化从基于时间改为LRU,首先删除根表上的老化。然后使用带有ADD AGING LRU子句的ALTER TABLE语句来为根表增加LRU老化。

注意:如果要改变AUTOREFRESH缓存集合根表的属性,必须停止缓存代理。在AUTOREFRESH 缓存集合中增加、改变或删除老化之前,停止缓存代理。

老化和外键

通过外键关联的表必须拥有相同的老化性质。

如果LRU老化在起作用过程中并且子表中的行最近被访问过,则不管是父表还是子表中的行都将被删除。

如果基于时间老化在起作用过程中并且父表中的行已成为老化候选行,则父行和它所有的子行都将被删除。

如果表的ON DELETE CASCADE被激活,则将忽略此设置。

老化开始时的时序安排

使用ttAgingScheduleNow内部程序来安排老化过程的时序。一旦调用内部程序老化过程就立即开始,除非已经有一个老化过程正在进行中,这种情况下,当进行中的老化完成时,新的老化才能开始。

当调用ttAgingScheduleNow时,老化过程将启动,而不管状态是否是ON或OFF。当调用ttAgingScheduleNow时要指定根表的名称。否则ttAgingScheduleNow将在数据存储中有老化定义的所有表上启动或重新启动老化,而不仅仅是缓存集合的根表。

老化过程的启动只是作为调用ttAgingScheduleNow的结果。调用ttAgingScheduleNow不会改变老化的状态。当调用ttAgingScheduleNow时如果老化的状态是OFF,则老化过程将开始,但在过程完成后它不会持续。为了继续老化,必须再次调用ttAgingScheduleNow或将老化状态改为ON。

如果老化状态已经设置为ON,则ttAgingScheduleNow将根据调用ttAgingScheduleNow的时间来重新设置老化周期。

可以控制老化行为。首先通过使用带有SET AGING OFF子句的ALTER TABLE语句来非激活老化。然后在期望的时间使用ttAgingScheduleNow来启动老化。

调用程序时,可以使用ttAgingScheduleNow并通过通过指定表名来为单一表启动或重启老化。如果不指定表名,则ttAgingScheduleNow将启动或重启有老化定义的数据存储中所有表的老化。

可以使用ttTraceMon工具来监视老化。

配置变化窗口

可以使用基于时间老化来完成缓存集合数据变化窗口。在带有变化窗口的缓存集合中,按照时序规则添加新数据和删除老数据,以使缓存只保留满足指定的时间间隔的数据。

可以通过使用增量AUTOREFRESH属性来为缓存集合数据配置一变化窗口,并指定基于时间老化性质。AUTOREFRESH操作将在Oracle中检查timestamp以决定是否将新数据刷新到缓存表中。Oracle和TimesTen的SYSDATE和时区必须一致。

不能为通过手工加载、显示加载、刷新或插入数据的其它类型的缓存集合配置变化窗口来将新数据更新到缓存集合表中。

例 3.7 下面的语句使用变化窗口属性创建一个缓存集合。

CREATE READONLY CACHE GROUP cg1

AUTOREFRESH STATE ON INTERVAL 1 MINUTES

FROM t1(i NUMBER NOT NULL PRIMARY KEY,

ts TIMESTAMP NOT NULL,

c VARCHAR2(50))

AGING USE ts LIFETIME 3 HOURS CYCLE 10 MINUTES;

cg1缓存集合有1分钟的自动刷新间隔。每一分钟都会将Oracle表中的新数据更新到缓存集合中。

老化将每10分钟检查一次老数据。老化将删除大于3小时的老数据(ts < SYSDATE - 3 HOURS)。

为AUTOREFRESH间隔和LIFETIME间隔设置的参数将决定数据将在缓存中保存多长时间。小于完整生存期间隔的数据也可能被老化出缓存。例如,如果AUTOREFRESH间隔是3天,并且LIFETIME间隔为30天,当数据进入缓存时可能已经存在3天了。因此数据在27天后将从缓存中被删除。这种情况发生是因为老化是基于Oracle timestamp而不是基于TimesTen timestamp

使用数据类型和类型模式工作

如果使用Oracle TimesTen In-Memory Database的Cache Connect特性,必须使用Oracle类型模式(TypeMode=0),即使缓存集合是被7.0以前的版本所定义。

如果缓存集合是被7.0以前的版本所定义,使用带有-convertCGTypes选项的ttMigrate工具来映射数据类型到用于7.0或此后的版本的数据类型。

注意如果应用使用的是本地整数数据类型,并要继续使用它们,在调用ttMigrate之前,必须改变应用为指定的TT_INTEGER、TT_SMALLINT、TT_TINYINT和TT_BIGINT。

浮点数据类型

BINARY_FLOAT和BINARY_DOUBLE被传入到Oracle Database 10g Release 1。Cache Connect支持从Oracle9i到Oracle Database 10g的Oracle客户端和服务器端。

如果需要使用BINARY_FLOAT或BINARY_DOUBLE数据类型,TimesTen推荐如下配置:

• 使用Oracle Database 10g客户端和服务器

• 将TimesTen中的BINARY_FLOAT数据映射为Oracle中BINARY_FLOAT数据

• 将TimesTen中的BINARY_DOUBLE数据映射为Oracle中的BINARY_DOUBLE数据

可以在Oracle9i和Oracle Database 10g中使用FLOAT(n)。

如果在映射TT_BINARY_FLOAT数据类型为Oracle的FLOAT(n)时,需要保持内存或提高执行速度,TimesTen推荐Oracle客户端的版本要与服务器Oracle的版本相同或较低。尽管作为推荐,也会发生下列情况:

• 在从FLOAT(n) 转换到BINARY_FLOAT和BINARY_DOUBLE时,会有数据精度的丢擒失。

• 在缓存中当Inf和NaN被定义为BINARY_FLOAT和BINARY_DOUBLE数据类型时,Inf可能被转换溢出,NaN可能被转换为0。

关于Cache Connect to Oracle数据类型映射

当为缓存集合表的列选择数据类型时,要考虑Oracle列的数据类型,并为缓存集合表中的列选择等价的数据类型。

主键和外键列级别要高于非键列。对于缓存集合表中的键列允许的数据类型映射显示在表 3.6中。

表 3.6 键列中允许的数据类型映射

Oracle数据类型

TimesTen数据类型

NUMBER(p,s)

NUMBER(p,s)

注意:也可以使用DECIMAL(p,s)或NUMERIC(p,s)。它们是NUMBER(p,s)的别名。

NUMBER(p,0)

INTEGER

TT_TINYINT

TT_SMALLINT

TT_INTEGER

TT_BIGINT

INTEGER

NUMBER(p,0)

NUMBER

TT_TINYINT

TT_SMALLINT

TT_INTEGER

TT_BIGINT

NUMBER

CHAR(m)

CHAR(m)

VARCHAR2(m)

VARCHAR2(m)

RAW(m)

VARBINARY(m)

TIMESTAMP(m)

TIMESTAMP(m)

DATE

DATE

NCHAR(m)

NCHAR(m)

NVARCHAR2(m)

NVARCHAR2(m)

表 3.7 显示关于缓存集合中非键列映射的数据类型。

表 3.7 关于非键列允许的数据类型映射

Oracle数据类型

TimesTen数据类型

NUMBER(p,s)

NUMBER(p,s)

REAL

FLOAT

BINARY_FLOAT

DOUBLE

BINARY_DOUBLE

NUMBER(p,0)

INTEGER

TT_TINYINT

TT_SMALLINT

TT_INTEGER

TT_BIGINT

INTEGER

NUMBER(p,0)

FLOAT

BINARY_FLOAT

DOUBLE

BINARY_DOUBLE

NUMBER

TT_TINYINT

TT_SMALLINT

TT_INTEGER

TT_BIGINT

NUMBER

REAL

FLOAT

BINARY_FLOAT

DOUBLE

BINARY_DOUBLE

CHAR(m)

CHAR(m)

VARCHAR2(m)

VARCHAR2(m)

RAW(m)

VARBINARY(m)

LONG

VARCHAR2(m)

注意:m可以是为此数据类型定义的范围内的任何有效值。

LONG RAW

VARBINARY(m)

注意:m可以是为此数据类型定义的范围内的任何有效值。

TIMESTAMP(m)

TIMESTAMP(m)

DATE

DATE

TIMESTAMP(0)

FLOAT(n)

注意:包括DOUBLE PRECISION和FLOAT,等于

FLOAT(126)。也包括REAL,等于FLOAT(63)。

FLOAT(n)

BINARY_DOUBLE

注意:FLOAT(126)可以声明为DOUBLE PRECISION。FLOAT(63)可以声明为REAL。

BINARY_FLOAT

BINARY_FLOAT

BINARY_DOUBLE

BINARY_DOUBLE

NCHAR(m)

NCHAR(m)

NVARCHAR2(m)

NVARCHAR2(m)

第四章 管理缓存集合

为缓存集合配置系统

这部分总结将TimesTen主机配置为Oracle Client并使用Cache Connect to Oracle特性来操作远程Oracle服务器的指定步骤。

1.在TimesTen主机上安装Oracle客户端或Oracle数据库。Oracle客户端或数据库必须在安装TimesTen之前装以防止使用Cache Connect特性时会出现问题。

2. 为特定的操作系统配置环境变更。

3. 安装TimesTen。

4. 如果打算使用基于Web的Cache Administrator,配置内植的web服务器。

5. 如果在TNSNAMES.ORA文件中定义Oracle Service Names,要使用系统级TNSNAMES.ORA文件。TimesTen的主守护程序、缓存代理、web服务器和复制代理将使用系统级TNSNAMES.ORA文件中提供的信息。不要使用不同的TNSNAMES.ORA文件来配置Oracle客户端。

注意:TimesTen不支持Oracle Name Server for Windows clients。

在UNIX平台上配置Cache Connect to Oracle

为TimesTen用户环境和启动TimesTen守护程序(根)的用户环境设置环境变量:

• 设置ORACLE_HOME环境变量为Oracle Client安装目录的路径。例如:

$ORACLE_HOME = /oracle/ora10g

• 对于32-位和64-位Oracle/TimesTen安装应该包括LD_LIBRARY_PATH或SHLIB_PATH环境变更:

$ORACLE_HOME/lib

$ORACLE_HOME/network/lib

install_dir/lib

例如:

LD_LIBRARY_PATH = $ORACLE_HOME/lib:$ORACLE_HOME/network/lib:

/timesten/myinstance/lib

注意:如果使用32-位TimesTen安装而配置64-位Oracle服务器,则库路径是$ORACLE_HOME/lib32。

• PATH环境变量应该包括:

$ORACLE_HOME/bin

install_dir/bin

例如:

PATH = $ORACLE_HOME/bin:/timesten/myinstance/bin

在Window系统中配置Cache Connect to Oracle

必须设置PATH系统环境变量包括:

Oracle_install_dir/bin

install_dir/lib

install_dir/bin

例如:

PATH = C:/Oracle/Ora10g/bin;C:/timesten/myinstance/lib;

C:/timesten/myinstance/bin;

Oracle数据库中安装任务

这部分将讨论操作Oracle DBA必须使用system帐号在Oracle数据库上执行。

创建Oracle用户并设置权限

必须指定一个Oracle用户和口令以访问Oracle表和创建缓存集合。所有Oracle用户帐号必须授予CREATE SESSION权限,以使用Cache Connect to Oracle。一些Cache Connect to Oracle操作要求另外的Oracle用户权限。

一些Cache Connect to Oracle操作要求一个使用另外Oracle权限的独立的用户。因为可能要求只授予另外缓存管理用户权限来选择用户,所以Cache Connect to Oracle允许创建一个独立的缓存管理用户帐号。

关于用于每个Cache Connect to Oracle操作的Oracle用户和缓存管理用户最小权限显示在表 4.1中。对一每个缓存管理用户的权限必须包括所有Oracle表可以被缓存到数据存储中,同时Oracle用户也需要特定的指定在由用户创建的缓存集合中的Oracle表的权限。参阅例 4.1。

表 4.1 对于缓存集合操作的Oracle权限要求

缓存集合操作

授予Cache Connect to

Oracle用户的最小权限

授予缓存管理用户的最小权限

所有操作

• 在Oracle数据库上CREATE SESSION

• SELECT TABLE

一个也不需要

CREATE READONLY

CACHE GROUP

• 在Oracle数据库上CREATE SESSION

• SELECT TABLE

• 在Oracle数据库上CREATE SESSION

• SELECT TABLE

• UNLIMITED TABLESPACE

(或在表空间上适当的空间引用 )

• CREATE TABLE①

• CREATE ANY TRIGGER①

CREATE

SYNCHRONOUS

WRITETHROUGH

CACHE GROUP

• 在Oracle数据库上CREATE SESSION

• SELECT TABLE

• INSERT

• UPDATE

• DELETE

一个也不需要

CREATE

ASYNCHRONOUS

WRITETHROUGH

CACHE GROUP

• 在Oracle数据库上CREATE SESSION

• SELECT TABLE

• INSERT②

• UPDATE②

• DELETE ②

• QUERY REWRITE③

• 在Oracle数据库上CREATE SESSION

• SELECT TABLE

• INSERT

• UPDATE

• DELETE

• UNLIMITED TABLESPACE

(或在表空间上适当的空间引用 )

• CREATE TABLE①

CREATE

USERMANAGED CACHE

GROUP(参阅并发行中的变量)

• 在Oracle数据库上CREATE SESSION

• SELECT TABLE

一个也不需要

CREATE

USERMANAGED CACHE

GROUP

.....加上 PROPAGATE

• 在Oracle数据库上CREATE SESSION

• SELECT TABLE

• INSERT

• UPDATE

• DELETE

一个也不需要

CREATE

USERMANAGED CACHE

GROUP

.....加上 AUTOREFRESH

INCREMENTAL

• 在Oracle数据库上CREATE SESSION

• SELECT TABLE

• QUERY REWRITE ③

• 在Oracle数据库上CREATE SESSION

• SELECT TABLE

• UNLIMITED TABLESPACE

(或在表空间上适当的空间引用 )

• CREATE TABLE①

• CREATE ANY TRIGGER①

LOAD CACHE GROUP

• 在Oracle数据库上CREATE SESSION

• SELECT TABLE

• 在Oracle数据库上CREATE SESSION

• SELECT TABLE

REFRESH CACHE

GROUP

• 在Oracle数据库上CREATE SESSION

• SELECT TABLE

• 在Oracle数据库上CREATE SESSION

• SELECT TABLE

FLUSH CACHE GROUP

• 在Oracle数据库上CREATE SESSION

• SELECT TABLE

• INSERT TABLE

• UPDATE TABLE

-

使用Real Application Clusters 进行配置的所有操作

• 在Oracle数据库上CREATE SESSION

• SELECT TABLE

在Oracle GV$SESSION上SELECT动态性能视图

如果Oracle对象是手工安装的,不要求创建缓存集合

不强从TimesTen执行

只对于Oracle server version 9.2才要求

4.1 需要为两个用户SamJohn设立权限,使每个用户可以发送一条CREATE READONLY CACHE GROUP语句来各自创建只读缓存集合。Sam创建一个缓存Oracle表TTUSER.TABLEA的缓存集合,John创建另一个缓存Oracle TTUSER.TABLEB的缓存集合。

为了提供SamJohn充足的Oracle权限来CREATE READONLY CACHE GROUP,需要创建两个Oracle用户帐号,并且其中一个缓存管理用户帐号将拥有扩展的权限。缓存管理用户的名称为User2

• oracleUID = Sam

• oracleUID = John

• cacheUid = User2

在Oracle上创建帐号:

SQL> CREATE USER Sam IDENTIFIED BY Samspwd DEFAULT TABLESPACE users;

SQL> CREATE USER John IDENTIFIED BY Johnspwd DEFAULT TABLESPACE users;

SQL> CREATE USER User2 IDENTIFIED BY User2pwd DEFAULT TABLESPACE users;

然后为每个用户分配下列权限:

SQL> GRANT CREATE SESSION, SELECT ON TTUSER.TABLEA TO Sam;

SQL> GRANT CREATE SESSION, SELECT ON TTUSER.TABLEB TO John;

SQL> GRANT

> CREATE SESSION,

> SELECT ON TTUSER.TABLEA, TTUSER.TABLEB,

> UNLIMITED TABLESPACE,

> CREATE TABLE,

> CREATE ANY TRIGGER

> TO User2;

SQL>

为缓存管理用户创建一个独立的表空间

TimesTen强烈推荐为缓存管理用户创建一个独立的表空间。此表空间用作缓存管理用户的缺省表空间。此表空间包含有每个Oracle表的自动刷新触发器、变化日志表和其它对于每个缓存集合用户TimesTen需要的对象。如果不指定一个独立的表空间,这些对象将放在Oracle system表空间中。

当在Oracle上创建缓存管理用户时,要指定表空间。也可以创建用户之后使用Oracle ALTER USER语句的DEFAULT TABLESPACE子句来指定表空间。

4.2 例 4.1 显示怎样创建并授权给缓存管理用户User2。为了给User2指定一个名为cacheuser的独立表空间,在Oracle中输入下列语句:

SQL> ALTER USER User2 IDENTIFIED BY User2pwd

DEFAULT TABLESPACE cacheuser;

每个缓存的Oracle表的变化日志表驻留在缓存管理用户表空间中。对于Oracle表上每次更新,将为此Oracle表向变化日志表插入一行(一条变化记录)。变化日志记录的字节大小如下:

变化日志记录的大小 = Oracle表上主键的大小 + 250

变化日志表中的记录数将依赖于Oracle表的更新率和TimesTen上的自动刷新间隔。每隔20秒,TimesTen将删除已经应用到缓存相关Oracle表的数据存储的变化日志记录。

当缓存管理用户表空间写满时

当缓存管理用户表空间变写满时,自动刷新触发器将通过删除已存在的变化日志记录来为新变化日志记录产生空间。这将引起一些TimesTen数据存储上一些表的完全自动刷新。

如果表空间写满,检查如下内容:

• 是否正在创建一个缓存集合或正在复制一个数据存储?这些临时操作将停止变化日志表上的清除操作。

• TimesTen数据存储上的缓存代理是否正在运行?如果缓存代理没有运行,变化日志记录将堆积。

• 在数据存储中是否没有通过删除自动刷新缓存集合而抛弃的数据存储?在这种情况下,变化日志记录也将堆积。

为缓存表定义DSN

缓存Oracle数据的数据存储必须定义为系统DSN,不能作为User DSN,如果TimesTen缓存不定义为System DSN,则TimesTen Cache Administrator就不能进行工作,而且ttAdmin也不能启动TimesTen缓存代理。

DSN路径必须是一个绝对值。

当为了缓存Oracle表创建DSN时,DSN的属性必须如下设置:

Logging 必须激活为disk-based。

LockLevel 必须激活row-level locking。(Cache Connect to Oracle不支持database-level locking。)

Isolation 可以是任何isolation模式。

OracleID 必须设置为Oracle Service Name for Oracle 9i和以后的Oracle版本。

PassThrough 可以设置来控制程序和SQL语句是在本地的TimesTen缓存中执行或是传递到Oracle。

DatabaseCharacterSet 必须与Oracle数据库字符集相同。

TypeMode 必须设置为0(Oracle)。

下列属性可以指定为DSN属性或作为连接属性:

• Oracle User ID指定Oracle用户ID。此字符串通过设置UID连接属性来间接指定。相应的UNIX平台上的DSN属性是UID。在Window系统中,相应的DSN属性是User ID。

OraclePWD 为Oracle用户指定口令。

用来连接到Oracle的用户名和口令将从DSN定义的属性中或ODBC连接串中取出。在连接串中给出的值将覆盖指定DSN中的值。

例如,可以在ttIsql连接串中指定Oracle UID和OraclePWD

ttIsql -connStr "DSN=cgDSN; UID=testuser; OraclePWD=mypsswrd"

如果通过ODBC应用发送更新并提交,必须在连接串中指定用户名和口令。例如:

SQLDriverConnect(hdbc, ..., "DSN=cgDSN; UID=testuser;

OraclePWD=mypsswrd", ...);

UNIX平台上 例如,为UNIX平台上的myOraCache定义就如下形式:

[myOraCache]

DataStore=/users/OracleCache/hotData

Authenticate=0

Logging=1

LockLevel=0

PermSize=40

TypeMode=0

DurableCommits=1

OracleID=system1

UID=testuser

OraclePWD=mypsswrd

DatabaseCharacterSet=WE8ISO1559P1

Windowt系统中 在ODBC TimesTen Setup dialog的Oracle Data Loading窗口中指定OracleID

启动和停止缓存代理

一个TimesTen进程调用一缓存代理来执行异步缓存操作,如加载或刷新缓存集合。许多Cache Connect to Oracle操作可以直接通过TimesTen进行,而不需要缓存代理的协助。

如果下列之一或多个情形为真,则必须为每个包含缓存集合的数据存储启动一个独立的缓存代理:

• 缓存集合为READONLY。

• 缓存集合为USERMANAGED并且包含一条AUTOREFRESH子句。

• 应用加载或刷新缓存集合。

可以从命令行或一个程序来为一个DSN启动缓存代理。

也可从基于浏览器的Cache Administrator来启动缓存代理。

注意:如果安装TimesTen时激活了Access Control,必须拥有数据存储的ADMIN权限来启动或停止缓存代理。另外,TimesTen用户名必须与Oracle用户名相匹配(应用到内部和外部的用户名)。

从命令行控制缓存代理

使用ttAdmin工具来从命令行控制缓存代理。可以使用ttAdmin来:

• 从命令行设置缓存管理用户ID和口令

• 从命令行启动缓存代理

• 从命令行停止缓存代理

• 从命令行设置代理启动性质

从命令行设置缓存管理用户ID和口令

如果使用下列之一的缓存集合类型,则必须有一个拥有相应Oracle权限的缓存管理用户帐号:

• ASYNCHRONOUS WRITETHROUGH缓存集合

• READONLY缓存集合

• 使用AUTOREFRESH属性的USERMANAGED缓存集合

缓存管理用户ID必须遵守下列规则:

• 长度为1到30字节。

• 必须以字母开头。

• 只能包含ASCII字母、下划线(_)、美元符号($)和英镑符号(#)。

缓存管理口令必须遵守下列规则:

• 长度为1到30字节。

• 可以包含除了分号(;)外的任何ASCII字符。

在启动缓存代理之前设置缓存管理用户ID和口令。使用如下语法:

ttAdmin -cacheUidPwdSet -cacheUid cacheUid -cachePwd cachePwd DSN

注意:如果数据存储中有自动刷新或AWT缓存集合,则缓存管理用户ID和口令不能进行重新设置。在重新设置缓存管理用户ID和口令之前,必须删除那些缓存集合。

例 4.3 ttAdmin -cacheUidPwdSet -cacheUid testuser -cachePwd mypass myOraCache

如果改变了缓存管理用户ID或口令,则必须重新启动缓存代理。

注意:如果在数据存储中没有缓存集合,则不要设置缓存管理用户ID和口令。如果没有缓存集合时设置了它们,将不会使用缓存管理用户ID和口令,并校验到Oracle数据库。

从命令行启动缓存代理

为了人命令行启动缓存代理,使用如下语法:

ttAdmin -cacheStart DSN

例 4.4 ttAdmin -cacheStart myOraCache

如果试图为在DSN中使用相关路径标识的数据存储启动缓存代理,TimesTen将搜索TimesTen运行和失败的相关数据存储。例如,在Window系统中,如果在DSN中为数据存储指定路径为DataStore=./dsn1,并且试图使用下面命令启动缓存代理:

ttAdmin -cacheStart dsn1

缓存代理在install_dir/srv/dsn1中搜索数据存储。将不能在此位置找到数据存储,也不能启动缓存代理。对于UNIX,缓存代理将查找:

/var/TimesTen/ttversion/bits

从命令行停止缓存代理

为了停止代理,使用如下语法:

ttAdmin -cacheStop DSN

例 4.5 ttAdmin -cacheStop myOraCache

注意:使用AUTOREFRESH特性时,在删除或改变缓存集合之后,不要立即停止缓存代理。应该至少等待2分钟。缓存代理需要这个时间来清除AUTOREFRESH使用的Oracle对象。

从命令行设置缓存代理启动性质

可以通过调用ttCachePolicySet程序来设置缓存代理启动性质。使用ttCachePolicyGet程序来返回当前的性质。

缺省的缓存代理启动性质是manual。如果要在TimesTen守护程序重新启动时将缓存代理自动重新启动,则设置缓存代理性质为always。一旦设置性质为always,缓存代理将立即启动。

4.6 设置缓存代理性质为always

CALL ttCachePolicySet ('always');

从程序控制缓存代理

为了从程序中控制数据存储的缓存代理,首先连接到数据存储。使用ttCacheUidPwdSetttCacheStartttCacheStopttCachePolicySet程序来执行下列任务:

• 从程序设置缓存管理用户ID和口令

• 从程序启动缓存代理

• 从程序停止缓存代理

• 从程序设置缓存代理性质

注意:如果Access Control被激活,则需要ADMIN权限来为缓存代理和复制代理进行启动、停止和设置性质。也需要ADMIN权限来设置缓存管理用户ID和口令。

从程序设置缓存管理用户ID和口令

如果使用下列类型之一的缓存集合,必须有一个拥有相应Oracle权限的缓存管理用户帐号:

• ASYNCHRONOUS WRITETHROUGH缓存集合

• READONLY缓存集合

• 使用AUTOREFRESH属性的USERMANAGED缓存集合

缓存管理用户ID必须遵守下列规则:

• 长度为1到30字节。

• 必须以字母开头。

• 只能包含ASCII字母、下划线(_)、美元符号($)和英镑符号(#)。

缓存管理口令必须遵守下列规则:

• 长度为1到30字节。

• 可以包含除了分号(;)外的任何ASCII字符。

在启动缓存代理之前设置缓存管理用户ID和口令。使用ttCacheUidPwdSet程序。

例 4.7 在此例中,通过连接句柄hdbc指定数据存储。缓存管理用户ID为testuser,并且缓存管理用户口令为mypass

sprintf( stmt, "CALL ttCacheUidPwdSet('testuser','mypass')");

rc = SQLAllocStmt( hdbc, &hstmt );

rc = SQLExecDirect( hstmt, (SQLCHAR *) stmt, SQL_NTS );

sprintf( stmt, "CALL ttCacheStart()" );

rc = SQLAllocStmt( hdbc, &hstmt2 );

rc = SQLExecDirect( hstmt2, (SQLCHAR *) stmt, SQL_NTS );

从程序启动缓存代理

使用ttCacheStart程序来启动缓存代理。

例 4.8 在此例中,通过连接句柄hdbc指定数据存储。

sprintf( stmt, "CALL ttCacheStart()" );

rc = SQLAllocStmt( hdbc, &hstmt );

rc = SQLExecDirect( hstmt, (SQLCHAR *) stmt, SQL_NTS );

注意:如果自动提交非激活,则必须在提交之前之后调用ttCacheStart

从程序停止缓存代理

使用ttCacheStop程序来停止缓存代理。

例 4.9 sprintf( stmt, "CALL ttCacheStop()" );

rc = SQLAllocStmt( hdbc, &hstmt );

rc = SQLExecDirect( hstmt, (SQLCHAR *) stmt, SQL_NTS );

ttCacheStop程序有一个选项参数stopTimeout,用来指定TimesTen守护程序要等多长时间才停止缓存代理。如果缓存代理在指定的时间内没有停止,则TimesTen守护程序将停止缓存代理。stopTimeout的缺省值是100秒。0值指定永远等待下去。

例 4.10 为了停止缓存代理,并设置stopTimeout为160秒:

sprintf( stmt, "CALL ttCacheStop(160)" );

rc = SQLAllocStmt( hdbc, &hstmt );

rc = SQLExecDirect( hstmt, (SQLCHAR *) stmt, SQL_NTS );

从程序设置缓存代理启动性质

可以通过调用ttCachePolicySet程序来设置缓存代理启动性质。使用ttCachePolicyGet程序来返回当前的性质。

缺省的缓存代理启动性质是manual。如果要在TimesTen守护程序重新启动时将缓存代理自动重新启动,则设置缓存代理性质为always。一旦设置性质为always,缓存代理将立即启动。

例 4.11 设置由hdbc连接句柄指定数据存储的缓存代理启动性质为always

sprintf( stmt, "CALL ttCachePolicySet ('always')");

rc = SQLAllocStmt( hdbc, &hstmt );

rc = SQLExecDirect( hstmt, (SQLCHAR *) stmt, SQL_NTS );

检查缓存代理的状态

可以使用ttStatus工具或ttDataStoreStatus程序来检查正在运行的TimesTen缓存代理。

例 4.12 为了使用ttStatus工具来确认位于c:/temp/cgds的数据存储的缓存代理正在运行,输入:

C:/>ttStatus

TimesTen status report as of Wed Apr 07 15:04:45 2004

Daemon pid 484 port 15000 instance MYCOMPUTER

No TimesTen server running

--------------------------------------------------------------

Data store c:/temp/cgds

There are 4 connections to the data store

Data store is in shared mode

Shared Memory KEY Global/DBI3cd02077.0.SHM.26 HANDLE 0x380

Subdaemon pid 964 context 0x5d82d0 connected (KEY

Global/DBI3cd02077.0.SHM.26)

Process pid 2040 context 0x97b200 connected (KEY

Global/DBI3cd02077.0.SHM.26)

Process pid 2040 context 0x1427c70 connected (KEY

Global/DBI3cd02077.0.SHM.26)

Process pid 2040 context 0x144bd70 connected (KEY

Global/DBI3cd02077.0.SHM.26)

TimesTen's cache agent is running for this data store

cache agent restart policy: manual

可以使用带有-query选项的ttAdmin工具来确认为数据存储设置的性质,包括缓存代理的重启性质。

例 4.13

C:/>ttAdmin -query cgDSN

RAM Residence Policy : inUse

Replication Agent Policy : manual

Replication Manually Started : False

cache agent Policy : manual

cache agent Manually Started : True

例 4.14 如果已经创建了一个AWT缓存集合,并且数据存储已经启动复制代理,则ttStatus工具也报告Oracle和复制代理的状态。在此例中,复制和缓存代理正在运行。

C:/> ttStatus

TimesTen status report as of Wed May 4 13:44:30 2005

Daemon pid 25337 port 16000 instance -

No TimesTen server running

No TimesTen webserver running

-----------------------------------------------------------------

------- Data store /datastore/cache There are 15 connections to

the data store Data store is in shared mode Shared Memory KEY

0x260e30c2 ID 521502725

Cache agent pid 25545 context 0x82fd820 name timestenorad

connid 2 connected (KEY 0x260e30c2)

Cache agent pid 25545 context 0x832d798 name timestenorad

connid 4 connected (KEY 0x260e30c2)

Cache agent pid 25545 context 0x8335198 name timestenorad

connid 3 connected (KEY 0x260e30c2)

Cache agent pid 25545 context 0xaf27ad08 name timestenorad

connid 6 connected (KEY 0x260e30c2)

Process pid 25485 context 0x80bd8b0 name cache connid 8

connected (KEY 0x260e30c2)

Replication pid 25559 context 0x8193110 name connid 7

connected (KEY 0x260e30c2)

Replication pid 25559 context 0x81bddb0 name connid 9

connected (KEY 0x260e30c2)

Replication pid 25559 context 0x81e53f8 name connid 12

connected (KEY 0x260e30c2)

Replication pid 25559 context 0x82040d8 name connid 5

connected (KEY 0x260e30c2)

Replication pid 25559 context 0x8229148 name connid 10

connected (KEY 0x260e30c2)

Replication pid 25559 context 0x824e1b8 name connid 11

connected (KEY 0x260e30c2)

Subdaemon pid 25350 context 0x8092960 name Worker connid

2044 connected (KEY 0x260e30c2)

Subdaemon pid 25350 context 0x8110140 name Flusher connid

2045 connected (KEY 0x260e30c2)

Subdaemon pid 25350 context 0x813a838 name Checkpoint

connid 2047 connected (KEY 0x260e30c2)

Subdaemon pid 25350 context 0x81608f8 name Monitor connid

2046 connected (KEY 0x260e30c2)

Replication policy : Manual

Replication agent is running.

Cache agent policy : Manual

TimesTen's Cache agent is running for this data store

为AWT缓存集合启动复制代理

如果使用异步写(AWT)缓存集合,必须启动复制代理。

CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP 语句将创建一个复制计划以激活数据存储与Oracle数据库之间的通信。复制计划完全由TimesTen管理,不需要用户介入。使用DROP CACHE GROUP语句删除AWT缓存集合时,复制计划也将被删除。

可能通过使用带有-repStart选项的ttAdmin工具从命令行启动复制代理。

例 4.15 AWTdsn数据存储启动复制代理。

ttAdmin -repStart AWTdsn

也可以通过使用ttRepStart程序从程序启动复制代理。

例 4.16 一个缓存管理用户的ID为testuser,口令为mypass,可以使用:

ttCacheUidPwdSet 程序来设置缓存管理用户ID和口令

ttCacheStart 程序来启动缓存代理

ttRepStart 程序来为AWTdsn数据存储启动复制代理

sprintf( stmt, "CALL ttCacheUidPwdSet('testuser','mypass')");

rc = SQLAllocStmt( hdbc, &hstmt );

rc = SQLExecDirect( hstmt, (SQLCHAR *) stmt, SQL_NTS );

sprintf( stmt, "CALL ttCacheStart()" );

rc = SQLAllocStmt( hdbc, &hstmt2 );

rc = SQLExecDirect( hstmt2, (SQLCHAR *) stmt, SQL_NTS );

sprintf( stmt, "CALL ttRepStart()" );

rc = SQLAllocStmt( hdbc, &hstmt3 );

rc = SQLExecDirect( hstmt3, (SQLCHAR *) stmt, SQL_NTS );

注意:在为AWT缓存集合发送一条CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP或DROP CACHE GROUP语句之前,要停止复制代理(如ttAdmin -repStop DSN)。

应用缓存集合定义到数据存储

如果有定义缓存集合的SQL文件,就可以在TimesTen数据存储上使用带有-f选项的ttIsql工具来执行此SQL。语法是::

ttIsql -f file.sql DSN

例 4.17 如果缓存集合在名为CG1.sql的文件中定义,可以在名为cgDSN的DSN上执行此文件,输入:

C:/> ttIsql -f CG1.sql cgDSN

也可以从ttIsql命令行执行包含缓存集合定义的SQL文件。例如:

Command> run CG1.sql

设置passthrough级别

应用通过TimesTen连接可以发送SQL语句到TimesTen或Oracle。

SQL是否被直接传送到TimesTen或Oracle将依赖于SQL语句的组成和PassThrough连接属性的设置。可以设置PassThrough属性来定义SQL语句的类型:是由本地的TimesTen处理,还是重定向到Oracle。

例如,可以设置PassThrough=0(缺省值)来指定所有SQL都在TimesTen中执行或PassThrough=3来指定所有SQL被传送到Oracle去执行。

如图 4.1显示,可以设置PassThrough=1来为一个不在TimesTen中的目标表或在TimesTen中产生的一条语法错误传送SQL。例如,一条到缓存表(Table A)的UPDATE 在TimesTen缓存中被处理,同时一条到在TimesTen中找不到的表(Table G)的UPDATE被传送到Oracle。同样地,TimesTen的设置程序如ttCacheStartttCkpt,由TimesTen处理,同时不支持的过程将传送到Oracle。

4.1 PassThrough=1

TIMESTEN内存数据库-最佳实践(已翻译)_第20张图片

对于PassThrough=1的设置,没有DDL语句会传送到Oracle。TimesTen中不存在的过程将被传送到Oracle:如果对于缓存集合表DML语句包含错误语法,就不会发送到Oracle。但是,所有包含错误语法的SELECT语句将被发送到Oracle。

对于所有的passthrough级别,如果事务有任何DDL或DML语句传送到Oracle,则提交和回滚将在Oracle和TimesTen中都要执行。否则,将只在TimesTen中执行。

READONLY缓存集合禁止在缓存集合中使用DML语句的更新。如果计划使用READONLY缓存集合,可以设置PassThrough=2来直接将缓存集合中所有表的DML语句定向到Oracle。否则,此设置将于PassThrough=1时一样,因此所有DDL语句、兼容的非DML语句及过程将直接到TimesTen。相同的passthrough情形也应用到USERMANAGED缓存集合中的READONLY表。例如,考虑如图4.1所示的缓存集合示例。如果在Table A上设置了READONLY属性,并且PassThrough = 2,一条到Table A的UPDATE将被传送到Oracle。

在AWT和SWT缓存集合的表DML操作不推荐使用passthrough特性。在被定义为异步的AWT集合中通过缓存进行的更新,passthrough将同步实施,可能将产生非预期结果。如果运用passthrough特性,SWT缓存集合中的更新可能导致自死锁。

Passthrough和参数绑定

确保应用为传送语句提供正确的SQL数据类型。ODBC驱动器将转换C和SQL类型,并向TimesTen传送转换的数据和SQL类型码。TimesTen传递此信息到Oracle。

TimesTen处理passthrough语句的参数与在TimesTen中它自己执行语句中的参数不同。TimesTen查询优化将为TimesTen语句的参数分配数据类型。应用将获得分配的数据类型来使用SQLDescribeParam ODBC函数。与此相比,passthrough语句的参数将不会为它们分配数据类型。TimesTen将报告passthrough语句的参数的数据类型为VARCHAR2(4000)。此数据类型只是一个占位符。它不意谓着TimesTen期望作为VARCHAR2数据来接收此参数值。作为替代,当应用调用SQLBindParameter ODBC函数时,必须通知TimesTen关于passthrough语句参数的数据类型。SQLBindParameter的fSqlType参数指定参数的SQL数据类型。如果使用,cbColDef和ibScale参数指定精度和比例。

例如,为了绑定一个SQL数据类型INTEGER的参数为NUMBER(3)参数,使用下列参数调用SQLBindParameter ODBC函数:

fCType=SQL_C_SLONG

fSqlType=SQL_DECIMAL

cbColDef=3

ibScale=0

二选其一,也可以使用下列参数:

fCType=SQL_C_SLONG

fSqlType=SQL_INTEGER

cbColDef=0

ibScale=0

对于SQL_INTEGER,cbColDef和ibScale参数将被忽略。

改变passthrough级别

可以在ttIsql会话中使用passthrough命令来覆盖DSN中PassThrough的设置。也可以为指定的事务通过调用ttOptSetFlag程序并指定‘passthrough’作为optflag参数和新的passthrough设置作为optval参数来重新设置passthrough。新的passthrough设置将立即产生影响。在事务的最后,passthrough将被重置为原来指定在PassThrough属性中的值。

注意:PassThrough的行为如同任何其它的优化标志。当执行语句时准备的语句是使用的级别时,将建立PassThrough级别。如果在准许语句和执行它之间改变了PassThrough级别,则在执行中将使用原来的PassThrough级别。

监视缓存集合

以下部分将讨论怎样得到缓存集合的配置信息和怎样监视缓存集合的状态。

使用ttIsql cachegroup命令

可以通过使用ttIsql cachegroup命令来获得关于数据存储中当前使用中的缓存集合的信息,如下面例4.18所示。

例 4.18

Command> cachegroup;

Cache Group TESTUSER.CUSTOMERORDERS:

AutoRefresh Mode: Incremental

AutoRefresh State: On

AutoRefresh Interval: 5 Minutes

Root Table: TESTUSER.CUSTOMER

Where Clause: (none)

Type: Read Only

Child Table: TESTUSER.ORDERTAB

Where Clause: (none)

Type: Read Only

Cache Group TESTUSER.TABCACHE:

Root Table: TESTUSER.TAB3

Where Clause: (none)

Type: Propagate

2 cache groups found.

监视自动刷新缓存集合

TimesTen提供下列工具来监视自动刷新缓存集合:

ttCacheAutorefreshStatsGet内部程序

• 支持日志中的信息

• 一个可以在Oracle数据库中执行的SQL脚本来显示关于变化日志表的信息

ttTraceMon工具的AUTOREFRESH组成

• SNMP陷阱

为READONLY、AUTOREFRESH和AWT缓存集合管理Oracle对象

READONLY缓存集合和一些USERMANAGED缓存集合使用AUTOREFRESH特性来自动将Oracle更新刷新到TimesTen缓存中。

可以为缓存集合建立完全或增量自动刷新模式。当配置为增量自动刷新时,TimesTen将为缓存集合中的每个Oracle基表要求创建一个触发器、日志表和其它对象。每次在Oracle基表上的插入、更新和删除操作将启动触器。触发器将在日志表中记录更新记录的主键。TimesTen缓存代理将定期搜索日志表中的更新键和关联的被更新的Oracle基表以得到最近更新的快照。

使用AUTOREFRESH INCREMENTAL属性创建缓存集合时,自动刷新的要求的Oracle对象将被自动安装。二选其一,可以手工安装Oracle对象,以允许用户使用较小的Oracle权限来创建要使用触发器的缓存集合。

在安装Oracle对象之前,必须:

• 有一个授予了额外的缓存管理用户权限的缓存管理用户帐号。

• 使用ttCacheUidPwdSet设置缓存管理用户ID和口令。

• 启动缓存代理。

对于每个缓存管理用户,TimesTen将创建下列各表,version是一个内部TimesTen版本号:

• TT_version_USER_COUNT

• TT_version_AGENT_STATUS

• TT_version_SYNC_OBJS

对于缓存集合中的每个表,TimesTen将创建下列对象,number是原Oracle表的对象ID,version是一个内部TimesTen版本号。

对象

描述

TT_version_number_L

为记录到Oracle表的变化变化日志表。

TT_version_number_T

在变化日志表记录变化的触发器。当在缓存表中有插入、删除和更新时被触发。

AWT缓存集合请求一个额外的Oracle对象。将在Oracle上创建一个名为TT_version_REPPPEERS的表用来跟踪状态和最近应用到Oracle的语句。此表将由CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP语句自动创建。二选其一,可以创建AWT缓存集合之前手工创建此Oracle表。

如果AWT缓存集合是一个活动的复制计划备用对的一部分,则当创建活动的备用对时,一个名为TT_version_REPACTIVESTANDBY将在Oracle上被自动创建。

TimesTen将下列表的SELECT、INSERT、UPDATE和DELETE的权限授予给user PUBLIC:

• TT_version_number_L

• TT_version_USER_COUNT

• TT_version_REPPEERS (为AWT缓存集合创建)

• TT_version_REPACTIVESTANDBY (为活动的备用复制计划中的AWT缓存集合创建)

自动安装Oracle对象

为了直接使TimesTen自动安装Oracle对象,确保缓存管理用户拥有所有要求的自动创建Oracle对象的权限。当以PAUSED或ON状态创建缓存集合或缓存集合状态被改为PAUSED或ON时,将自动创建Oracle对象。

例 4.19 显示怎样直接使TimesTen为READONLY缓存集合自动安装Oracle对象。

1. 使用ttIsql来连接到cgDSN数据存储。

2. 调用ttCacheUidPwdSet程序来为数据存储设置缓存管理用户ID(testuser)和口令。

3. 调用ttCacheStart程序来启动缓存代理。

4. 使用CREATE READONLY CACHE GROUP来创建一个READONLY缓存集合,此集合有AUTOREFRESH INCREMENTAL值,并且STATE被设置为缺省值PAUSED。

例 4.19

> ttIsql cgDSN

Command> call ttCacheUidPwdSet('testuser','mypsswrd');

Command> call ttCacheStart();

Command> CREATE READONLY CACHE GROUP readcache

FROM

user1.readtab

(a NUMBER NOT NULL PRIMARY KEY, b VARCHAR2(31));

例 4.20 显示怎样直接使TimesTen为AWT缓存集合自动安装Oracle对象。

例 4.20

> ttIsql cgDSN

Command> call ttCacheUidPwdSet('testuser','mypsswrd');

Command> call ttCacheStart();

Command> CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP writecache

FROM user1.writetab (a NUMBER NOT NULL PRIMARY KEY,b VARCHAR2(31));

手工安装Oracle对象

如果不需要授予用户完全自动安装Oracle对象的CREATE权限设置,可以手工安装Oracle对象,并允许用户使用较少的权限来创建AWT缓存集合和使用AUTOREFRESH INCREMENTAL属性的缓存集合。

对象的安装必须授予与选择自动安装选项的用户相同的Oracle权限。

获得SQL码需要通过下方式之一从TimesTen创建Oracle对象:

• 从ttIsql提示符,输入一条带有INSTALL标志的cachesqlget命令。

• 从一个程序中,调用ttCacheSqlGet内部程序并指定参数install_flag为‘1’。

注意:当获得SQL码来安装Oracle对象时,也应该产生一个来获得SQL码的脚本并保存它以在以后用来删除对象。

在已经获得SQL码以后,就可以通过在Oracle主机上启动SQL*Plus来手工创建Oracle对象,登录如下:

sqlplus cacheUid/cachePwd@machine_name

在SQL>提示符,输入SQL码来创建对象。

4.21 使用ttIsql来连接到数据存储。然后调用ttCacheStart程序来为数据存储启动缓存代理。缓存管理用户ID是testuser,口令为mypsswrd。下一步,使用CREATE CACHE GROUP来创建一个READONLY缓存集合,AUTOREFRESH STATE设置为OFF,并运行cachesqlget命令来获取必须的SQL来安装Oracle对象:

> ttIsql cgDSN

Command> call ttCacheUidPwdSet('testuser', 'mypsswrd');

Command> call ttCacheStart();

Command> CREATE READONLY CACHE GROUP readcache

AUTOREFRESH

MODE INCREMENTAL

INTERVAL 30 SECONDS

STATE OFF

FROM user1.readtab

(a NUMBER NOT NULL PRIMARY KEY, b VARCHAR2(31));

Command> cachesqlget readcache install;

从cachesqlget的输出相似如下:

CREATE TABLE system.tt_version_user_count(tableName VARCHAR2(65),

userCount

.... more code .....

END;

.

RUN;

可以从TimesTen剪贴和粘贴此SQL到Oracle上的SQL*Plus提示符:

SQL> CREATE TABLE system.tt_version_user_count(tableName

VARCHAR2(65), userCount

.... more code .....

END;

.

RUN;

二选其一,可以请求ttIsql将cachesqlget输出到一个在命令行中提供的输出文件名称的一个文件将其保存。然后可以拷贝此文件到Oracle系统并执行此文件来安装Oracle对象。

注意:如果手工安装Oracle对象,必须要手工删除它们。

手工为AWT缓存集合安装Oracle对象

当手工为AWT缓存集合安装Oracle对象时,必须在为Oracle实例创建AWT缓存集合之前安装。对于每个Oracle实例和缓存管理用户ID和口令,对象只需要安装一次。

执行下列任务来为一个AWT缓存集合安装Oracle对象:

1. 在ttIsql会话中使用ttCacheUidGet程序来检查是否已经设置缓存管理用户ID和口令。在此例中,DSN为cgDSN。NULL结果表示还没有为cgDSN设置缓存管理用户ID和口令。

> ttIsql cgDSN

Command> call ttCacheUidGet();

< >

1 row found.

2. 通过使用ttCacheUidPwdSet(uid,pwd)来设置缓存管理用户ID和口令。下面的例子在ttIsql会话中设置缓存管理用户ID为testuser,口令为mypsswrd,然后验证它已经被设置。

Command> call ttCacheUidPwdSet('testuser','mypsswrd');

Command> call ttCacheUidGet();

< testuser >

3. 通过使用ASYNCHRONOUS_WRITETHROUGH和INSTALL标志的ttIsql cachesqlget命令来获取SQL以安装对象。

Command> cachesqlget ASYNCHRONOUS_WRITETHROUGH INSTALL;

输出相似如下:

CREATE TABLE testuser.TT_03_RepPeers(

replication_name CHAR(31) NOT NULL,

replication_owner CHAR(31) NOT NULL,

tt_store_id NUMBER(19,0) NOT NULL,

subscriber_id NUMBER(19,0) NOT NULL,

commit_timestamp NUMBER(19,0),

commit_seqnum NUMBER(19,0),

timerecv NUMBER(10,0),

protocol NUMBER(10,0),

PRIMARY KEY(tt_store_id));

GRANT INSERT, UPDATE, DELETE, SELECT

ON testuser.TT_03_RepPeers TO PUBLIC;

CREATE TABLE testuser.TT_03_RepActiveStandby(

tt_store_pair INTEGER NOT NULL,

tt_store_id1 NUMBER(19,0) NOT NULL,

tt_store_id2 NUMBER(19,0) NOT NULL,

ts1 NUMBER(19,0),

ts2 NUMBER(19,0),

role1 CHAR(1),

role2 CHAR(1),

state NUMBER(10,0),

rep_checksum NUMBER(19,0),

PRIMARY KEY(tt_store_pair));

CREATE INDEX testuser.TT_03_RepActiveStandby_ix

ON testuser.TT_03_RepActiveStandby

( tt_store_id1, tt_store_id2 );

GRANT INSERT, UPDATE, DELETE, SELECT

ON testuser.TT_03_RepActiveStandby TO PUBLIC;

4. 剪切并粘贴SQL码到SQL*Plus会话以创建TT_version_REPPEERS。二选其一,可以从一个PassThrough属性被设置为3进行连接的TimesTen中的ODBC或JDBC程序中执行此代码。

如果AWT缓存集合是活动的备用对中的副本,还要创建TT_version_REPACTIVESTANDBY和TT_version_REPACTIVESTANDBY_IX。

Oracle对象的配置安装

为了确定安装在Oracle中的对象,登录Oracle帐号并从Oracle SQL *Plus命令提示符执行下列查询:

SQL> select owner, object_name, object_type from all_objects where

object_name like 'TT/___/_%' escape '/';

输出应该包含对象,相似如下:

OWNER OBJECT_NAME OBJECT_TYPE

------------- ------------------------------ ------------------

TESTUSER TT_03_34520_L TABLE

TESTUSER TT_03_34520_T TRIGGER

TESTUSER TT_03_USER_COUNT TABLE

TESTUSER TT_03_REPPEERS TABLE

删除Oracle对象

如果Oracle对象由Cache Connect to Oracle自动安装,则当设置AUTOREFRESH为OFF或使用DROP CACHE GROUP来删除缓存集合时,将自动删除。

如果手工安装Oracle对象,可以通过在Oracle系统中执行代码来卸载它们来删除对象。为了从TimesTen获得卸载代码,使用下列方式之一:

• 从ttIsql提示符,输入一条cachesqlget命令,指定uninstall。

• 从一个程序,调用ttCacheSqlGet程序并设置install_flag为0。

注意:如果在删除或改变自动刷新缓存集合之后立即关闭缓存代理,则它可能不会卸载Oracle对象。当重启缓存代理时,它将卸载删除或改变自动刷新缓存集合时留下的Oracle对象。

为AWT缓存集合手工删除Oracle对象

在从所有使用一个Oracle实例的数据存储中删除所有的AWT缓存集合之后,要为AWT缓存集合删除Oracle对象。

1. 从ttIsql会话,执行cachesqlget命令来获取SQL来删除对象。在此例中,DSN为cgDSN,并且用户是testuser。

> ttIsql cgDSN

Command> cachesqlget ASYNCHRONOUS_WRITETHROUGH UNINSTALL;

输出相似如下:

DROP TABLE testuser.TT_03_RepPeers;

DROP TABLE testuser.TT_03_RepActiveStandby;

2. 剪切并粘贴此SQL到SQL*Plus会话来删除对象。二选其一,可以从使用PassThrough属性被设置为3的TimesTen连接中的ODBC或JDBC程序中执行此代码。

第五章 使用缓存集合

这章将讨论怎样使用缓存集合。

改变缓存集合

使用ALTER CACHE GROUP语句来改变AUTOREFRESH STATE、INTERVAL和MODE的设置。任何通过ALTER CACHE GROUP设置的值或状态都是永久的;它们保存在数据存储中,并在TimesTen守护程序和缓存代理重新启动时生存。

注意:如果TimesTen安装时Access Control被激活,则必须拥有DDL权限来在数据存储中使用ALTER CACHE GROUP语句。

当一个AUTOREFRESH操作正在进行中并且将STATE改为OFF:

• 如果LockWait普通连接属性大于0,则AUTOREFRESH操作将停止。ALTER CACHE GROUP SET AUTOREFRESH STATE OFF语句优先于AUTOREFRESH操作。

• 如果LockWait普通连接属性为0,则AUTOREFRESH操作将继续。ALTER CACHE GROUP SET AUTOREFRESH STATE OFF语句将失败,产生一个锁定终止错误。

例 5.1 此例通过将状态改为ON来激活AutorefreshCustomers缓存集合的AUTOREFRESH:

ALTER CACHE GROUP AutorefreshCustomers

SET AUTOREFRESH STATE ON;

删除缓存集合

使用DROP CACHE GROUP SQL语句来从TimesTen中删除缓存集合和它所有相关的表。

注意:如果TimesTen安装时Access Control被激活,则必须拥有DDL权限来在数据存储中使用DROP CACHE GROUP语句。

如果删除使用了以INCREMENTAL模式的AUTOREFRESH并在Oracle进行手工安装对象的READONLY缓存集合或USERMANAGED缓存集合,则在删除缓存集合之前,必须手工删除Oracle对象。

当一个AUTOREFRESH操作正在进行时,如果输入一条DROP CACHE GROUP语句:

• 如果LockWait普通连接属性大于0,则AUTOREFRESH操作将停止。DROP CACHE GROUP语句优先于AUTOREFRESH操作。

• 如果LockWait普通连接属性为0,则AUTOREFRESH操作将继续。DROP CACHE GROUP语句将失败,产生一个锁定终止错误。

为了删除WesternCustomers缓存集合:

DROP CACHE GROUP WesternCustomers

所有WesternCustomers缓存中表将立即从TimesTen中被删除,并且缓存集合的定义也将从TimesTen系统表中被删除。

注意:所有AWT设置都将保持有效,直到DROP CACHE GROUP事务被提交。如果缓存集合是AWT,在删除缓存集合之前,确保所有绑定的更新都已经应用到Oracle。使用ttRepSubscriberWait程序。

在Oracle数据库和缓存集合之间拷贝数据

TimesTen多个机制来从Oracle拷贝数据到TimesTen和从TimesTen拷贝数据到Oracle。

一个应用可以使用下列SQL语句来在Oracle和缓存集合之间拷贝数据:

SQL语句

描述

LOAD CACHE GROUP

从Oracle 数据中加载还没有在缓存中的缓存实例。

REFRESH CACHE GROUP

使用当前的Oracle数据替换缓存实例。

FLUSH CACHE GROUP

从缓存集合表中拷贝数据到Oracle表。缓存集合必须是PROPAGATE没有激活的USERMANAGED。

PROPAGATE被激活的SWT缓存集合、AWT缓存集合和USERMANAGED缓存集合提供了自动方式来将缓存集合中的更新应用到Oracle表。

AUTOREFRESH缓存集合属性可用于READONLY和USERMANAGED缓存集合中来自动将Oracle表中变化应用到缓存集合中。

当一条SELECT查询在缓存集合表中没有找到数据时,可以使用事务加载特性来将Oracle表中的数据加载到缓存集合表中。可以对除了使用AUTOREFRESH属性以外的所有缓存集合使用事务加载。

AUTOREFRESH是一个缓存集合定义的一部分。在已经定义缓存集合并按需调用之后,事务加载就可以实现。事务加载与AUTOREFRESH缓存集合相比较,前者在缓存集合上的限制较少。

AUTOREFRESH适用于与静态数据相关的如产品目录或飞行航班表。事务加载在动态缓存内容方面更有用。应用可以使用事务加载特性来加载数据到缓存中,并使TimesTen代理自动删除长时间没有使用的数据。

加载和刷新缓存集合

可以使用一条LOAD CACHE GROUP或REFRESH CACHE GROUP语句来将数据从Oracle加载到缓存集合中。两种从Oracle拷贝数据到缓存集合的SQL语句都可以含或不含WHERE子句或WITH ID子句。加载和刷新的有如下不同:

• LOAD CACHE GROUP 不更新已经出现在缓存集合中的实例。

• REFRESH CACHE GROUP 使用最近的Oracle数据替换缓存集合中所有或指定的实例,即使实例已经出现在缓集合中。自动刷新操作相当于一条UNLOAD CACHE GROUP 语句后跟一条LOAD CACHE GROUP 语句。所有到Oracle数据的变化,包括根表和子表中的插入、更新和删除,将在刷新操作后反映到缓存中。

例 5.2 为了从Oracle加载数据到WesternCustomers缓存集合:

LOAD CACHE GROUP WesternCustomers

COMMIT EVERY 256 ROWS;

例 5.3 为了只从Oracle中加载Zip Code 94022中的用户的缓存集合实例到WesternCustomers 缓存集合:

LOAD CACHE GROUP WesternCustomers

WHERE (user1.customer.zip = 94022)

COMMIT EVERY 256 ROWS;

例 5.4 为了从Oracle表中刷新整个WesternCustomers 缓存集合:

REFRESH CACHE GROUP WesternCustomers

COMMIT EVERY 256 ROWS;

例 5.5 为了只刷新与合同号2353相关的缓存集合实例:

REFRESH CACHE GROUP WesternCustomers

WHERE (user1.orderdetails.itemid = 2353)

COMMIT EVERY 256 ROWS;

加载和刷新AUTOREFRESH和READONLY缓存集合

加载和刷新AUTOREFRESH和READONLY缓存集合有如下限制:

• 加载一个AUTOREFRESH呀READONLY缓存集合时,缓存集合必须为空。

• AUTOREFRESH状态必须是PAUSED。

• LOAD或REFRESH语句不能包含WHERE子句或WITH ID子句。

执行下列任务来加载一个AUTOREFRESH缓民集合:

1. 设置AUTOREFRESH状态为PAUSED。

ALTER CACHE GROUP testcache SET AUTOREFRESH STATE PAUSED;

COMMIT;

2. 卸载缓存集合。

UNLOAD CACHE GROUP testcache;

COMMIT;

3. 加载缓存集合。

LOAD CACHE GROUP testcache COMMIT EVERY 256 ROWS;

COMMIT;

4. 设置AUTOREFRESH状态为ON。

ALTER CACHE GROUP testcache SET AUTOREFRESH STATE ON;

COMMIT;

使用WITH ID加载或刷新缓存集合

WITH ID子句能够根据主键的值而不需要WHERE子句来加载或刷新一个缓存集合。可以以字段名或绑定参数来描述主键值。使用WITH ID子句将比使用等价的WHERE子句速度要快。如果失败,也能够回滚加载的事务。

WITH ID子句不能用于AUTOREFRESH或READONLY缓存集合。

WITH ID子句允许每次加载一个缓存实例。假设有一个orders表,其主键为order_id。如果用户调用一指定的合同,则可以通过为指定的order_id加载缓存实例加载相关信息。

例 5.6 在Oracle中,创建一名为sample的表:

CREATE TABLE sample (a NUMBER, b NUMBER, c NUMBER,

PRIMARY KEY (a,b));

缓装此表以使它包含以下行:

A B C

---------- ---------- ----------

1 2 3

4 5 6

7 8 9

在TimesTen上创建缓存集合:

CREATE SYNCHRONOUS WRITETHROUGH CACHE GROUP testcache

FROM sample

(a NUMBER, b NUMBER, c NUMBER, PRIMARY KEY (a,b));

使用主键有值(1,2)的行加载缓存集合:

LOAD CACHE GROUP testcache WITH ID (1,2);

1 cache instance affected.

SELECT * FROM sample;

< 1, 2, 3>

1 row found.

例 5.7 使用主键有值(4,5)的行刷新testcache缓存集合:

REFRESH CACHE GROUP testcache WITH ID (4,5);

1 cache instance affected.

SELECT * FROM sample;

< 1, 2, 3 >

< 4, 5, 6 >

2 rows found.

使用多表加载或刷新缓存集合

如果缓存集合包含多个表,并且Oracle当前正在更新被加载或刷新的表,在提交LOAD CACHE GROUP或REFRESH CACHE GROUP语句之前,可以设置TimesTen isolation级别为SERIALIZABLE。这将使TimesTen以连接的方式来查询Oracle表,并保证加载的数据与事务一致。在已经加载或刷新缓存集合之后,可以为更好的并发重新设置isolation级别为READ_COMMITTED。

例 5.8 在一个ttIsql会话中,在加载缓存集合之前可以重新设置isolation级别。当要加载或刷新缓存集合时,这个将应用到非日志模式。

Command> isolation SERIALIZABLE;

Command> LOAD CACHE GROUP WesternCustomers

>COMMIT EVERY 1000 ROWS;

Command> isolation READ_COMMITTED;

改善加载和刷新大表的执行速度

可以通过使用LOAD CACHE GROUP或REFRESH CACHEGROUP语句的PARALLEL子句来改善加载或刷新大表的执行速度。指定要使用的线程号。一个线程从Oracle中取出行,并且另外一个线程插入数据到缓存集合中。不要指定大于CPU能够加载的线程数量。

例 5.9

REFRESH CACHE GROUP WesterCustomers

COMMIT EVERY 256 ROWS

PARALLEL 2;

使用透明加载

当一条SELECT查询在缓存集合中没有查找到数据时,可以配置TimesTen来自动从Oracle表中加载数据到缓存集合表中。当执行SELECT语句时,被选择的和相关的行被加载到缓存集合的根表中,并且关联和被选择的行也被加载到子表中。只有那些满足缓存集合定义的行被加载。如果缓存集合有基于时间的老化性质定义,这些行也必须满足此老化性质。

可以为所有的类型的缓存集合配置透明加载,除了使用AUTOREFRESH属性的READONLY缓存集合和USERMANAGED缓存集合。

当缓存内容是动态的情况下,透明加载特别有用。例如,可以使用它来加载已经被老化删除的数据。

SELECT语句的类型

透明加载可用于下列类型的SELECT语句:

• SELECT在单表的主键上使用了一个等价的条件。此等价条件必须包括一个常量或参数。例如:

SELECT * FROM table1 WHERE primkey=1;

如果主键是复合键,则SELECT语句必须包括所有主键列的等价条件。例如:

SELECT * FROM table2 WHERE pkcol1=10 AND pkcol2=10;

• SELECT在单表的外键上使用了一个等价的条件。此等价条件必须包括一个常量或参数。例如:

SELECT * FROM table2 WHERE foreignkey=1;

如果外键是复合键,则SELECT语句必须包括所有外键列的等价条件。例如:

SELECT * FROM table2 WHERE fkcol1=10 AND fkcol2=10;

• 使用一个等价的条件选择缓存集合实例中的一个子树。例如:

SELECT * FROM table1,table2 where table1.primkey=1 and

table2.foreignkey=table1.primkey;

SELECT查询必须满足下列条件:

• SELECT查询必须是语句中最外层的查询。

• SELECT查询不能包含UNION、INTERSECT或MINUS结果集操作。

• 只有一个缓存集合中的表可以指定在最外层的SELECT查询中,但其它没有在缓存集合中的表可以指定在语句中。

当SELECT查询返回选择的行时,整个缓存实例都要被加载,以保持主键和外键之间的关联。.

配置透明加载

为了透明加载数据,设置TransparentLoad Cache Connect属性为1。这将使一条SELECT语句在Oracle表上被执行。数据结果将被加载到缓存集合表中。然后此数据通过在缓存集合表中执行原来的SELECT语句被透明返回。

下表总结关于TransparentLoad的设置:

设置

描述

0

不使用透明加载。(缺省)

1

在TimesTen中不发送错误信息或警告信息的运行SELECT语句。

2

如果SELECT操作不能使用透明加载,将返回一个错误。将根据TimesTen中可用的数据来执行SELECT操作。

二选其一,为了能够使用透明加载,可以使用SQLSetConnectOption ODBC函数来设置TT_TRANSPARENT_LOAD ODBC连接选项。此设置将应用到整个连接。

覆盖一个事务的透明加载

可以通过使用ttOptSetFlag内部程序的TransparentLoad标志来覆盖指定事务的TransparentLoad属性或TT_TRANSPARENT_LOAD ODBC选项。当语句准备时,TransparentLoad标志值就将产生影响,并且在运行时不能进行改变。在事务被提交或回滚时之后,此连接属性将重新产生影响。

冲洗USERMANAGED缓存集合

FLUSH CACHE GROUP语句将USERMANAGED缓存集合中的插入和更新冲洗到Oracle。不冲洗删除。指定为READONLY或PROPAGATE的表中的记录也不会冲洗到Oracle。

当从TimesTen到Oracle的数据提交被关闭时,使用FLUSH CACHE GROUP。相比每次事务提交更新数据,在更新被传送到Oracle之前,许多事务可以在TimesTen中被提交会更好。对于每个实例,如果缓存实例在Oracle中存在,则Oracle中操作将由一个更新构成。如果缓存实例在Oracle不存在,则TimesTen将插入它。

FLUSH CACHE GROUP语句可以使用WHERE或WITH ID子句指定以控制冲洗到Oracle的数据。

例 5.10 为了将WesternCustomers缓存集合中的变化冲洗到Oracle:

FLUSH CACHE GROUP WesternCustomers;

卸载缓存集合

可以使用UNLOAD CACHE GROUP SQL语句来删除缓存集合中一些或所有的实例。与DROP CACHE GROUP语句不同,它们中的表不会被删除。

对于使用AUTOREFRESH属性的缓存集合要小心使用UNLOAD CACHE GROUP语句。如果行或它的子行在Oracle中被更新,作为自动刷新的结果,被卸载的行有可能再次出现在缓存集合中。

例 5.11 为了从WesternCustomers缓存中删除所有实例:

UNLOAD CACHE GROUP WesternCustomers;

为了从WesternCustomers缓存中删除CustId = 1的用户:

UNLOAD CACHE GROUP WesternCustomers WITH ID(1);

UNLOAD CACHE GROUP WesternCustomers

WHERE (User1.Customer.CustId = 1);

复制缓存集合表

可以从一个数据存储中复制缓存集合表到另一个数据存储中的缓存集合表中或另一个数据存储的标准TimesTen表中。主数据存储中的缓存集合类型必须与子数据存储中的缓存集合类型相同。例如,READONLY缓存集合中的表可只能被复制到另一个数据存储中的READONLY缓存集合的表中或另一个数据存储的标准TimesTen表中。

缓存集合中的所有表都必须包括在复制计划中。

可以为下列类型的缓存集合通过配置一个名为active standby pair的复制计划来实现高效的缓存实例:

• READONLY缓存集合

• ASYNCHRONOUS WRITETHROUGH缓存集合

一个复制这些类型之一的缓存集合活动备用对可以自动地改变缓存集合的角色作为失败和使用最小数据丢失进行恢复的一部分。缓存集合给自己提供来自于Oracle数据库的弹性,进一步巩固系统的可靠性。

也可以配置缓存集合表的复制来实现工作量的平衡。下面的配置是一个示例:

• 加载平衡 — 配置从使用AUTOREFRESH属性的缓存集合中的表到标准表中的单向复制。Oracle上的更新将自动刷新到TimesTen缓存集合。此更新然后被复制到TimesTen表。

• 分隔工作量 — 在不同的数据存储的WRITETHROUGH缓存集合中的表之间配置双向复制。设计应用以使事务为了一个特定用途(例如,一个地理区域)只更新特定的缓存数据表,并且相同的缓存集合表不能在两个存储中都直接被更新。在一个存储中被更新的缓存集合表被复制到另一个数据存储中相应的缓存集合表中。更新将直接通过应用传送到Oracle,但不进行复制更新。

不要使用活动active/活动配置,特别是复制缓存集合时。这种配置的非预期结果包括不可解的死锁、缓存集合内容的冲突和恢复问题。

改变Oracle规划

Cache Connect to Oracle没有机制来发现Oracle数据库由际操作如CREATE、DROP或ALTER引起的规划改变。如果需要改变Oracle规划,则要执行下列任务:

1. 使用DROP CACHE GROUP来删除所有缓存Oracle被改变表的缓存集合。

2. 停止缓存代理。

3. 对Oracle进行期望的改变。

4. 使用CREATE CACHE GROUP来重新创建缓存集合。

如果在Oracle数据库中规划被修改之前不删除缓存集合,则在原来缓存集合中的操作,包括AUTOREFRESH,可能成功,也可能失败而产生错误。

增量AUTOREFRESH不能发现一人Oracle表的截短。如果要截短一个Oracle基表,则要执行下列任务:

1. 使用ALTER CACHE GROUP语句来设置AUTOREFRESH STATE为PAUSED。

2. 截短Oracle基表。

3. 通过使用不带有WHERE或WITH ID子句的REFRESH CACHE GROUP语句刷新缓存集合。

在刷新缓存集合之后,自动刷新操作将重新开始。

注意:在缓存集合中不允许截短TimesTen表。

注意:如果缓存集合是AWT,在删除缓存集合之前,确保所有绑定的更新已经应用到Oracle。使用ttRepSubscriberWait程序。

第六章 Cache Administrator

关于Cache Administrator

TimesTen提供了一个基于浏览器名为Cache Administrator的工具创建缓存集合定义和工作。Cache Administrator能够使用管理员使用位于与安装TimesTen相同的机器上的Web浏览器通过操纵Oracle规划来定义一个或多个缓存集合。可以设置Web服务器以使能够访问Cache Connect to Oracle。

下列Web浏览器支持Cache Administrator:

• Internet Explorer 6.0

• Firefox 1.5和以后的版本

安全

缓存集合定义保存在守护程序目录中的ws/cgi-bin/cache/cachedata文件中。可以通过输入ttVersion –m命令来获得守护程序目录。

缓存集合定义既包括查询和索引又包括连接信息的定义。如果Access Control被激活,连接信息也包括Oracle用户和TimesTen用户。

Oracle用户帐号必须拥有下列权限:

• CREATE SESSION

• 需为为每个缓存集合创建需要访问的表的SELECT

当Access Control为TimesTen实例激活时,用户必须是一个内部TimesTen用户。TimesTen用户必须有下列权限:

• DDL

• SELECT

当Access Control被激活时,TimesTen用户必须拥有ADMIN权限,以使它能够从命令行启动和停止缓存代理。

启动Cache Administrator

在启动Cache Administrator之前,确保:

• Oracle客户端已经安装到要启动Cache Administrator的机器上。

• 要正确设置ORACLE_HOME环境变量。在启动TimesTen守护程序之前,必须进行设置。

• UNIX上的LD_LIBRARY_PATH或Window上的PATH要设置正确。

• Cache Connect to Oracle已经成功安装。

• TimesTen守护程序正在运行。

• Web服务器正在运行。可以通过使用ttStatus来验证。实例管理员可以通过使用带有-startwebserver选项的ttDaemonAdmin工具来启动它。

通过在浏览器中输入下列URL来启动Cache Administrator:

http://localhost:port/cache

本地主机只支持可以启动Web服务的位置。这就意谓着Cache Administrator必须运行在安装TimesTen的机器上。试图从其它机器上查看Cache Administrator将会失败。

port是守护程序Web服务器的端口号。端口号在安装时指定。如果不知道此端口号,查看守护程序目录中守护程序的Web服务日志webserver.log。

在Window平台上,可以从Start >Programs > TimesTen菜单来启动Cache Administrator。

连接到数据存储

在为数据存储启动缓存代理之后,选择Login来连接到数据存储。图 6.1 显示如果在数据存储上没有激活Access Control时的Connect to a Data Store 屏幕。

6.1 不使用Access Control连接到数据存储

TIMESTEN内存数据库-最佳实践(已翻译)_第21张图片

下字段必须完成:

TimesTen DSN — 指定用于缓存的TimesTen数据存储。可以输入一简单串(DSN的名称)或完整连接串。

简单串是一个在Window系统中ODBC面板或UNIX平台上SYS.ODBC.INI文件中已经创建的DSN的名称。

下面是一个完整连接串的示例:DSN=CacheData;DurableCommits=0;DatabaseCharacterSet=US7ASCII;

Oracle username — Oracle数据库上的一个用户帐号。它获取关于保存在Oracle上的表和索引信息。

Oracle password — 指定Oracle用户的口令。

TimesTen password — 如果数据存储上的Access Control被激活,也必须输入TimesTen Password,如图 6.2所示。Password输入是大小写敏感的。

6.2 使用激活的Access Control连接到数据存储

TIMESTEN内存数据库-最佳实践(已翻译)_第22张图片

在完成输入后,单击Log in

当成功连接到数据存储时,Cache Administrator选项将显示如图 6.3所示。

6.3 欢迎页和完整菜单

TIMESTEN内存数据库-最佳实践(已翻译)_第23张图片

使用Cache Administrator

可以使用Cache Administrator来执行下列任务:

• 管理缓存集合定义(创建、拷贝、修改和删除)。

• 查看描述缓存集合的SQL语句。

• 为创建缓存集合生成必须的SQL语句,并发送信息到到创建它的数据存储。

• 创建缓存集合。

• 管理缓存代理(启动、停止、状态)。

Cache Administrator的在线帮助将说明怎样执行这些任务。

第七章 在RAC环境中实现Cache Connect

这章将讨论怎样在RAC环境中实现Cache Connect to Oracle。

在RAC环境中Cache Connect怎样工作

Oracle Real Application Clusters (RAC)能够使多个Oracle实例使用共享资源访问一个数据库,共享资源包括驻留在簇共享磁盘上所有的数据文件、控制文件、PFILE和重做日志文件。在提供高性能的同时,RAC处理连续的读/写和加载平衡。

Fast Application Notification (FAN)是一个与Oracle Call Interface (OCI) in Oracle Database 10g Release 2结合使用的RAC特性。FAN发布关于簇上变化的信息给订阅FAN事件的应用。FAN将排除如下的降低效率的行为:

• 当服务被关闭时的试图连接

• 当服务被关闭时的试图完成事务的进程

• 等待TCP/IP终止

不使用FAN,Cache Connec可能要花费数分钟来接收一个Oracle失败的通知。

Transparent application failover (TAF)是一个Oracle Net Services的特性,以使可以指定失败以后需要应用怎样进行重新连接。Cache Connect将OCI结合FAN使用来接收Oracle事件的通知。OCI应用可以使用下列类型之一的Oracle Net失败功能:

• 会话:如果一用户的连接丢失,一个新的会话将自动为用户创建。此失败的类型不会试图恢复选择。

• 选择:此失败的类型可以使用户在失败以后使用打开游标来继续在里面取值。

• 无:这是缺省值。不使用失败功能。也可以显式指定来防止失败的产生。

Cache Connect能够很快地从Oracle失败中恢复过来,而不需要用户的干预。Cache Connect可以与Oracle Database 10g Release 2 server一起用于RAC环境。Oracle客户端可以是Oracle9i Release 2或Oracle Database 10g Release 2。

Cache Connect的行为将依赖于TAF的动作和TAF是怎样配置的。RACCallback Cache Connect属性缺省地注册TAF和FAN回叫。如果不需要TAF和FAN可用,则在连接串中设置RACCallback为0。

表 7.1 显示在使用不同的TAF失败类型的RAC环境中Cache Connect特性和操作的行为。这些行为与Oracle9i Release 2和Oracle Database 10g Release 2客户端一样,除了当Oracle Database 10g Release 2中FAN被激活时,Cache Connect将立即接收到节点失败的通知。

表 7.1 在RAC环境中Cache Connect特性和操作的行为

特性或操作

TAF失败类型

在连接到Oracle数据库失败后Cache Connect的行为

Autorefresh

缓存代理将自动关闭、重启和等待,直到可以建立到Oracle服务的连接。此行为与Cache Connect to Oracle release 6.0.1和非RAC环境中的Cache Connect中的一样。

Autorefresh

Session

将发生下列情形之一:

• 所有失败的连接将恢复。正在进行中的Autorefresh操作将被回滚并重试。

• 如果TAF时间已到或不能恢复连接,则缓存代理将自动关闭、重启和等待,直到可以建立到Oracle服务的连接。此行为与Cache Connect to Oracle release 6.0.1和非RAC环境中的Cache Connect中的一样。

Autorefresh

Select

将发生下列情形之一:

• Autorefresh将从连接失败点继续重新开始。

• 正在进行中的Autorefresh操作将被回滚并重试。

•如果TAF时间已到或不能恢复连接,则缓存代理将自动关闭、重启和等待,直到可以建立到Oracle服务的连接。此行为与Cache Connect to Oracle release 6.0.1中的一样。

Passthrough、

SWT、propagate和flush

通知应用连接丢失并必须回滚TimesTen连接。在下一次passthrough操作期间,Cache Connect试图重新连接到Oracle数据库。所有被修改的会话属性会丢失。此行为与Cache Connect to Oracle release 6.0.1和非RAC环境中Cache Connect中的一样。

Passthrough、

SWT、propagate和flush

Session

将发生下列情形之一:

• 将恢复到Oracle数据库的连接。如果在丢失的连接上有打开的游标、DML或锁定操作,则会产生一个错误,并且用户必须回滚事务。否则用户可以继续而不使用回滚。

• 如果TAF时间到或不能恢复连接,通知应用连接丢失并必须回滚TimesTen连接。在下一次passthrough操作期间,Cache Connect试图重新连接到Oracle数据库。所有被修改的会话属性会丢失。此行为与Cache Connect to Oracle release 6.0.1和非RAC环境中Cache Connect中的一样。

Passthrough

Select

将恢复到Oracle数据库的连接。如果在丢失的连接上有打开的游标、DML或锁定操作,则会产生一个错误,并且用户必须回滚事务。否则用户可以继续而不使用回滚。

SWT、

Propagate、

和flush

Select

将发生下列情形之一:

• 将恢复到Oracle数据库的连接。如果在丢失的连接上有DML或锁定操作,则会产生一个错误,并且用户必须回滚事务。否则用户可以继续而不使用回滚。

• 如果TAF时间到或不能恢复连接,通知应用连接丢失并必须回滚TimesTen连接。在下一次passthrough操作期间,Cache Connect试图重新连接到Oracle数据库。所有被修改的会话属性会丢失。此行为与Cache Connect to Oracle release 6.0.1和非RAC环境中Cache Connect中的一样。

Load和

refresh

应用将收到一个连接丢失的错误。

Load和

refresh

Session

将发生下列情形之一:

• 加载成功。

• 返回一个错误,报告Oracle取值不能执行。

Load和

refresh

Select

将发生下列情形之一:

• 如果Oracle游标被打开,并且游标被恢复或Oracle游标没有被打开,则加载成功。

• 如果TAF不能恢复会话或打开Oracle游标,则返回一个错误。

注意:返回错误的可能性小于TAF失败类型是Session。

AWT

AWT的复制接收线程存在。产生一个新线程并试图连接到Oracle数据库。

AWT

Session、

select

将发生下列情形之一:

• 如果连接被恢复并且在连接上有未提交的DML操作,则批量操作或事务将被回滚并重新执行。

• 如果连接被恢复并且在连接上无未提交的DML操作,则工作继续。

在RAC环境中使用Cache Connect的限制

可以为下列Oracle客户端和服务器的版本在RAC环境中使用Cache Connect to Oracle:

• Oracle Database 10g Release 2。如果客户端和服务器的版本都是Oracle Database 10g Release 2,则只能使用FAN。

• Oracle Database 10g Release 1

• Oracle9i Release 9.2

对于每个版本,要使用Oracle客户端最近的版本。

Cache Connect支持的RAC有下列限制:

• Cache Connect的行为被限制为使用RAC、FAN和TAF的能力。例如,如果服务所有的节点失败,服务将不会重启。Cache Connect将等待用户来重新启动服务。

• TAF不会恢复ALTER SESSION操作。由用户负责在失败之后恢复改变了的会话属性。

• Cache Connect结合FAN事件使用Oracle Client Interface (OCI)。此接口自动产生一个线程来等待一个Oracle事件。在一个直接连接的TimesTen应用中产生一个线程只是TimesTen的特性。建修改ODBC应用以解决此线程的创建。如果不需要额外的线程,设置RACCallback Cache Connect属性为0。则将不会使用TAF和FAN。

在RAC环境中安装Cache Connect

安装Cache Connect和RAC。确保缓存管理用户在s Oracle GV$SESSION动态执行视图上有SELECT权限。

有两个TimesTen环境变量控制TAF超时设置:

• TT_ORA_FAILOVER_TIMEOUT:TAF以分钟数为用户应用(SWT缓存集合、使用propagate选项的缓存集合和使用passthrough特性的缓存集合)进行超时设置。缺省值是5分钟。

• TT_AGENT_ORA_FAILOVER_TIMEOUT:TAF以分钟数为复制代理(对于AWT缓存集合)进行超时设置。缺省值为5小是。

下列Oracle组件也必须启动:

• Oracle实例

• Oracle监听器

• 将用于Cache Connect的Oracle服务

然后执行下列任务:

1. 核实RACCallback连接属性被设置为1(缺省值)。

2. 使用DBMS_SERVICE.MODIFY_SERVICE Oracle PL/SQL包或Oracle Enterprise Manager以使可以进行FAN事件的发布。这将改变Oracle ALL_SERVICES视图的AQ_HA_NOTIFICATIONS列为YES。(这将应用到Oracle Database 10g Release 2客户端。)

3. 通过下列方式之一使得在服务上能够使用TAF:

• 在Oracle tnsnames.ora文件中使用下列字符为Cache Connect创建一个服务:

– LOAD_BALANCE=ON (选项)

– FAILOVER_MODE=(TYPE=SELECT)或FAILOVER_MODE=(TYPE=SESSION)

• 使用DBMS_SERVICE.MODIFY_SERVICE来设置TAF失败类型。

4. 如果应用是一个ODBC直接连接应用,使用一个线程库进行连接,以使它能够接收FAN通知。FAN将产生一个线程来监视失败。(这将应用到Oracle Database 10g Release 2客户端。)

第八章 TimesTenOracle之间的兼容性

这章将列出TimesTen和Oracle之间的兼容性问题。此列表不完整,但它包括需要特别注意的地方。

注意:TimesTen不支持Oracle Call Interface (OCI)。

兼容性问题总结

考虑下面TimesTen和Oracle之间的不同:

• TimesTen和Oracle数据库的元数据保存不同。

• TimesTen和Oracle有不同的事务隔绝模式。

• TimesTen和Oracle有不同的连接和语句属性。例如,timesTen不支持目录名、滚动游标或更新游标。

• 对于ROWID,TimesTen和Oracle不同的类型和长度。TimesTen 不支持Oracle ROWID数据类型。

• Sequence不会被缓存,并且在缓存和Oracle数据库之间不同步。

• 触发器和过程的作用不会传送到缓存中,直到一个AUTOREFRESH操作或手工REFRESH CACHE GROUP操作之后。

• 在缓存集合中不支持XA和JTA API。

关于Oracle客户端/服务器版本的Cache Connect支持

Cache Connect to Oracle不防碍所有支持的Oracle客户端/服务器相互联合协调工作的配置。例如,在TimesTen服务的机器上Cache Connect使用9.2.0.8 Oracle客户端安装并连接到不同服务器上的10.2.0.3 Oracle数据库是被支持的。用户应该检查Metalink Documentation Note 207303.1、“Client/Server/Interoperability Support Between Different Oracle Versions”中关于当前Oracle客户端/服务器支持的配置信息。用户也应该检查关于交互问题的Oracle和TimesTen版本注意事项。

事务的意义

TimesTen和Oracle的事务意义的不同如下:

• Oracle连接的事务在提交时可能失败,因为事务不能被连续化。而TimesTen将使用锁来强制进行连续的事务。

• Oracle用户可以通过显式的SQL来锁定表。此锁定特征在TimesTen中不支持。

• Oracle支持保存点。而TimesTen不支持。

• 在Oracle中,事务可以被设置为只读/。这在TimesTen中也是不支持的。

JDBC兼容性

应用到JDBC的兼容性问题包括如下:

• JDBC数据库元数据函数返回TimesTen元数据。如果需要Oracle元数据,可以使用带有PassThrough属性的Cache Connect或直接连接到Oracle数据库。

设置/得到连接和语句属性将在TimesTen上。

• 所有Oracle java.sql.ResultSet元数据(长度、类型、标签)将以TimesTen数据类型长度返回。返回的列标签也是TimesTen列标签。

• 对于java.sql.CallableStatement方法的输出参数(OUT和INOUT),在TimesTen中不被支持。

• 不支持Oracle扩展(oracle.sql和oracle.jdbc包)。

• 在TimesTen中不支持Java存储过程。

注意:TimesTen不支持语句的异步执行,也不支持从一个不同的线程取消一条执行语句。

java.sql.Connection

下面的Connection方法没有兼容性问题:

close

commit

createStatement

setAutoCommit

prepareCall

prepareStatement

rollback

下面的方法在本地TimesTen中被执行:

getCatalog

getMetaData

get/setTransactionIsolation

isReadOnly

isClosed – 只返回TimesTen连接状态

nativeSQL

setCatalog

setReadOnly

java.sql.Statement

下面的Statement方法有兼容性问题:

close

execute

executeUpdate

executeQuery

getResultSet

getUpdateCount

getWarnings

executeBatch

clearBatch

addBatch

下面的方法在本地的TimesTen中执行:

get/setMaxFieldSize

get/setMaxRows

get/setQueryTimeout

getMoreResults

setEscapeProcessing

setCursorName

cancel

java.sql.ResultSet

下面的ResultSet方法没有兼容性问题:

close

findColumn(int) 和 findColumn(string)

getXXX(number) 和 getXXX(name)

getXXXStream(int) 和 getXXXStream(string)

getMetaData

java.sql.PreparedStatement

下面的PreparedStatement方法没有兼容性问题:

execute

executeUpdate

executeQuery

setXXX

setXXXStream

close

getResultSet

getUpdateCount

addBatch

下面的方法在本地TimesTen中执行:

get/setMaxFieldSize

get/setMaxRows

get/setQueryTimeout

getMoreResults

setEscapeProccessing

setCursorName

cancel

java.sql.CallableStatement

与显示在java.sql.Statement和应用到CallableStatementjava.sql.PreparedStatement接口有相同的限制。另外,使用任何输出形态的CallableStatement都不被支持。所有参数都被作为输入参数。没有输出参数的Callablestatement可能在准备时返回一个错误,通过registerOutparameter返回错误或应用可能得到非预期的结果。

• 在一个WRITETHROUGH缓存集合中,如果PassThrough=1,则隐藏在存储过程中或通过触发器产生的间接DML操作可能被传送,但没有被Cache Connect to Oracle发现。

• 从READONLY缓存集合进行更新的、插入或删除的存储过程将在另一个异步方式的事务中被自动刷新。因此在存储过程被执行的相同事务中将不会出现变化,并且在自动刷新到缓存表之前,会有一段时间间隔。

java.sql.ResultSetMetadata

下面ResultSetMetadata方法没有兼容性问题:

getColumnCount

getColumnType

getColumnLabel

getColumnName

getTableName

isNullable

下面的方法在本地的TimesTen中执行:

getSchemaName

getCatalogName

getColumnDisplaySize

getColumnType

getColumnTypeName

getPrecision

getScale

isAutoIncrement

isCaseSensitive

isCurrency

isDefinitelyWritable

isReadOnly

isSearchable

isSigned

isWritable

Stream support

兼容性问题相关的流是:

• JDBC驱动器在调用executeQuerynext方法时将数据完全取出并放入到内存缓冲区。getXXXStream条目指针返回从此缓冲区读数据的流。

• Oracle支持最大到2GB的long或long raw数据。

• Oracle总是long/long raw数据流,即使应用没有调用getXXXStream

• TimesTen没有close方法。当它移动到下一行时,将使stream流无效。当移动到下一列时,Oracle将关闭流。

• TimesTen不支持markmarkSupportedreset方法。

ODBC兼容性

下表列出ODBC 2.5 API调用和指出函数是否有兼容性问题。

函数

兼容性

SQLAllocConnect

-

SQLAllocEnv

-

SQLAllocStmt

-

SQLBindCol

-

SQLBindParameter

当一条SQL语句有相同的参数名时,TimesTen认为它们是相同参数的多次出现,不允许它们分别绑定。Oracle认为它们是不同的参数,并允许它们分别绑定。

SQLBrowseConnect

不支持

SQLCancel

TimesTen不支持语句的异步执行,并且不支持从一不同的线程来取消一条执行语句。

SQLColAttributes

-

SQLColumnPrivileges

不支持

SQLColumns

元数据函数从TimesTen表返回元数据。

SQLConnect

-

SQLDataSource

-

SQLDescribeCol

-

SQLDescribeParam

-

SQLDisconnect

-

SQLDriverConnect

-

SQLDrivers

-

SQLError

是TimesTen错误的本地错误码。用户可以接收到一般错误如“execution at Oracle failed, Oracle error code nnn.”。

SQLExecDirect

-

SQLExecute

-

SQLExtendedFetch

不支持

SQLFetch

-

SQLForeignKeys

元数据函数从TimesTen表返回元数据。

SQLFreeConnect

-

SQLFreeEnv

-

SQLFreeStmt

-

SQLGetConnectOption

-

SQLGetCursorName

TimesTen支持get/set游标名,但不支持游标delete/update语句。

SQLGetData

-

SQLGetFunctions

-

SQLGetInfo

-

SQLGetStmtOption

-

SQLGetTypeInfo

元数据函数从TimesTen表返回元数据。

SQLMoreResults

不支持

SQLNativeSql

-

SQLNumParams

-

SQLNumResultCols

-

SQLParamData

-

SQLParamOptions

-

SQLPrepare

-

SQLPrimaryKeys

元数据函数从TimesTen表返回元数据。

SQLProcedureColumns

元数据函数从TimesTen表返回元数据。

SQLProcedures

元数据函数从TimesTen表返回元数据。

SQLPutData

-

SQLRowCount

-

SQLSetConnectOption

设置函数设置TimesTen选项或元数据。

SQLSetCursorName

设置函数设置TimesTen选项或元数据。

SQLSetPos

不支持

SQLSetScrollOptions

不支持

SQLSetStmtOption

设置函数设置TimesTen选项或元数据。

SQLSpecialColumns

元数据函数从TimesTen表返回元数据。

SQLStatistics

元数据函数从TimesTen表返回元数据。

SQLTablePrivileges

不支持

SQLTables

元数据函数从TimesTen表返回元数据。

SQLTransact

-

SQL兼容性

这部分比较TimesTen的SQL与Oracle的SQL的执行。目的是提供用户一个在TimesTen中不支持或使用不同意义支持的Oracle SQL特性的列表。这部分比较Oracle Database 10g Release 2和Oracle TimesTen In-Memory Database 7.0.0.0.0。

计划对象

TimesTen不承认一些Oracle中支持的计划对象。当语句操作或使用这些对象并传送到Oracle时,TimesTen将返回一个语法错误。不支持的对象是:

• 与存储过程相关的对象

– 存储过程

– 存储函数

– 包

– 触发器

• 访问控制对象

– 角色

– 外形

– 上下文

• 存储管理特性

– 簇

– 表空间

–回滚段

– CREATE/DROP DATABASE语句

– 数据库链节

– 目录

– 分区

• 扩展特性

– 扩展程序库

– Object表

– Object类型

– Object视图

TimesTen支持视图和物化视图,但不支持缓存Oracle视图。当TimesTen中没有相同的本地对象名时,包括视图和物化视图的语句将传送到Oracle。

Oracle和TimesTen表之间的差异

一些TimesTen不支持的Oracle特性是:

• ON DELETE SET NULL

• 约束检查

数据类型支持

下列Oracle数据类型不被TimesTen支持:

TIMESTAMP WITH TIME ZONE

TIMESTAMP WITH LOCAL TIME ZONE

INTERVAL YEAR TO MONTH

INTERVAL DAY TO SECOND

ROWID

UROWID

CLOB

NCLOB

BLOB

BFILE

REF

“Any”类型

XML类型

Spatial类型

Media类型

下列TimesTen数据类型不被Oracle支持:

TT_TINYINT

TT_SMALLINT

TT_INTEGER

TT_BIGINT

TT_VARBINARY

注意:TimesTen NCHAR/NVARCHAR2数据类型将被编译为UTF-16。Oracle NCHAR/NVARCHR2将被编译为UTF-16或UTF-8。

SQL操作符

TimesTen支持这些Oracle操作符和动词:

一元数的 -

+, -, *, /

=, <, >, <=, >=, <>=

| |

IS NULL, IS NOT NULL

LIKE(Oracle LIKE操作符将忽略后面的空格,但TimesTen不会。)

BETWEEN

IN

NOT IN (list)

AND

OR

+(外连接)

ANY、SOME

ALL (list)

EXISTS

UNION

MINUS

INTERSECT

SQL函数

TimesTen支持这些Oracle函数:

ABS

ADD_MONTHS

AVG

CEIL

COALESCE

CONCAT

COUNT

DECODE

EXTRACT

FLOOR

GREATEST

INSTR

LEAST

LENGTH

LPAD

LTRIM

MAX

MIN

MOD

NUMTOYMINTERVAL

NUMTODSINTERVAL

NVL

POWER

ROUND

RPAD

RTRIM

SIGN

SQRT

SUBSTR

SUM

SYSDATE

TO_DATE

TO_CHAR

TO_NUMBER

TRIM

TRUNC

SQL表达式

TimesTen支持这些Oracle表达式:

• 列引用

• Sequence

• NULL

• ()

• 绑定参数

• 计算表达式

• CAST

SQL子查询

TimesTen支持Oracle子查询:

• IN(子查询)

• >,<,= ANY(子查询)

• >,=,< SOME(子查询)

• EXISTS(子查询)

• >,=,< (分级子查询)

• 在DELETE/UPDATE的WHERE子句中

• 在FROM子句中

注意:一个“单行结果集”的非验证分级子查询直到执行时才能被确认。TimesTen允许在整个查询中至多只能有一个非验证分级子查询,并且子查询不指定在OR表达式中。

SQL查询

TimesTen支持这些查询:

• FOR UPDATE

• ORDER BY

• GROUP BY

• 表别名

• 列别名

Oracle支持闪回查询,以查询数据库一些以前状态(例如,查询昨天的一个表)。TimesTen不支持闪回查询。

INSERT/DELETE/UPDATE语句

TimesTen支持这些Oracle DML语句:

• INSERT INTO ... VALUES

• INSERT INTO ... SELECT

• UPDATE WHERE expression(expression可以包含子查询)

• DELETE WHERE expression(expression可以包含子查询)

• MERGE(TimesTen不支持ODBC批量执行MERGE语句)

只用于TimesTen的SQL和内部程序

这部分列出Oracle不支持的TimesTen SQL语句和内部程序。使用PassThrough= 3时,这些语句将被传送到Oracle并产生一个错误。

• 所有TimesTen缓存集合DDL和DML语句,包括CREATE CACHE GROUP、DROP CACHE GROUP、ALTER CACHE GROUP、LOAD CACHE GROUP、UNLOAD CACHE GROUP、FLUSH CACHE GROUP和REFRESH CACHE GROUP语句。

• 所有TimesTen复制管理DDL语句,包括CREATE REPLICATION、DROP REPLICATION、ALTER REPLICATION、CREATE ACTIVE STANDBY PAIR、ALTER ACTIVE STANDBY PAIR和DROP ACTIVE STANDBY PAIR语句。

• 所有TimesTen内部程序。

其它SQL问题

• Oracle ROWID数据类型是假的ROWID。TimesTen的ROWID数据类型是BINARY(16)。它们的长度不同。

• PL/SQL是一种Oracle语言,并不被TimesTen支持。

• Oracle内部优化内含在SQL注释中。TimesTen使用内部程序来设置内部优化。

• Oracle和TimesTen的系统表不同。

• TimesTen不支持Oracle INSERT、UPDATE和DELETE语句中的RETURNING子句。

• Oracle存储函数可能通过输出参数返回游标引用或返回值。TimesTen不支持这种特性。

• 当一条SQL语句有相同的名字的参数时,TimesTen认为它们是相同参数的重复出现,并且不允许对它们进行分别绑定。Oracle则认为它们是不同的参数并允许分别绑定。

术语表

age out

在一个指定的时间周期之后(基于时间)或当数据的使用已经达到指定的水平(基于使用),将从缓存集合中删除缓存实例。

asynchronous writethrough cache group

TimesTen中一个缓存集合中的数据被更新,并异步的传送到Oracle。

autorefresh

Oracle上的更新通过Oracle触发器的手段被自动地传送到TimesTen缓存集合。

AWT cache group

同asynchronous writethrough cache group。

bidirectional propagation

为了将Oracle或TimesTen缓存集合中的更新拷贝到另一方。

cache agent

一个TimesTen进程以保证缓存集合的操作,如AUTOREFRESH和COMMIT EVERY n ROWS。

cache group

将Oracle表中的数据缓存到一个TimesTen数据存储中。缓存集合可以创建来缓存一个单表的所有或部分,或是缓存一个Oracle相关联的表集。如果缓存了多个Oracle表,则缓存集合中的每个表必须与缓存集合中另一个表通过一对多相关联。

cache group primary key

缓存集合中根表的主键。

cache instance

由缓存集合根表中的主键指定的数据中一指定的行。如果缓存集合中有多个表,则缓存实例由通过外键与根表中行关联的相关的行集组成。

cache instance key

根表中指定行的主键,用来确定根表的行和缓存集合子表中引用根表此行的所有子表行。

child table

缓存集合中有一个引用根表主键的外键或引用另一个直接或间接引用根表的子表主键的外键的表。缓存集合中表的层次可以指定子表是另其它子表的父表。缓存集合中不能有多个父表的子表。

flush

为了将缓存集合中的插入或更新从TimesTen拷贝到Oracle。

load

为了从Oracle只拷贝新实例。不会更新或删除缓存中已经存在实例。

propagate

为了在Oracle和TimesTen缓存集合之间拷贝数据。

refresh

为了使用最近的Oracle数据来替换TimesTen缓存集合中所有的缓存实例。

replication

在多个数据存储中保持数据的副本拷贝的过程。

replication agent

通过一个replication agent来控制在每个主和从数据存储的复制。在主数据存储上的复制代理来从事务日志读记录并向前查找所有改变以复制到从数据存储上的复制代理。从数据存储上的复制代理然后将更新应用到它的数据存储中。

root table

缓存集合中的主表不通过外键约束来引用缓存集合中的任何其它表。根表的主键就是缓存集合的主键。

synchronous writethrough cache group

一个缓存集合中缓存数据在TimesTen中被更新,并且同步地传送到Oracle。

system-managed cache group

System-managed cache group强制指定行为。系统管理缓存集合是READONLY、SYNCHRONOUS、WRITETHROUGH和ASYNCHRONOUS WRITETHROUGH。

READONLY缓存集合强制地将Oracle表中的更新通过AUTOREFRESH机制应用到TimesTen。不能在READONLY缓存集合中直接更新表。

ASYNCHRONOUS WRITETHROUGH (SWT)缓存集合强制将TimesTen中缓存数据的更新传送到Oracle。当应用提交事务时,在向TimesTen提交之前向Oracle提交。

ASYNCHRONOUS WRITETHROUGH (AWT)缓存集合的强制缓存行为与SWT缓存集合相同,即TimesTen中缓存数据的更新被传送到Oracle,但TimesTen提交的发生与Oracle提交不同步。

user-managed cache group

一个user-managed cache group实现自定义行为,如双向传送。

unload

为了从缓存集合中删除一此或所有缓存实例。

你可能感兴趣的:(数据库,oracle,cache,asynchronous,存储,table)