TimesTen 应用层数据库缓存学习:5. 异步读写缓存

eleAsynchronous Write Through(AWT) cache group, 即TimesTen的异步写缓存。数据只允许在TimesTen中修改,然后同步到Oracle。当然,TimesTen中的数据最初是从Oracle加载而来。


对于熟悉存储的人来说,cache 分为write-through和write back。而TimesTen的AWT对应的就是存储的write-back。
TimesTen 应用层数据库缓存学习:5. 异步读写缓存_第1张图片
由于有双向的数据流动,因此对于AWT,除了只读缓存组所需的cache agent外,还需要一个replication agent,负责数据从TimesTen到Oracle的同步。
TimesTen 应用层数据库缓存学习:5. 异步读写缓存_第2张图片

使用AWT缓存的好处除了性能外,还可以保证,当后端Oracle失效时,TimesTen仍可以接收和修改数据,保证数据不丢失,待Oracle正常后,数据自动同步到后端。

AWT缓存组可以保证和不能保证的

  • 可以保证的

No transactions are lost because of communication failures between the TimesTen and Oracle databases.

这点很重要,不会因Oracle失效而丢数据,而且可以自动恢复(通过复制代理)

If the replication agent is not running or loses its connection to the Oracle database, automatic propagation of committed updates on the TimesTen cache tables to the cached Oracle Database tables resumes after the agent restarts or reconnects to the Oracle database.

不会因复制代理失效丢数据,而且可以自动恢复

Transactions are committed in the Oracle database in the same order they were committed in the TimesTen database.

保证数据的一致性

  • 不能保证的

    All transactions committed successfully in the TimesTen database are successfully propagated to and committed in the Oracle database


因此TimesTen中的约束应比Oracle强

The absolute order of Oracle Database updates is preserved because TimesTen does not resolve update conflicts.

这些情况发生在多头写的时候,如两个缓存组同时更新一条记录,或TimesTen和Oracle同时修改一条记录。由于AWT是异步的,虽然其可以保证一个TimesTen中的时序,但跨两个数据库就不能保证了。 因此,尽量避免多头写,或者通过cache grid保持数据一致性

准备工作

在建立cache group之前,首先配置cache grid。这里概念容易混淆,因为我们说cache group和cache grid是不同的,而这里的操作又是必需的,我们可以理解这里的配置工作为建立一个cache grid的框架,没有任何TimesTen节点attach到它上面,只是便于以后扩展。
$ ttisql -v1 -connstr "dsn=cachedb1_1122;uid=cacheadm;pwd=timesten;oraclepwd=oracle"
Command> call ttGridCreate ('samplegrid');
Command> call ttGridInfo;
< SAMPLEGRID, CACHEADM, Linux Intel x86, 32-bit, 11, 2, 2 >
Command> call ttGridNameSet ('samplegrid');
Command> call ttGridNameGet;
< SAMPLEGRID >
然后启动cache agent。
$ ttisql -v1 cachedb1_1122
Command> call ttCacheStart;
或者
$ ttAdmin -cacheStart cachedb1_1122
然后可以通过ttStatus查看cache agent的状态:
$ ttstatus cachedb1_1122
TimesTen status report as of Sun Apr 10 06:24:24 2016

Daemon pid 2046 port 53392 instance tt1122
No TimesTen server running
------------------------------------------------------------------------
Data store /home/oracle/app/oracle/product/TimesTen/tt1122/info/DemoDataStore/cachedb1_1122
There are 14 connections to the data store
Shared Memory KEY 0x3a41077e ID 8650765
PL/SQL Memory KEY 0x3b41077e ID 8683534 Address 0x10000000
Type            PID     Context     Connection Name              ConnID
Cache Agent     17221   0x09a41200  Handler                           2
Cache Agent     17221   0x09b70538  Timer                             3
Cache Agent     17221   0xa7a0c560  Aging                             4

Dynamic AWT Cache Group

$ cd $TT_HOME/quickstart/sample_scripts/cachegrid/

$ ls
create_global_awt.sql  create_local_awt.sql  create_local_dyn_ro.sql  create_local_ro.sql
将create_local_awt.sql稍作修改为create_local_d_awt_bak.sql

$ cat create_local_d_awt_bak.sql
create dynamic asynchronous writethrough cache group d_awt from 
tthr.regions    ( region_id    number  not null primary key,
                region_name  varchar2(25)),
tthr.countries  ( country_id   char (2) not null primary key,
                country_name varchar2(40),
                region_id    number,
   foreign key (region_id)
   references tthr.regions (region_id)),
tthr.locations  ( location_id  number (4) not null primary key,
                street_address varchar2 (40),
                postal_code    varchar2 (12),   
                city           varchar2 (30) not null,
                state_province varchar2 (25),
                country_id     char(2),
   foreign key (country_id)
   references tthr.countries (country_id));


$ sqlplus tthr/oracle@ttorcl
SQL> select * from regions;

 REGION_ID REGION_NAME
---------- -------------------------
         1 Europe
         2 Americas
         3 Asia
         4 Middle East and Africa

SQL> select * from countries;

CO COUNTRY_NAME                              REGION_ID
-- ---------------------------------------- ----------
IT Italy                                             1
JP Japan                                             3
US United States of America                          2
CA Canada                                            2
CN China                                             3
IN India                                             3
AU Australia                                         3
ZW Zimbabwe                                          4
SG Singapore                                         3
UK United Kingdom                                    1
FR France                                            1

CO COUNTRY_NAME                              REGION_ID
-- ---------------------------------------- ----------
DE Germany                                           1
ZM Zambia                                            4
EG Egypt                                             4
BR Brazil                                            2
CH Switzerland                                       1
NL Netherlands                                       1
MX Mexico                                            2
KW Kuwait                                            4
IL Israel                                            4
DK Denmark                                           1
HK HongKong                                          3

CO COUNTRY_NAME                              REGION_ID
-- ---------------------------------------- ----------
NG Nigeria                                           4
AR Argentina                                         2
BE Belgium                                           1

25 rows selected.

SQL> 
SQL> set linesize 150
SQL> select * from locations;

LOCATION_ID STREET_ADDRESS                           POSTAL_CODE  CITY                           STATE_PROV CO
----------- ---------------------------------------- ------------ ------------------------------ ---------- --
       1000 1297 Via Cola di Rie                     00989        Roma                                      IT
       1100 93091 Calle della Testa                  10934        Venice                                    IT
       1200 2017 Shinjuku-ku                         1689         Tokyo                          Tokyo Pref JP
                                                                                                 ecture

       1300 9450 Kamiya-cho                          6823         Hiroshima                                 JP
       1400 2014 Jabberwocky Rd                      26192        Southlake                      Texas      US
       1500 2011 Interiors Blvd                      99236        South San Francisco            California US
       1600 2007 Zagora St                           50090        South Brunswick                New Jersey US
       1700 2004 Charade Rd                          98199        Seattle                        Washington US
       1800 147 Spadina Ave                          M5V 2L7      Toronto                        Ontario    CA

LOCATION_ID STREET_ADDRESS                           POSTAL_CODE  CITY                           STATE_PROV CO
----------- ---------------------------------------- ------------ ------------------------------ ---------- --
       1900 6092 Boxwood St                          YSW 9T2      Whitehorse                     Yukon      CA
       2000 40-5-12 Laogianggen                      190518       Beijing                                   CN
       2100 1298 Vileparle (E)                       490231       Bombay                         Maharashtr IN
                                                                                                 a

       2200 12-98 Victoria Street                    2901         Sydney                         New South  AU
                                                                                                 Wales

       2300 198 Clementi North                       540198       Singapore                                 SG
       2400 8204 Arthur St                                        London                                    UK
       2500 Magdalen Centre, The Oxford Science Park OX9 9ZB      Oxford                         Oxford     UK

LOCATION_ID STREET_ADDRESS                           POSTAL_CODE  CITY                           STATE_PROV CO
----------- ---------------------------------------- ------------ ------------------------------ ---------- --
       2600 9702 Chester Road                        09629850293  Stretford                      Manchester UK
       2700 Schwanthalerstr. 7031                    80925        Munich                         Bavaria    DE
       2800 Rua Frei Caneca 1360                     01307-002    Sao Paulo                      Sao Paulo  BR
       2900 20 Rue des Corps-Saints                  1730         Geneva                         Geneve     CH
       3000 Murtenstrasse 921                        3095         Bern                           BE         CH
       3100 Pieter Breughelstraat 837                3029SK       Utrecht                        Utrecht    NL
       3200 Mariano Escobedo 9991                    11932        Mexico City                    Distrito F MX
                                                                                                 ederal,


23 rows selected.

# 对于AWT,由于是可写缓存,必须赋予更改权限。对于有多张表的缓存组,根表和子表全部需具有更改权限,否则报错如下:
# 5185: Cache admin user CACHEADM does not have insert, update or delete Oracle privileges on TTHR.REGIONS.
# 5185: Cache admin user CACHEADM does not have insert, update or delete Oracle privileges on TTHR.COUNTRIES.

SQL> grant select, insert, update, delete on regions to cacheadm;

Grant succeeded.

SQL> grant select, insert, update, delete on countries to cacheadm;

Grant succeeded.

SQL> grant select, insert, update, delete on locations to cacheadm;

Grant succeeded.
SQL> exit

# 建立缓存组
$ ttisql -v1 -connstr "dsn=cachedb1_1122;uid=cacheadm;pwd=timesten;oraclepwd=oracle" -f create_local_d_awt_bak.sql 
$ ttisql -v1 -connstr "dsn=cachedb1_1122;uid=cacheadm;pwd=timesten"
Command> cachegroups;

Cache Group CACHEADM.D_AWT:

  Cache Group Type: Asynchronous Writethrough (Dynamic)
  Autorefresh: No
  Aging: LRU on

  Root Table: TTHR.REGIONS
  Table Type: Propagate


  Child Table: TTHR.COUNTRIES
  Table Type: Propagate


  Child Table: TTHR.LOCATIONS
  Table Type: Propagate

# 启动replication agent
Command> call ttrepstart;
或者用
$ ttAdmin -repStart cachedb1_1122
AWT比read-only缓存组,除了cache agent外,还需要启动replication agent,因为从TimesTen到Oracle,也算一种异构的复制。后面也会提到,TimesTen数据库之间也是支持复制的,也需要启动replication agent。
确认agent已经启动,可以再运行一次命令:  
Command> call ttrepstart;
12026: The agent is already running for the data store.
The command failed.
或者通过ttStatus:
[oracle@localhost ~]$ ttstatus cachedb1_1122
TimesTen status report as of Mon Apr 11 22:44:29 2016

Daemon pid 2034 port 53392 instance tt1122
No TimesTen server running
------------------------------------------------------------------------
Data store /home/oracle/app/oracle/product/TimesTen/tt1122/info/DemoDataStore/cachedb1_1122
There are 19 connections to the data store
Shared Memory KEY 0x3f41077e ID 1966094
PL/SQL Memory KEY 0x4041077e ID 1998863 Address 0x10000000
Type            PID     Context     Connection Name              ConnID
Cache Agent     4297    0x094d5200  Handler                           2
Cache Agent     4297    0x09604538  Timer                             4
Cache Agent     4297    0xa5b1bd60  Aging                             3
Replication     4339    0x0b9cd6d8  REPHOLD:63638416                132
Replication     4339    0x0babad30  REPLISTENER:66788240            130
Replication     4339    0x0bb20ac0  LOGFORCE:130186128              129
Replication     4339    0x0bb80dc0  TRANSMITTER(M):69938064         128
Replication     4339    0x0bce05b8  RECEIVER:85457808               127
......

# 我们可以查看复制的定义
Command> repschemes;

Replication Scheme TTREP._AWTREPSCHEME:

  Element: _1086048                       
  Type: Table TTHR.REGIONS
  Master Store: CACHEDB1_1122 on LOCALHOST.LOCALDOMAIN Transmit Durable
  Subscriber Store: _ORACLE from LOCALHOST.LOCALDOMAIN 

  Element: _1086056                       
  Type: Table TTHR.COUNTRIES
  Master Store: CACHEDB1_1122 on LOCALHOST.LOCALDOMAIN Transmit Durable
  Subscriber Store: _ORACLE from LOCALHOST.LOCALDOMAIN 

  Element: _1086064                       
  Type: Table TTHR.LOCATIONS
  Master Store: CACHEDB1_1122 on LOCALHOST.LOCALDOMAIN Transmit Durable
  Subscriber Store: _ORACLE from LOCALHOST.LOCALDOMAIN 

  Store: CACHEDB1_1122 on LOCALHOST.LOCALDOMAIN
    Port: (auto)
    Log Fail Threshold: (none)
    Retry Timeout: 120 seconds
    Compress Traffic: Disabled

  Store: _ORACLE from LOCALHOST.LOCALDOMAIN
    Port: (auto)
    Log Fail Threshold: (none)
    Retry Timeout: 120 seconds
    Compress Traffic: Disabled

$ cd $TT_HOME/oraclescripts
$ sqlplus cacheadm/oracle@ttorcl

SQL*Plus: Release 11.2.0.2.0 Production on Mon Apr 11 17:00:14 2016

Copyright (c) 1982, 2010, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> @cacheInfo.sql
*************No autorefresh objects are found*************
*************No DDL Tracking objects are found*************

PL/SQL procedure successfully completed.


基本行为

$ ttisql -v1 -connstr "dsn=cachedb1_1122;uid=tthr;pwd=timesten;oraclepwd=oracle" Command> select * from regions; Command> select * from countries; Command> select * from locations; Command> select * from regions where region_id = 1; <-root table dynamic load < 1, Europe > Command> select * from countries; <- 我们可以看到dynamic load 将子表的数据也加载了 < BE, Belgium, 1 > < CH, Switzerland, 1 > < DE, Germany, 1 > < DK, Denmark, 1 > < FR, France, 1 > < IT, Italy, 1 > < NL, Netherlands, 1 > < UK, United Kingdom, 1 > Command> select * from locations; <- 我们可以看到dynamic load 将子表的数据也加载了 < 1000, 1297 Via Cola di Rie, 00989, Roma, <NULL>, IT > < 1100, 93091 Calle della Testa, 10934, Venice, <NULL>, IT > < 2400, 8204 Arthur St, <NULL>, London, <NULL>, UK > < 2500, Magdalen Centre, The Oxford Science Park, OX9 9ZB, Oxford, Oxford, UK > < 2600, 9702 Chester Road, 09629850293, Stretford, Manchester, UK > < 2700, Schwanthalerstr. 7031, 80925, Munich, Bavaria, DE > < 2900, 20 Rue des Corps-Saints, 1730, Geneva, Geneve, CH > < 3000, Murtenstrasse 921, 3095, Bern, BE, CH > < 3100, Pieter Breughelstraat 837, 3029SK, Utrecht, Utrecht, NL > Command> select * from countries where country_id = 'CN'; <-child table dynamic load < CN, China, 3 > Command> select * from regions; <- cache instance相关的子母表也加载了数据 < 1, Europe > < 3, Asia > Command> select * from countries; <- cache instance相关的子母表也加载了数据 < AU, Australia, 3 > < BE, Belgium, 1 > < CH, Switzerland, 1 > < CN, China, 3 > < DE, Germany, 1 > < DK, Denmark, 1 > < FR, France, 1 > < HK, HongKong, 3 > < IN, India, 3 > < IT, Italy, 1 > < JP, Japan, 3 > < NL, Netherlands, 1 > < SG, Singapore, 3 > < UK, United Kingdom, 1 > Command> select * from locations; <- cache instance相关的子母表也加载了数据 < 1000, 1297 Via Cola di Rie, 00989, Roma, <NULL>, IT > < 1100, 93091 Calle della Testa, 10934, Venice, <NULL>, IT > < 1200, 2017 Shinjuku-ku, 1689, Tokyo, Tokyo Prefecture, JP > < 1300, 9450 Kamiya-cho, 6823, Hiroshima, <NULL>, JP > < 2000, 40-5-12 Laogianggen, 190518, Beijing, <NULL>, CN > < 2100, 1298 Vileparle (E), 490231, Bombay, Maharashtra, IN > < 2200, 12-98 Victoria Street, 2901, Sydney, New South Wales, AU > < 2300, 198 Clementi North, 540198, Singapore, <NULL>, SG > < 2400, 8204 Arthur St, <NULL>, London, <NULL>, UK > < 2500, Magdalen Centre, The Oxford Science Park, OX9 9ZB, Oxford, Oxford, UK > < 2600, 9702 Chester Road, 09629850293, Stretford, Manchester, UK > < 2700, Schwanthalerstr. 7031, 80925, Munich, Bavaria, DE > < 2900, 20 Rue des Corps-Saints, 1730, Geneva, Geneve, CH > < 3000, Murtenstrasse 921, 3095, Bern, BE, CH > < 3100, Pieter Breughelstraat 837, 3029SK, Utrecht, Utrecht, NL > Command> # 以下同理 Command> select * from countries where region_id = 3; < JP, Japan, 3 > < CN, China, 3 > < IN, India, 3 > < AU, Australia, 3 > < SG, Singapore, 3 > < HK, HongKong, 3 > Command> select * from regions; < 1, Europe > < 3, Asia > Command> select * from countries; < AU, Australia, 3 > < BE, Belgium, 1 > < CH, Switzerland, 1 > < CN, China, 3 > < DE, Germany, 1 > < DK, Denmark, 1 > < FR, France, 1 > < HK, HongKong, 3 > < IN, India, 3 > < IT, Italy, 1 > < JP, Japan, 3 > < NL, Netherlands, 1 > < SG, Singapore, 3 > < UK, United Kingdom, 1 > Command> select * from locations; < 1000, 1297 Via Cola di Rie, 00989, Roma, <NULL>, IT > < 1100, 93091 Calle della Testa, 10934, Venice, <NULL>, IT > < 1200, 2017 Shinjuku-ku, 1689, Tokyo, Tokyo Prefecture, JP > < 1300, 9450 Kamiya-cho, 6823, Hiroshima, <NULL>, JP > < 2000, 40-5-12 Laogianggen, 190518, Beijing, <NULL>, CN > < 2100, 1298 Vileparle (E), 490231, Bombay, Maharashtra, IN > < 2200, 12-98 Victoria Street, 2901, Sydney, New South Wales, AU > < 2300, 198 Clementi North, 540198, Singapore, <NULL>, SG > < 2400, 8204 Arthur St, <NULL>, London, <NULL>, UK > < 2500, Magdalen Centre, The Oxford Science Park, OX9 9ZB, Oxford, Oxford, UK > < 2600, 9702 Chester Road, 09629850293, Stretford, Manchester, UK > < 2700, Schwanthalerstr. 7031, 80925, Munich, Bavaria, DE > < 2900, 20 Rue des Corps-Saints, 1730, Geneva, Geneve, CH > < 3000, Murtenstrasse 921, 3095, Bern, BE, CH > < 3100, Pieter Breughelstraat 837, 3029SK, Utrecht, Utrecht, NL > # 下面测试更新语句 Command> insert into locations values(2001, 'Wukesong', '100036', 'Beijing', NULL, 'CN'); Command> select * from locations; < 1000, 1297 Via Cola di Rie, 00989, Roma, <NULL>, IT > < 1100, 93091 Calle della Testa, 10934, Venice, <NULL>, IT > < 1200, 2017 Shinjuku-ku, 1689, Tokyo, Tokyo Prefecture, JP > < 1300, 9450 Kamiya-cho, 6823, Hiroshima, <NULL>, JP > < 2000, 40-5-12 Laogianggen, 190518, Beijing, <NULL>, CN > < 2001, Wukesong, 100036, Beijing, <NULL>, CN > < 2100, 1298 Vileparle (E), 490231, Bombay, Maharashtra, IN > < 2200, 12-98 Victoria Street, 2901, Sydney, New South Wales, AU > < 2300, 198 Clementi North, 540198, Singapore, <NULL>, SG > < 2400, 8204 Arthur St, <NULL>, London, <NULL>, UK > < 2500, Magdalen Centre, The Oxford Science Park, OX9 9ZB, Oxford, Oxford, UK > < 2600, 9702 Chester Road, 09629850293, Stretford, Manchester, UK > < 2700, Schwanthalerstr. 7031, 80925, Munich, Bavaria, DE > < 2900, 20 Rue des Corps-Saints, 1730, Geneva, Geneve, CH > < 3000, Murtenstrasse 921, 3095, Bern, BE, CH > < 3100, Pieter Breughelstraat 837, 3029SK, Utrecht, Utrecht, NL > $ sqlplus tthr/oracle@ttorcl # 可以看到AWT的数据已经同步到Oracle SQL> select * from locations where country_id = 'CN'; LOCATION_ID STREET_ADDRESS POSTAL_CODE CITY STATE_PROV CO ----------- ---------------------------------------- ------------ ------------------------------ ---------- -- 2000 40-5-12 Laogianggen 190518 Beijing CN 2001 Wukesong 100036 Beijing CN # 按理说,Oracle这边是不应该写数据的,不过我们还是测一下 SQL> insert into regions values(5, 'Moon'); 1 row created. SQL> select * from regions; REGION_ID REGION_NAME ---------- ------------------------- 5 Moon 1 Europe 2 Americas 3 Asia 4 Middle East and Africa SQL> commit; # 数据通过dynamic load进入到TimesTen Command> select * from regions where region_id = 5; < 5, Moon > Command> select * from regions; < 1, Europe > < 3, Asia > < 5, Moon > # 接着分别在母表和子表中插入数据 Command> insert into regions values(6, 'Saturn'); Command> insert into countries values('WJ', 'Wujiguo', 5); SQL> select * from regions; REGION_ID REGION_NAME ---------- ------------------------- ...... 6 Saturn 6 rows selected. SQL> select * from countries; CO COUNTRY_NAME REGION_ID -- ---------------------------------------- ---------- WJ Wujiguo 5 ...... 26 rows selected. # 再试下update,此update并没有关联主键,因为数据已经在TimesTen中了,因此无需通过主键dynamic load Command> update locations set postal_code = '100038' where street_address = 'Wukesong'; # 数据迅速同步到了Oracle, SQL> select * from locations; LOCATION_ID STREET_ADDRESS POSTAL_CODE CITY STATE_PROVINCE CO ----------- ---------------------------------------- ------------ ------------------------------ ------------------------- -- 2001 Wukesong 100038 Beijing CN 24 rows selected. Command> update regions set region_name = 'AMERICAS' where region_name = 'Americas'; 0 rows updated. <- 因为不满足dynamic load的条件 Command> update regions set region_name = 'AMERICAS' where region_id = 2; 1 row updated.<- 满足dynamic load,成功 Command> update regions set region_name = 'Americas' where region_name = 'AMERICAS'; 1 row updated. <- 数据已经在TimesTen,无需dynamic load,成功 Command> update regions set region_id = 7 where region_name = 'AMERICAS'; 1000: Cannot set primary key columns to different values <- 不允许修改主键,失败 The command failed. 

load 和 refresh

在一下的测试中,我们启动两个会话,一个用于cacheadm执行load/unload/refresh操作 ` ttisqlconnstrdsn=cachedb11122;uid=cacheadm;pwd=timesten;oraclepwd=oracleesetpromptcacheadm> ttisql -v2 -connstr “dsn=cachedb1_1122;uid=tthr;pwd=timesten;oraclepwd=oracle” -e “set prompt tthr>”`
tthr>select * from regions;
< 1, Europe >
< 2, Americas >
< 3, Asia >
< 5, Moon >
< 6, Saturn >
5 rows found.
tthr>select count(*) from regions;
< 5 >
tthr>select count(*) from countries;
< 20 >
tthr>select count(*) from locations;
< 24 >
cacheadm>unload cache group cacheadm.d_awt where region_id = 1;
1 cache instance affected.
tthr>select count(*) from regions;
< 4 >
tthr>select count(*) from countries;
< 12 >
tthr>select count(*) from locations;
< 15 >
# 试着从子表unload,没有成功,说明只能从根表unload
cacheadm>unload cache group cacheadm.d_awt where countries.region_id = 2;
 1024: Referenced table COUNTRIES not in FROM list
The command failed.
cacheadm>unload cache group cacheadm.d_awt where country_id = 'CN';
 2211: Referenced column COUNTRY_ID not found
The command failed.
cacheadm>unload cache group cacheadm.d_awt;
4 cache instances affected.
Command cancelled ...
tthr>select count(*) from locations;
< 0 >
tthr>select count(*) from countries;
< 0 >
tthr>select count(*) from regions;
< 0 >

cacheadm>load cache group cacheadm.d_awt where (regions.region_id = 1) commit every 256 rows;
1 cache instance affected.
tthr>select count(*) from regions union select count(*) from countries union select count(*) from locations;
< 1 >
< 8 >
< 9 >
3 rows found.
cacheadm>load cache group cacheadm.d_awt where (countries.country_id = 'CN') commit every 256 rows;
 5056: The cache operation fails: error_type=<Oracle Error>, error_code=<904>, error_message: ORA-00904: "COUNTRIES"."COUNTRY_ID": invalid identifier
The command failed.
cacheadm>load cache group cacheadm.d_awt where (locations.location_id = 3200) commit every 256 rows;
 5056: The cache operation fails: error_type=<Oracle Error>, error_code=<904>, error_message: ORA-00904: "LOCATIONS"."LOCATION_ID": invalid identifier
The command failed.
# 同样, load也只能从root table进行操作。那么如果要扩展,可能的架构是每一个region作为一个shard,初始按照region来load初始化数据


tthr>select * from countries;
< BE, Belgium, 1 >
< CH, Switzerland, 1 >
< DE, Germany, 1 >
< DK, Denmark, 1 >
< FR, France, 1 >
< IT, Italy, 1 >
< NL, Netherlands, 1 >
< UK, United Kingdom, 1 >
8 rows found.
SQL> select * from countries where region_id = 1;

CO COUNTRY_NAME                              REGION_ID
-- ---------------------------------------- ----------
IT Italy                                             1
UK United Kingdom                                    1
FR France                                            1
DE Germany                                           1
CH Switzerland                                       1
NL Netherlands                                       1
DK Denmark                                           1
BE Belgium                                           1

8 rows selected.

SQL> update countries set country_name = 'ITALY' where country_id = 'IT';

1 row updated.

SQL> commit;

Commit complete.
tthr>select * from countries where country_id = 'IT';
< IT, Italy, 1 > <- 由于AWT缓存没有autorefresh,因此数据不可能自动变化
cacheadm>refresh cache group cacheadm.d_awt where region_id = 2 commit every 256 rows; <- dynamic缓存组不允许在refresh时带where条件
 3022: Refresh cache group with a where clause is only allowed only if the cache group is not dynamic
cacheadm>refresh cache group cacheadm.d_awt commit every 256 rows;
1 cache instance affected.
tthr>select * from countries where country_id = 'IT';
< IT, ITALY, 1 > <- refresh起到了update的作用
SQL> insert into countries values('RU', 'Russian', 1);

1 row created.

SQL> commit;

Commit complete.
tthr>select * from countries where country_id = 'RU';
0 rows found. <- 虽然是从国家这个角度插入数据,但由于欧洲的cache instance已经加载,因此refresh仍会更新这条数据
cacheadm>refresh cache group cacheadm.d_awt commit every 256 rows;
1 cache instance affected.
tthr>select * from countries where country_id = 'RU';
< RU, Russian, 1 >
1 row found.

tthr>delete from regions where region_id > 4;
0 rows deleted. <- 不符合dynamic load,没找到数据
tthr>delete from regions where region_id = 5;
 3001: Foreign key violation [TTFOREIGN_4]: the row at Rowid <BMUFVUAAAB1AAAAHBf> in child table COUNTRIES has a parent in the delete or update range.
The command failed. <- 虽然失败,但是还是触发了dynamic load
tthr>delete from regions where region_id = 6;
1 row deleted. <- 满足dynamic load
# 找到相应的数据
SQL> select * from countries where region_id = 5;

CO COUNTRY_NAME                              REGION_ID
-- ---------------------------------------- ----------
WJ Wujiguo                                           5

SQL> select * from locations where country_id = 'WJ';

no rows selected
tthr>delete from countries where country_id = 'WJ';
1 row deleted.
tthr>delete from regions where region_id = 5;
1 row deleted.
tthr>select * from regions;
< 1, Europe >
1 row found.

# 再看一下load的行为特征,我们在Oracle中插入一条新数据
SQL> select * from regions;

 REGION_ID REGION_NAME
---------- -------------------------
         1 Europe
         2 Americas
         3 Asia
         4 Middle East and Africa

SQL> insert into regions values(5, 'Moon'); 
SQL> insert into countries values('WJ', 'Wujiguo', 5);
SQL> insert into locations values(2002, 'Wuyixiang', '100036', 'Wujidu', NULL, 'WJ');
SQL> commit;
cacheadm>refresh cache group cacheadm.d_awt commit every 256 rows;
1 cache instance affected.
tthr>select * from regions;
< 1, Europe > <- refresh只更新已经在timesten中的cache instance,因此这里没有变化
cacheadm>load cache group cacheadm.d_awt where (regions.region_id = 5) commit every 256 rows;
1 cache instance affected.
tthr>select * from regions;
< 1, Europe >
< 5, Moon >
2 rows found.
tthr>select * from countries where country_id = 'WJ';
< WJ, Wujiguo, 5 >
1 row found.
tthr>select * from locations where country_id = 'WJ';
< 2002, Wuyixiang, 100036, Wujidu, <NULL>, WJ >
1 row found.
# 下面的命令就更明显说明load是将Oracle中存在而TimesTen中没有的数据加载进来
cacheadm>load cache group cacheadm.d_awt where (regions.region_id != 1) commit every 256 rows;
3 cache instances affected.
tthr>select * from regions;
< 1, Europe >
< 2, Americas > <- 新load
< 3, Asia > <- 新load
< 4, Middle East and Africa > <- 新load
< 5, Moon >
5 rows found.


Explicitly Loaded AWT Cache Group

注意在此实验前,请将Oracle中三张表的数据复位,如上一个实验时最初的数据,正常的数据如下:
SQL> select count(*) from regions union select count(*) from countries union select count(*) from locations;

  COUNT(*)
----------
         4
        23
        25

$ cd $TT_HOME/quickstart/sample_scripts/cachegrid/
# 基于create_local_awt.sql,将其修改为create_local_awt_bak.sql
$ cat create_local_awt_bak.sql
create asynchronous writethrough cache group awt from 
tthr.regions    ( region_id    number  not null primary key,
                region_name  varchar2(25)),
tthr.countries  ( country_id   char (2) not null primary key,
                country_name varchar2(40),
                region_id    number,
   foreign key (region_id)
   references tthr.regions (region_id)),
tthr.locations  ( location_id  number (4) not null primary key,
                street_address varchar2 (40),
                postal_code    varchar2 (12),   
                city           varchar2 (30) not null,
                state_province varchar2 (25),
                country_id     char(2),
   foreign key (country_id)
   references tthr.countries (country_id));

# 启动cache agent,命令见前
# 在Oracle中,将regions, countries, locations三表的权限赋予cacheadm,命令见前
# 建立Explicitly Loaded AWT Cache Group
$ ttisql -v1 -connstr "dsn=cachedb1_1122;uid=cacheadm;pwd=timesten;oraclepwd=oracle" -f create_local_awt_bak.sql
# 启动rep agent, 命令见前
# 注意,只有定义了复制关系后,rep agent才能启动,否则报错:
cacheadm>repschemes;
0 replication schemes found.
cacheadm>call ttrepstart;
 8191: This store (CACHEDB1_1122 on LOCALHOST.LOCALDOMAIN) is not involved in a replication scheme
The command failed.

cacheadm>cachegroups

Cache Group CACHEADM.AWT:

  Cache Group Type: Asynchronous Writethrough
  Autorefresh: No
  Aging: No aging defined

  Root Table: TTHR.REGIONS
  Table Type: Propagate


  Child Table: TTHR.COUNTRIES
  Table Type: Propagate


  Child Table: TTHR.LOCATIONS
  Table Type: Propagate

1 cache group found.
cacheadm>repschemes;

Replication Scheme TTREP._AWTREPSCHEME:

  Element: _1086048                       
  Type: Table TTHR.REGIONS
  Master Store: CACHEDB1_1122 on LOCALHOST.LOCALDOMAIN Transmit Durable
  Subscriber Store: _ORACLE from LOCALHOST.LOCALDOMAIN 

  Element: _1086056                       
  Type: Table TTHR.COUNTRIES
  Master Store: CACHEDB1_1122 on LOCALHOST.LOCALDOMAIN Transmit Durable
  Subscriber Store: _ORACLE from LOCALHOST.LOCALDOMAIN 

  Element: _1086064                       
  Type: Table TTHR.LOCATIONS
  Master Store: CACHEDB1_1122 on LOCALHOST.LOCALDOMAIN Transmit Durable
  Subscriber Store: _ORACLE from LOCALHOST.LOCALDOMAIN 

  Store: CACHEDB1_1122 on LOCALHOST.LOCALDOMAIN
    Port: (auto)
    Log Fail Threshold: (none)
    Retry Timeout: 120 seconds
    Compress Traffic: Disabled

  Store: _ORACLE from LOCALHOST.LOCALDOMAIN
    Port: (auto)
    Log Fail Threshold: (none)
    Retry Timeout: 120 seconds
    Compress Traffic: Disabled

1 replication scheme found.
cacheadm>
tthr>select count(*) from regions union select count(*) from countries union select count(*) from locations;
< 0 >
1 row found.
tthr>insert into regions values(5, 'Moon');
1 row inserted.
tthr>select count(*) from regions union select count(*) from countries union select count(*) from locations;
< 0 >
< 1 >
2 rows found.
SQL> select * from regions where region_id = 5;

 REGION_ID REGION_NAME
---------- -------------------------
         5 Moon

tthr>select * from regions where region_id = 1;
0 rows found. <- 因不是dynamic load,此语句无用,数据加载还是要手工load

cacheadm>load cache group cacheadm.awt where region_id = 1 commit every 256 rows;
 5002: Unable to connect to the cache agent for /home/oracle/app/oracle/product/TimesTen/tt1122/info/DemoDataStore/cachedb1_1122; check agent status
The command failed. <- 恰好说明load操作是通过cache agent实现的
cacheadm>call ttcachestart; <- 前面忘启动了
cacheadm>load cache group cacheadm.awt where region_id = 1 commit every 256 rows;
 5056: The cache operation fails: error_type=<Oracle Error>, error_code=<918>, error_message: ORA-00918: column ambiguously defined
The command failed. 
cacheadm>load cache group cacheadm.awt where regions.region_id = 1 commit every 256 rows;
1 cache instance affected.
tthr>select count(*) from regions union select count(*) from countries union select count(*) from locations;
< 2 >
< 8 >
< 9 >
3 rows found.

tthr>select * from regions;
< 1, Europe >
< 5, Moon >
2 rows found.
SQL> update regions set region_name = 'MOON' where region_id = 5;
SQL> commit;
tthr>select * from regions where region_id = 5;
< 5, Moon >
cacheadm>load cache group cacheadm.awt where regions.region_id = 5 commit every 256 rows;
0 cache instances affected. <- load只处理cache table中没有的cache instance
tthr>select * from regions where region_id = 5;
< 5, Moon > <-关键的区别其实是这句,如果是dynamic load,数据会发生变化,而Explicitly load只有用下面的refresh来更新数据了
cacheadm>refresh cache group cacheadm.awt where regions.region_id = 5 commit every 256 rows;
1 cache instance affected.
tthr>select * from regions where region_id = 5;
< 5, MOON >
cacheadm>load cache group cacheadm.awt commit every 256 rows;
3 cache instances affected.
# 加载所有数据
tthr>select count(*) from regions union select count(*) from countries union select count(*) from locations;
< 5 >
< 23 >
< 25 >
3 rows found.
cacheadm>unload cache group cacheadm.awt where regions.region_id = 1;
1 cache instance affected.
tthr>select count(*) from regions union select count(*) from countries union select count(*) from locations;
< 4 >
< 14 >
< 17 >
3 rows found.

# 下面的例子充分说明了,对于Explicitly load的缓存组, refresh等于unload + load
cacheadm>unload cache group cacheadm.awt;
4 cache instances affected.
tthr>select count(*) from regions union select count(*) from countries union select count(*) from locations;
< 0 >
1 row found.
cacheadm>refresh cache group cacheadm.awt commit every 256 rows;
5 cache instances affected.
tthr>select count(*) from regions union select count(*) from countries union select count(*) from locations;
< 5 >
< 23 >
< 25 >
3 rows found.

模拟Oracle数据库故障

AWT的一个好处是可以屏蔽后端数据库的故障,我们可以停掉Oracle,但为了简便,我们停掉cache agent即可。
tthr>select count(*) from regions union select count(*) from countries union select count(*) from locations;
< 5 >
< 23 >
< 25 >
3 rows found.
cacheadm>repschemes;

Replication Scheme TTREP._AWTREPSCHEME:

  Element: _1086048                       
  Type: Table TTHR.REGIONS
  Master Store: CACHEDB1_1122 on LOCALHOST.LOCALDOMAIN Transmit Durable
  Subscriber Store: _ORACLE from LOCALHOST.LOCALDOMAIN 

  Element: _1086056                       
  Type: Table TTHR.COUNTRIES
  Master Store: CACHEDB1_1122 on LOCALHOST.LOCALDOMAIN Transmit Durable
  Subscriber Store: _ORACLE from LOCALHOST.LOCALDOMAIN 

  Element: _1086064                       
  Type: Table TTHR.LOCATIONS
  Master Store: CACHEDB1_1122 on LOCALHOST.LOCALDOMAIN Transmit Durable
  Subscriber Store: _ORACLE from LOCALHOST.LOCALDOMAIN 

  Store: CACHEDB1_1122 on LOCALHOST.LOCALDOMAIN
    Port: (auto)
    Log Fail Threshold: (none)
    Retry Timeout: 120 seconds
    Compress Traffic: Disabled

  Store: _ORACLE from LOCALHOST.LOCALDOMAIN
    Port: (auto)
    Log Fail Threshold: (none)
    Retry Timeout: 120 seconds
    Compress Traffic: Disabled

1 replication scheme found.
cacheadm>
cacheadm>CALL ttRepSubscriberWait('_AWTREPSCHEME','TTREP','_ORACLE','LOCALHOST.LOCALDOMAIN',-1);
< 00 >
1 row found.
# 先确定两个数据库中都有一致的关于日本的数据
tthr>select * from locations where country_id = 'JP';
< 1300, 9450 Kamiya-cho, 6823, Hiroshima, <NULL>, JP >
< 1200, 2017 Shinjuku-ku, 1689, Tokyo, Tokyo Prefecture, JP >
2 rows found.
SQL> select * from locations where country_id = 'JP';

LOCATION_ID STREET_ADDRESS                           POSTAL_CODE  CITY                           STATE_PROVINCE            CO
----------- ---------------------------------------- ------------ ------------------------------ ------------------------- --
       1200 2017 Shinjuku-ku                         1689         Tokyo                          Tokyo Prefecture          JP
       1300 9450 Kamiya-cho                          6823         Hiroshima                                                JP

#从TimesTen中删除数据,马上可以同步到Oracle

tthr>delete from locations where location_id = 1300;
1 row deleted.
SQL> /

LOCATION_ID STREET_ADDRESS                           POSTAL_CODE  CITY                           STATE_PROVINCE            CO
----------- ---------------------------------------- ------------ ------------------------------ ------------------------- --
       1200 2017 Shinjuku-ku                         1689         Tokyo                          Tokyo Prefecture          JP

cacheadm>call ttrepstop; <- 模拟后端Oracle通信故障
cacheadm>call ttrepstop;
12027: The agent is already stopped for the data store.
The command failed.
# 从TimesTen中删除另一条数据,成功,但Oracle中数据仍在
tthr>delete from locations where location_id = 1200;
1 row deleted.
tthr>select * from locations where country_id = 'JP';
0 rows found.
SQL> /

LOCATION_ID STREET_ADDRESS                           POSTAL_CODE  CITY                           STATE_PROVINCE            CO
----------- ---------------------------------------- ------------ ------------------------------ ------------------------- --
       1200 2017 Shinjuku-ku                         1689         Tokyo                          Tokyo Prefecture          JP

cacheadm>CALL ttRepSubscriberWait('_AWTREPSCHEME','TTREP','_ORACLE','LOCALHOST.LOCALDOMAIN',10);
< 01 >
1 row found.
cacheadm>call ttrepstart;
cacheadm>call ttrepstart;
12026: The agent is already running for the data store.
The command failed.
# 这时数据已经同步了
SQL> /

no rows selected

TimesTen的约束应比Oracle严格

TimesTen Cache User Guide中有这么一段话:

All transactions committed successfully in the TimesTen database are successfully propagated to and committed in the Oracle database. Execution errors on the
Oracle database cause the transaction in the Oracle database to be rolled back. For example, an update on the Oracle database may fail because of a unique constraint
violation. Transactions that contain execution errors are not retried.

为何这么说,因为在TimesTen中执行成功,在Oracle中执行未必成功。除非TimesTen具有比Oracle更严格的约束。 在我们的例子中,Oracle的HR schema约束性较TimesTen强,例如Oracle中的表locations有 DEPT_LOC_FK约束,关联departments表,而在TimesTen中根本没这个表。因此会带来问题,见下例。
# 先确定TimesTen和Oracle的数据是一致的
SQL> select * from locations where country_id = 'UK';

LOCATION_ID STREET_ADDRESS                           POSTAL_CODE  CITY                           STATE_PROVINCE            CO
----------- ---------------------------------------- ------------ ------------------------------ ------------------------- --
       2400 8204 Arthur St                                        London                                                   UK
       2500 Magdalen Centre, The Oxford Science Park OX9 9ZB      Oxford                         Oxford                    UK
       2600 9702 Chester Road                        09629850293  Stretford                      Manchester                UK
tthr>select * from locations where country_id = 'UK';
< 2600, 9702 Chester Road, 09629850293, Stretford, Manchester, UK >
< 2500, Magdalen Centre, The Oxford Science Park, OX9 9ZB, Oxford, Oxford, UK >
< 2400, 8204 Arthur St, <NULL>, London, <NULL>, UK >
3 rows found.
# 在timesten中删除数据,但是并没有同步到Oracle
tthr>delete from locations where country_id = 'UK';
3 rows deleted.
SQL> select * from locations where country_id = 'UK';

LOCATION_ID STREET_ADDRESS                           POSTAL_CODE  CITY                           STATE_PROVINCE            CO
----------- ---------------------------------------- ------------ ------------------------------ ------------------------- --
       2400 8204 Arthur St                                        London                                                   UK
       2500 Magdalen Centre, The Oxford Science Park OX9 9ZB      Oxford                         Oxford                    UK
       2600 9702 Chester Road                        09629850293  Stretford                      Manchester                UK

# 查看awt错误数据日志,这个日志位于DataStore同一目录下
[oracle@localhost DemoDataStore]$ cat cachedb1_1122.awterrs


Error occurred 01:06:17 on 04-13-2016
Datastore: /home/oracle/app/oracle/product/TimesTen/tt1122/info/DemoDataStore/cachedb1_1122
Oracle Id: TTORCL
Transmitting name: CACHEDB1_1122
Error message: 
  TT5224: Oracle foreign key violation error in DELETE FROM "TTHR"."LOCATIONS" WHERE "LOCATION_ID" = 2500
: ORA-02292: integrity constraint (TTHR.DEPT_LOC_FK) violated - child record found -- file "bdbTblH.c", lineno 1894, procedure "bdbAWTPlSqlWithMetaExecDirect()"
  TT5130: Error executing the following statement on Oracle: AWT PL/SQL BLOCK WITH META DATA -- file "bdbTblH.c", lineno 1925, procedure "bdbAWTPlSqlWithMetaExecDirect()"
  TT5059: Cannot apply Awt changes to Oracle.  The Oracle transaction will be rolled back. -- file "bdbTblH.c", lineno 4604, procedure "ttBDbStmtForce()"

Operation that caused the error:
DELETE FROM "TTHR"."LOCATIONS" WHERE "LOCATION_ID" = 2500

Failed transaction:
Delete From TTHR.LOCATIONS
Where LOCATION_ID = 2600;

Delete From TTHR.LOCATIONS
Where LOCATION_ID = 2500;

Delete From TTHR.LOCATIONS
Where LOCATION_ID = 2400;

End of failed transaction

# 在tterrors.log中也发现了类似的错误
01:06:17.91 Err : REP:  4263: [37993360, 0, Awt] CACHEDB1_1122:receiver.c(7794): TT16187: Transaction 1460533031/778; Error: transient 0, permanent 1 state 2 error message : 
01:06:17.93 Err : REP:  4263: [37993360, 0, Awt] CACHEDB1_1122:receiver.c(8971): TT16039: Failed to commit transaction for caller: rxCommitTx()
01:06:17.93 Err : REP:  4263: CACHEDB1_1122:receiver.c(8971): TT5224: TT5224: Oracle foreign key violation error in DELETE FROM "TTHR"."LOCATIONS" WHERE "LOCATION_ID" = 2500 : ORA-02292: integrity constraint (TTHR.DEPT_LOC_FK) violated - child record found -- file "bdbTblH.c", lineno 1894, procedure "bdbAWTPlSqlWithMetaExecDirect()"
01:06:17.93 Err : REP:  4263: CACHEDB1_1122:receiver.c(8971): TT5130: TT5130: Error executing the following statement on Oracle: AWT PL/SQL BLOCK WITH META DATA -- file "bdbTblH.c", lineno 1925, procedure "bdbAWTPlSqlWithMetaExecDirect()"
01:06:17.93 Err : REP:  4263: CACHEDB1_1122:receiver.c(8971): TT5059: TT5059: Cannot apply Awt changes to Oracle.  The Oracle transaction will be rolled back. -- file "bdbTblH.c", lineno 4604, procedure "ttBDbStmtForce()"
01:06:17.93 Err : REP:  4263: [37993360, 0, Awt] CACHEDB1_1122:receiver.c(7794): TT16187: Transaction 1460533031/778; Error: transient 0, permanent 1 state 2 error message : 

# 直接在Oracle中删数据,发现无法删除,这就是原因了
SQL> delete from locations where country_id = 'UK';
delete from locations where country_id = 'UK'
*
ERROR at line 1:
ORA-02292: integrity constraint (TTHR.DEPT_LOC_FK) violated - child record found

# 当然,我们之前可以用ttCacheCheck来预防这个错误,不过此命令需要启动并行复制

控制与Oracle通信的速度

为提高AWT缓存组的吞吐量,可以设置从TimesTen到Oracle的并行同步。并行同步可以保证数据的一致性和数据依赖性。 最简单的设置方法是设置CacheAWTParallelism > 1,但是这个属性是Data Store属性,因此在建库前就必须规划好。
$ ttisql -v1 -connstr "dsn=cachedb1_1122;uid=cacheadm;pwd=timesten;oraclepwd=oracle" -f create_local_awt_bak.sql 
 5188: An oracle index is required on foreign key TTHR.COUNTRIES(REGION_ID).
$ ttisql -v1 -connstr "dsn=cachedb1_1122;uid=cacheadm;pwd=timesten;oraclepwd=oracle"
Command> cachegroups;
# 没有建立上
$ ttisql -v1 -connstr "dsn=cachedb1_1122;uid=cacheadm;pwd=timesten;oraclepwd=oracle" -f create_local_awt_bak.sql 
 5188: An oracle index is required on foreign key TTHR.LOCATIONS(COUNTRY_ID).
SQL> CREATE INDEX "TTHR"."INDEX1" ON "TTHR"."COUNTRIES" ("REGION_ID") 
SQL> CREATE INDEX "TTHR"."INDEX2" ON "TTHR"."LOCATIONS" ("COUNTRY_ID") 
$ ttisql -v1 -connstr "dsn=cachedb1_1122;uid=cacheadm;pwd=timesten;oraclepwd=oracle" -f create_local_awt_bak.sql
# 成功了

# 然后用ttcachecheck检查,注意检查时,rep agent必须停掉 
Command> call ttrepstop;
Command> call ttcachecheck(null, 'cacheadm', 'awt');
# 也没有检查出来什么错误,之前发生的错误仍旧存在,而且建立了两个不必要的索引,看来不好用
# 不过起码有一点,就是启动并行后,在建cache group时会严格比对Oracle和TimesTen的配置,后续Oracle的表发生变更时,也建议用ttcachecheck检查

# 在TimesTen中,还可以通过批量设置控制同步到Oracle的速度
> When using AWT cache groups, TimesTen batches together one or more transactions that are to be applied in parallel to the back-end Oracle database. The CacheParAwtBatchSize parameter configures a threshold value for the number of rows included in a single batch. Once the maximum number of rows is reached, TimesTen includes the rest of the rows in the transaction (TimesTen does not break up any transactions), but does not add any more transactions to the batch.

CacheParAwtBatchSize缺省为125行
Command> call ttDBConfig('CacheParAwtBatchSize');
< CACHEPARAWTBATCHSIZE, 125 >

监控

[oracle@timesten-hol info]$ ttrepadmin -showstatus cachedb1_1122

Replication Agent Status as of: 2016-04-13 03:17:57

DSN                         : cachedb1_1122
Process ID                  : 29705 (Started)
Replication Agent Policy    : manual
Host                        : TIMESTEN-HOL
RepListener Port            : 60365 (AUTO)
Last write LSN              : 0.19063048
Last LSN forced to disk     : 0.19062784
Replication hold LSN        : 0.19058952

Replication Peers:
   Name                     : _ORACLE
   Host                     : TIMESTEN-HOL
   Port                     : 60365 (AUTO) (Connected)
   Replication State        : STARTED
   Communication Protocol   : 36

   Name                     : CACHEDB1_1122
   Host                     : TIMESTEN-HOL
   Port                     : 0 (AUTO)
   Replication State        : STARTED
   Communication Protocol   : 36

TRANSMITTER thread(s):
 For                     : _ORACLE (track 0)
   Start/Restart count   : 1
   Send LSN              : 0.19058952
   Transactions sent     : 1
   Total packets sent    : 152
   Tick packets sent     : 146
   MIN sent packet size  : 64
   MAX sent packet size  : 1519
   AVG sent packet size  : 74
   Last packet sent at   : 03:17:56
   Total Packets received: 151
   MIN rcvd packet size  : 64
   MAX rcvd packet size  : 120
   AVG rcvd packet size  : 118
   Last packet rcvd'd at : 03:17:56
   TXNs Allocated        : 2
   TXNs In Use           : 0
   ACTs Allocated        : 3
   ACTs In Use           : 0
   ACTs Data Allocated   : 0
   Most recent errors (max 5):
     TT16025 in repagent.c (line 1227) at 03:06:46 on 04-13-2016
     TT16285 in transmitter.c (line 1020) at 03:06:46 on 04-13-2016
     TT16999 in transmitter.c (line 1331) at 03:06:46 on 04-13-2016

RECEIVER thread(s):
 For                     : CACHEDB1_1122 (track 0)
   Start/Restart count   : 1
   Transactions received : 1
   Total packets sent    : 151
   Tick packets sent     : 0
   MIN sent packet size  : 64
   MAX sent packet size  : 120
   AVG sent packet size  : 118
   Last packet sent at   : 03:17:56
   Total Packets received: 159
   MIN rcvd packet size  : 64
   MAX rcvd packet size  : 618
   AVG rcvd packet size  : 71
   Last packet rcvd'd at : 03:17:56
   rxWaitCTN             : 0.0
   prevCTN               : 0.0
   STA Blk Data Allocated: 32
   STA Data Allocated    : 4096
   Most recent errors (max 5):
     TT16025 in repagent.c (line 1227) at 03:06:46 on 04-13-2016

[oracle@timesten-hol info]$ 

AWT缓存组,cache 部分行和列

cache 部分列其实没多大必要,但是可以做,在创建缓存组时定义,比如一些允许为空值的列, 如下例:
CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP "AWT" FROM "TTHR"."REGIONS" ( "REGION_ID" NUMBER NOT NULL, "REGION_NAME" VARCHAR2(25 BYTE), PRIMARY KEY("REGION_ID") ), "TTHR"."COUNTRIES" ( "COUNTRY_ID" CHAR(2 BYTE) NOT NULL, "REGION_ID" NUMBER NOT NULL, PRIMARY KEY("COUNTRY_ID"), FOREIGN KEY("REGION_ID") REFERENCES "TTHR"."REGIONS"("REGION_ID") ), "TTHR"."LOCATIONS" ( "LOCATION_ID" NUMBER(4) NOT NULL, "CITY" VARCHAR2(30 BYTE) NOT NULL, "STATE_PROVINCE" VARCHAR2(25 BYTE), "COUNTRY_ID" CHAR(2 BYTE) NOT NULL, PRIMARY KEY("LOCATION_ID"), FOREIGN KEY("COUNTRY_ID") REFERENCES "TTHR"."COUNTRIES"("COUNTRY_ID") )
cache部分行不能在创建缓存组时定义,但可以在load时指定where条件,例如:
load cache group "CACHEADM"."AWT" where regions.region_id = 1 commit every 256 rows

部分数据不同步到Oracle

可以选择将一些数据只保留在TimesTen而不同步到Oracle,使用 ttCachePropagateFlagSet 开关即可
Command> set autocommit off
Command> call ttCachePropagateFlagSet(0);
15100: User TTHR lacks privilege CACHE_MANAGER
The command failed. <- 只好临时赋予tthr cache_manager权限
# 思考,是否需要将schema user和cache manager 角色合一呢?
Command> call ttCachePropagateFlagSet(0); <- 这个开关是session级别的
Command> insert into regions values(5, 'Moon');
1 row inserted.
Command> commit;
Command> select * from regions;
< 1, Europe >
< 5, Moon >
2 rows found.
Command> call ttCachePropagateFlagSet(1);
SQL> select * from regions where region_id = 5;

no rows selected

AWT缓存的限制

The cache table definitions cannot contain a WHERE clause.

A TRUNCATE TABLE statement cannot be issued on the cache tables.

AWT cache groups cannot cache Oracle Database views or materialized views.

The replication agent must be stopped before creating or dropping an AWT cache group.

Committed updates on the TimesTen cache tables are not propagated to the cached Oracle Database tables unless the replication agent is running.

You should avoid executing DML statements on Oracle Database tables cached in an AWT cache group. This could result in an error condition. Any insert, update, or delete operation on the cached Oracle Database table can negatively affect the operations performed on TimesTen for the affected rows. TimesTen does not detect or resolve update conflicts that occur on the Oracle database. Committed updates made directly on a cached Oracle Database table may be overwritten by a committed update made on the TimesTen cache table when the cache table update is propagated to the Oracle database. In addition, deleting rows on the cached Oracle Database table could cause an empty update if TimesTen tries to update a row that no longer exists.

避免多头写,不过Oracle端还是可以写的,注意以下事项即可。虽然在定义时不能指定where条件,但是可以在load时指定where条件来进行数据分区

To ensure that not all data is restricted from DML statements on Oracle Database, you can partition the data on Oracle Database to separate the data that is to be included in the AWT cache group from the data to be excluded from the AWT cache group.

清理cache group

$ ttisql -v1 -connstr "dsn=cachedb1_1122;uid=cacheadm;pwd=timesten;oraclepwd=oracle"
Command> call ttGridDetach;
 3363: Node is not attached to a grid <-说明是cache group而非cache grid
Command> drop cache group CACHEADM.D_AWT;
Command> drop cache group CACHEADM.AWT;
Command> call ttcachestop;
Command> call ttrepstop;
Command> call ttGridDestroy('samplegrid');
Command> call ttGridNameGet;
< <NULL> >

参考

  • Cache User Guide, Chapter 2 - Getting Started,Performing operations on the read-only cache group
  • Cache User Guide, Chapter 4 - Defining Cache Groups,Creating a cache group,Asynchronous writethrough (AWT) cache group
  • Cache User Guide, Chapter 5 - Cache Group Operations,Loading and refreshing a cache group
  • p159

If there are updates from DML statements that you do not want propagated to the Oracle database, then you can disable propagation of committed updates (as a result of executing DML statements) within the current transaction to the Oracle database by setting the flag in the ttCachePropagateFlagSet built-in procedure to zero. After the flag is set to zero, the effects of executing any DML statements are never propagated to the back-end Oracle database. Thus, these updates exist only on the TimesTen database. You can then re-enable propagation by resetting the flag to one with the ttCachePropagateFlagSet built-in procedure. After the flag is set back to one, propagation of all committed updates to the Oracle database resumes.
ttCacheCheck
Configuring batch size
测试Oracle失效时

Command> call ttBookmark();
< 0, 19273992, 0, 19273728, 0, 19267848 >

你可能感兴趣的:(awt,timesten,缓存组)