Начнем с настройки. В документации процесс создания Cache grid на нескольких машинах описан, на мой взгляд, не досточно четко, поэтому я и решил начать с его конфигурации.
Используемое окружение (три виртуальные машины):
OEL 5.3 (x86) - Oracle Database EE 11.2.0.2.0 – 192.168.2.131 (hostname - db)
OEL 5.3 (x86) - Oracle TimesTen 11.2.1.7.0 (32 bit Linux/x86) – 192.168.2.132 (hostname – tt1)
OEL 5.3 (x86) - Oracle TimesTen 11.2.1.7.0 (32 bit Linux/x86) – 192.168.2.133 (hostname – tt2)
Предварительная настройка для кэш грида, в общем, очень похожа на настройку TimesTen для работы с Oracle Database (об этом можно почитать здесь).
Первоначально, создадим системные объекты и пользователя, с объектами которого будем работать, в Oracle Database.
[oracle@tt1 cache_article]$ sqlplus sys/oracle@orcl as sysdba SQL*Plus: Release 11.1.0.7.0 - Production on Mon Apr 11 02:57:11 2011 Copyright (c) 1982, 2008, 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> create tablespace timesten_tbls 2 / Tablespace created. SQL> create user oratt identified by oracle default tablespace timesten_tbls 2 / User created. SQL> grant create session, resource to oratt 2 / Grant succeeded. SQL> create user cacheadmin identified by oracle default tablespace timesten_tbls quota unlimited on timesten_tbls 2 / User created. SQL> @/u01/app/oracle/product/11.2.1/TimesTen/tt1/oraclescripts/initCacheGlobalSchema.sql "timesten_tbls" Please enter the tablespace where TIMESTEN user is to be created The value chosen for tablespace is timesten_tbls ******* Creation of TIMESTEN schema and TT_CACHE_ADMIN_ROLE starts ******* 1. Creating TIMESTEN schema 2. Creating TIMESTEN.TT_GRIDID table 3. Creating TIMESTEN.TT_GRIDINFO table 4. Creating TT_CACHE_ADMIN_ROLE role 5. Granting privileges to TT_CACHE_ADMIN_ROLE ** Creation of TIMESTEN schema and TT_CACHE_ADMIN_ROLE done successfully ** PL/SQL procedure successfully completed. SQL> @/u01/app/oracle/product/11.2.1/TimesTen/tt1/oraclescripts/grantCacheAdminPrivileges "cacheadmin" Please enter the administrator user id The value chosen for administrator user id is cacheadmin ***************** Initialization for cache admin begins ****************** 0. Granting the CREATE SESSION privilege to CACHEADMIN 1. Granting the TT_CACHE_ADMIN_ROLE to CACHEADMIN 2. Granting the DBMS_LOCK package privilege to CACHEADMIN 3. Granting the RESOURCE privilege to CACHEADMIN 4. Granting the CREATE PROCEDURE privilege to CACHEADMIN 5. Granting the CREATE ANY TRIGGER privilege to CACHEADMIN 6. Granting the DBMS_LOB package privilege to CACHEADMIN 7. Granting the SELECT on SYS.ALL_OBJECTS privilege to CACHEADMIN 8. Granting the SELECT on SYS.ALL_SYNONYMS privilege to CACHEADMIN 9. Checking if the cache administrator user has permissions on the default tablespace Permission exists 11. Granting the CREATE ANY TYPE privilege to CACHEADMIN ********* Initialization for cache admin user done successfully ********* SQL>На этом, настройки в Oracle Database завершены. Преступим к настройкам в TimesTen.
Настройка на узле tt1
Создадим DSN и активируем возможность создания грида. Для этого явно зададим атрибут CachegridEnable( по умолчанию он имеет значение 1).
[db_сache1] Driver=/u01/app/oracle/product/11.2.1/TimesTen/tt1/lib/libtten.so DataStore=/u01/app/oracle/datastore/db_cache1 PermSize=100 TempSize=32 PLSQL=1 DatabaseCharacterSet= WE8MSWIN1252 CachegridEnable=1 OracleNetServiceName=ORCL
Создадим необходимых пользователей в TimesTen.
[oracle@tt1 cache_article]$ ttisql db_cache1 Copyright (c) 1996-2010, Oracle. All rights reserved. Type ? or "help" for help, type "exit" to quit ttIsql. connect "DSN=db_cache1"; Connection successful: DSN=db_cache1;UID=oracle;DataStore=/u01/app/oracle/datastore/db_cache1; DatabaseCharacterSet=WE8MSWIN1252;ConnectionCharacterSet=US7ASCII; DRIVER=/u01/app/oracle/product/11.2.1/TimesTen/tt1/lib/libtten.so;PermSize=50;TempSize=32;TypeMode=0;OracleNetServiceName=ORCL; (Default setting AutoCommit=1) Command> create user cacheadmin identified by oracle; User created. Command> grant create session, cache_manager, create any table, drop any table to cacheadmin; Command> create user oratt identified by oracle; User created. Command> grant create session to oratt; Command>
Далее установим имя и пароль кэш администратора в Oracle Database.
Command> connect "DSN=db_cache1;UID=cacheadmin;PWD=oracle;OraclePWD=oracle"; Connection successful: DSN=db_cache1;UID=cacheadmin;DataStore=/u01/app/oracle/datastore/db_cache1; DatabaseCharacterSet=WE8MSWIN1252;ConnectionCharacterSet=US7ASCII;DRIVER=/u01/app/oracle/product/11.2.1/TimesTen/tt1/lib/libtten.so; PermSize=50;TempSize=32;TypeMode=0;OracleNetServiceName=ORCL; (Default setting AutoCommit=1) con1: Command> call ttCacheUidPwdSet('cacheadmin','oracle');
Далее, создаем грид и устанавливаем имя грида с datastore. После чего, запускаем кэш агент.
con1: Command> call ttGridCreate('myGrid'); con1: Command> call ttGridInfo; < MYGRID, CACHEADMIN, Linux Intel x86, 32-bit, 11, 2, 1 > 1 row found. con1: Command> call ttGridNameSet('myGrid'); con1: Command> call ttCacheStart;
Последний шаг, это "присоединение" узла к гриду.
con1: Command> call ttGridNodeStatus; 0 rows found. con1: Command> call ttGridAttach(1, 'tt1', 'tt1', 5002); con1: Command> call ttGridNodeStatus; < MYGRID, 1, 1, T, tt1, MYGRID_tt1_1, 192.168.2.132, 5002, <null>, <null>, <null>, <null>, <null> > 1 row found. Command>
Настройка на узле tt2
На втором узле (или любом последующем узле, который вы хотите включить в грид), необходимо выполнить теже действия, что и на узле tt1. Только создавать grid не нужно, т.к. он уже создан.
Выполним эти действия.
[oracle@tt2 cache_article]$ ttisql db_cache2 Copyright (c) 1996-2010, Oracle. All rights reserved. Type ? or "help" for help, type "exit" to quit ttIsql. connect "DSN=db_cache2"; Connection successful: DSN=db_cache2;UID=oracle;DataStore=/u01/app/oracle/datastore/db_cache2; DatabaseCharacterSet=WE8MSWIN1252;ConnectionCharacterSet=US7ASCII; DRIVER=/u01/app/oracle/product/11.2.1/TimesTen/tt2/lib/libtten.so; PermSize=32;TempSize=32;TypeMode=0;PLSQL_TIMEOUT=1000;OracleNetServiceName=ORCL; (Default setting AutoCommit=1) Command> create user cacheadmin identified by oracle; User created. Command> grant create session, cache_manager, create any table, drop any table to cacheadmin; Command> create user oratt identified by oracle; User created. Command> grant create session to oratt; Command> connect "DSN=db_cache2;UID=cacheadmin;PWD=oracle;OraclePWD=oracle"; connect "DSN=db_cache2;UID=cacheadmin;PWD=oracle;OraclePWD=oracle"; Connection successful: DSN=db_cache2;UID=cacheadmin;DataStore=/u01/app/oracle/datastore/db_cache2;DatabaseCharacterSet=WE8MSWIN1252;ConnectionCharacterSet=US7ASCII;DRIVER=/u01/app/oracle/product/11.2.1/TimesTen/tt2/lib/libtten.so; PermSize=32;TempSize=32;TypeMode=0;PLSQL_TIMEOUT=1000;OracleNetServiceName=ORCL; (Default setting AutoCommit=1) con1: Command> call ttCacheUidPwdSet('cacheadmin','oracle'); con1: Command> call ttGridInfo; < MYGRID, CACHEADMIN, Linux Intel x86, 32-bit, 11, 2, 1 > con1: Command> call ttGridNameSet('myGrid'); con1: Command> call ttCacheStart; con1: Command>Далее, подсоединим данный узел к гриду.
Command> call ttGridNodeStatus; < MYGRID, 1, 1, T, tt1, MYGRID_tt1_1, 192.168.2.132, 5002,, , , , > 1 row found. Command> call ttGridAttach(1, 'tt2', 'tt2', 5002); Command> call ttGridNodeStatus; < MYGRID, 1, 1, T, tt1, MYGRID_tt1_1, 192.168.2.132, 5002, , , , , > < MYGRID, 2, 1, T, tt2, MYGRID_tt2_2, 192.168.2.133, 5002, , , , , > 2 rows found. Command>
На этом конфигурация грида закончена.
Read only Cache Grid
В данном пункте рассмотрим работу Cache Grid с read only кэш группами.
Первоначально создадим таблицу в Oracle Database, которую будем кэшировать, и наполним ее данными.Также предоставим необходимые привилегии кэш администратору.
[oracle@db ~]$ sqlplus oratt/oracle SQL*Plus: Release 11.2.0.2.0 Production on Mon Apr 18 08:22:13 2011 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> create table readtab ( a NUMBER NOT NULL PRIMARY KEY, 2 b VARCHAR2(100)); Table created. SQL> select count(*) from readtab; COUNT(*) ---------- 0 SQL> begin for i in 1 .. 10000 loop insert into readtab values (i,'db'); end loop; end; / 2 3 4 5 6 PL/SQL procedure successfully completed. SQL> select count(*) from readtab; COUNT(*) ---------- 10000 SQL> grant select on readtab to cacheadmin; Grant succeeded. SQL>Теперь создадим и загрузим кэш группы на узлах tt1 и tt2. Данную команду нужно выполнить на обоих узлах.
Command> CREATE READONLY CACHE GROUP readcache > AUTOREFRESH INTERVAL > 5 SECONDS > FROM oratt.readtab ( a NUMBER NOT NULL PRIMARY KEY, > b VARCHAR2(100) ); Command> load cache group readcache commit every 265 rows; 10000 cache instances affected. Command>
Теперь проверим работу кэш грида.
Для выполнения распределенного запроса, необходимо на уровне сессии установить флаг 'GlobalProcessing' в значение 1. Для этого необходимо воспользоваться функцией ttOptSetFlag. Перед этим необходимо отключить autocommit.
Command> connect "DSN=db_cache1;UID=oratt;PWD=oracle;"; Connection successful: DSN=db_cache1;UID=oratt;DataStore=/u01/app/oracle/datastore/db_cache1; DatabaseCharacterSet=WE8MSWIN1252;ConnectionCharacterSet=US7ASCII; DRIVER=/u01/app/oracle/product/11.2.1/TimesTen/tt1/lib/libtten.so; PermSize=32;TempSize=50;TypeMode=0;PLSQL_TIMEOUT=1000;OracleNetServiceName=ORCL; (Default setting AutoCommit=1) Command> select count(*) from readtab; < 10000 > 1 row found. Command> set autocommit 0; Command> call ttOptSetFlag('GlobalProcessing',1); Command> call ttOptGetFlag('GlobalProcessing'); < GlobalProcessing, 1 > 1 row found. Command> select count(*) from readtab; < 20000 > 1 row found. Command>
Как видим, при выполнени распределенного запроса, объем данных увеличился вдвое, т.е. записи задвоились.Поэтому, если у вас есть TimesTen и вы планируете с помощью Grid увеличить объем read only данных, вы должны учитывать, что при создании read only кэш групп, данные кэшируются не глобально, а локально!!! Т.е. по сути, Grid в для read only КЭШ ГРУПП - это только возможность выполнять глобальные запросы и все. Именно поэтому в определении кэш группы нет ключевого слова global.
Так что данную задачу можно решить, к сожалению, только сегментируя данные.
Например, на уровне создания кэш групп.
Пример.
На одном узле (tt1) выполняем:
Command> CREATE READONLY CACHE GROUP readcache > AUTOREFRESH INTERVAL > 5 SECONDS > FROM oratt.readtab ( a NUMBER NOT NULL PRIMARY KEY, > b VARCHAR2(100) ) > where a <= 5000; Command> load cache group readcache commit every 265 rows; 5000 cache instances affected. Command>
А на другом узле (tt2):
Command> CREATE READONLY CACHE GROUP readcache > AUTOREFRESH INTERVAL > 5 SECONDS > FROM oratt.readtab ( a NUMBER NOT NULL PRIMARY KEY, > b VARCHAR2(100) ) > where a >5000; Command> load cache group readcache commit every 265 rows; 5000 cache instances affected. Command>
Следовательно, при выполнении глобальных запросов мы увидим все множество:
Command> connect "DSN=db_cache1;UID=oratt;PWD=oracle;"; Connection successful: DSN=db_cache1;UID=oratt;DataStore=/u01/app/oracle/datastore/db_cache1; DatabaseCharacterSet=WE8MSWIN1252;ConnectionCharacterSet=US7ASCII; DRIVER=/u01/app/oracle/product/11.2.1/TimesTen/tt1/lib/libtten.so; PermSize=32;TempSize=50;TypeMode=0;PLSQL_TIMEOUT=1000;OracleNetServiceName=ORCL; (Default setting AutoCommit=1) con1: Command> con1: Command> con1: Command> con1: Command> select max(a) from readtab; < 5000 > 1 row found. con1: Command> select count(*) from readtab; < 5000 > 1 row found. con1: Command> set autocommit 0; con1: Command> call ttOptSetFlag('GlobalProcessing',1); con1: Command> call ttOptGetFlag('GlobalProcessing'); < GlobalProcessing, 1 > 1 row found. con1: Command> select count(*) from readtab; < 10000 > 1 row found. con1: Command> select max(a) from readtab; < 10000 > 1 row found. con1: Command>
Абсолютно также работают все остальные локальные кэш группы, но у AWT кэш групп есть возможность создания в глобальном режиме. Далее рассмотрим работу AWT кэш групп.
AWT кэш группы в In-Memory DB Cache Grid
C версии 11g при создании AWT кэш групп, можно указать ключевое слово Global,
причем, глобальными могут только AWT кэш группы. Следовательно при указании данного слова, мы говорим о создании распределенного кэша.
Создадим объекты в Oracle DB
[oracle@db ~]$ sqlplus oratt/oracle SQL*Plus: Release 11.2.0.2.0 Production on Tue Apr 19 06:33:32 2011 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> create table awttab ( a NUMBER NOT NULL PRIMARY KEY, b VARCHAR2(100)); 2 Table created. SQL> begin for i in 1 .. 100 loop insert into awttab values (i,'db'); end loop; end; 2 3 4 5 6 / PL/SQL procedure successfully completed. SQL> grant select, insert, update, delete on awttab to cacheadmin; Grant succeeded. SQL> select count(*) from awttab; COUNT(*) ---------- 100 SQL>
Создадим AWT кэш группу. Данный код необходимо выполнить на обоих узлах.
Command> create asynchronous writethrough global cache group awtcache > from oratt.awttab ( a number not null primary key, > b varchar2(100)); Command> Command> call ttRepStart; Command>
Инициируем первоначальные данные. Загружаем данные на узле tt2.
Command> dssize; PERM_ALLOCATED_SIZE: 32768 PERM_IN_USE_SIZE: 5867 PERM_IN_USE_HIGH_WATER: 5867 TEMP_ALLOCATED_SIZE: 32768 TEMP_IN_USE_SIZE: 6789 TEMP_IN_USE_HIGH_WATER: 7351 Command> load cache group awtcache commit every 265 rows; 100 cache instances affected. Command> dssize; PERM_ALLOCATED_SIZE: 32768 PERM_IN_USE_SIZE: 5903 PERM_IN_USE_HIGH_WATER: 5903 TEMP_ALLOCATED_SIZE: 32768 TEMP_IN_USE_SIZE: 6800 TEMP_IN_USE_HIGH_WATER: 7351 Command>
Видно, что записи загрузились. Теперь хост tt2 является владельцем данных строк.
Если мы попытаемся загрузить те же записи на узле tt1, то получим ошибку TT3356.
Command> load cache group awtcache commit every 265 rows; 5056: The cache operation fails: error_type=, error_code=<3356>, error_message: [TimesTen] TT3356: Error loading cache instance from member MYGRID_tt1_1; some instance is already owned by some member - from grid member MYGRID_tt2_2 The command failed. Command>
Т.е. видно, что записи отслеживаются глобально для избежания повторения.
Также, в данной конфигурации можно выполнять глобальные запросы.
Например:
Узел tt2 содержит 100 строк.
Command> connect "DSN=db_cache2;UID=oratt;PWD=oracle;"; Connection successful: DSN=db_cache2;UID=oratt;DataStore=/u01/app/oracle/datastore/db_cache2; DatabaseCharacterSet=WE8MSWIN1252;ConnectionCharacterSet=US7ASCII; DRIVER=/u01/app/oracle/product/11.2.1/TimesTen/tt2/lib/libtten.so; PermSize=32;TempSize=32;TypeMode=0;PLSQL_TIMEOUT=1000;OracleNetServiceName=ORCL; (Default setting AutoCommit=1) Command> select count(*) from awttab; < 100 > 1 row found. Command>
На узле tt1 строк нет и выполняя глобальный запрос мы можем получить необходимые строки с узла tt2.
Command> connect "DSN=db_cache1;UID=oratt;PWD=oracle;"; Connection successful: DSN=db_cache1;UID=oratt;DataStore=/u01/app/oracle/datastore/db_cache1; DatabaseCharacterSet=WE8MSWIN1252;ConnectionCharacterSet=US7ASCII; DRIVER=/u01/app/oracle/product/11.2.1/TimesTen/tt1/lib/libtten.so; PermSize=32;TempSize=50;TypeMode=0;PLSQL_TIMEOUT=1000;OracleNetServiceName=ORCL; (Default setting AutoCommit=1) Command> select count(*) from awttab; < 0 > 1 row found. Command> dssize; PERM_ALLOCATED_SIZE: 32768 PERM_IN_USE_SIZE: 5867 PERM_IN_USE_HIGH_WATER: 5903 TEMP_ALLOCATED_SIZE: 51200 TEMP_IN_USE_SIZE: 6864 TEMP_IN_USE_HIGH_WATER: 7351 Command> set autocommit 0; Command> call ttOptSetFlag('GlobalProcessing',1); Command> call ttOptGetFlag('GlobalProcessing'); < GlobalProcessing, 1 > 1 row found. Command> select count(*) from awttab; < 100 > 1 row found. Command> dssize; PERM_ALLOCATED_SIZE: 32768 PERM_IN_USE_SIZE: 5867 PERM_IN_USE_HIGH_WATER: 5903 TEMP_ALLOCATED_SIZE: 51200 TEMP_IN_USE_SIZE: 6927 TEMP_IN_USE_HIGH_WATER: 7351 PERM_ALLOCATED_SIZE: 32768 PERM_IN_USE_SIZE: 5903 PERM_IN_USE_HIGH_WATER: 5903 TEMP_ALLOCATED_SIZE: 32768 TEMP_IN_USE_SIZE: 6864 TEMP_IN_USE_HIGH_WATER: 7351 Command>
Кроме того, видно, что при выполнении глобальных операции чтения с удаленных узлов, информация не передается на сторону запрашиваемого узла.
Также, определить, выполняется ли глобальный запрос или нет, можно с помощью просмотра плана выполнения запроса.
Например:
Command> showplan 1; Command> select count(*) from awttab; Query Optimizer Plan: STEP: 1 LEVEL: 1 OPERATION: RowLkSerialScan TBLNAME: AWTTAB IXNAME:INDEXED CONDITION: NOT INDEXED: < 0 > 1 row found. Command> Command> select * from awttab; Query Optimizer Plan: STEP: 1 LEVEL: 1 OPERATION: RowLkTtreeScan TBLNAME: AWTTAB IXNAME: AWTTAB INDEXED CONDITION: NOT INDEXED: 0 rows found. Command> call ttOptSetFlag('GlobalProcessing',1); Command> call ttOptGetFlag('GlobalProcessing'); < GlobalProcessing, 1 > 1 row found. Command> select count(*) from awttab; Query Optimizer Plan: STEP: 1 LEVEL: 1 OPERATION: GridScan TBLNAME: IXNAME: INDEXED CONDITION: NOT INDEXED: < 100 > 1 row found. Command>
Но ,что будет, если мы попытаемся вставить запись с уже существующим идентификатором на узле tt1.
Command> select * from awttab where a =50; < 50, db > 1 row found. Command> insert into awttab values (50,'tt1'); 3342: Inserted key already exists on Oracle or remote node The command failed. Command>
Как видно, изменения в строках отслеживается на всех узлах грида.
Но, что же будет с изменением данных? Т.е., что будет, если мы попытаемся изменить
данные на одном узле и прочитать с другого.
Например:
Я выполняю update на узле tt2.
Command> set autocommit 0; Command> update awttab set b='tt2' where a=1; 1 row updated. Command> select * from awttab where a=1; < 1, tt2 > 1 row found. Command>
Конечно, у меня появляется эксклюзивная блокировка на данную строку.
[oracle@tt2 ~]$ ttXactAdmin db_cache2 2011-04-19 07:30:58.367 /u01/app/oracle/datastore/db_cache2 TimesTen Release 11.2.1.7.0 Outstanding locks PID Context TransID TransStatus Resource ResourceID Mode SqlCmdID Name Program File Name: ttIsqlCmd 3754 0x920c740 19.16 Active Database 0x01312d00 IX 0 Row BMUFVUAAABcAAAACBA Xn 34000460 ORATT.AWTTAB Table 574836 IXn 34000460 ORATT.AWTTAB 1 outstanding transaction found [oracle@tt2 ~]$
Пока все отлично, но если я попытаюсь запросить изменяемые данные с другого узла в гриде, я получаю неожиданный результат.
На узле tt1 запрашиваю данные.
Command> call ttOptSetFlag('GlobalProcessing',1); Command> call ttOptGetFlag('GlobalProcessing'); < GlobalProcessing, 1 > 1 row found. Command> select * from awttab where a=1;
Моя сессия подвисает, а на узле tt2 обнаруживаю
[oracle@tt2 ~]$ ttXactAdmin db_cache2 2011-04-19 07:37:38.835 /u01/app/oracle/datastore/db_cache2 TimesTen Release 11.2.1.7.0 Outstanding locks PID Context TransID TransStatus Resource ResourceID Mode SqlCmdID Name Program File Name: ttIsqlCmd 3754 0x920c740 19.18 Active Database 0x01312d00 IX 0 Row BMUFVUAAABcAAAACBA Xn 34000460 ORATT.AWTTAB Table 574836 IXn 34000460 ORATT.AWTTAB Program File Name: timestenorad 3775 0xa3ac540 10.4 Active Database 0x01312d00 IX 0 Table 574836 IXn 0 ORATT.AWTTAB Row BMUFVUAAABqAgAAPSU Xn 0 GRID.AWTTAB_1 Table 574844 IXn 0 GRID.AWTTAB_1 Awaiting locks PID Context TransID Resource ResourceID RMode RSqlCmdID HolderTransID HMode HSqlCmdID Name 3775 0xa3ac540 10.4 Row BMUFVUAAABcAAAACBA Xn 0 19.18 Xn 34000460 ORATT.AWTTAB 2 outstanding transactions found [oracle@tt2 ~]$
Неожиданно!!!
Мой простой запрос на узле tt1 инициировал блокировку кэш агента на узле tt2.
Т.е. перед тем как запросить данные, необходимо сбросить изменения в Oracle Database.
Ну и естественно, после таймаута на подвисшей сессии на узле tt1 получил
6003: Lock request denied because of time-out Details: Tran 10.4 (pid 3775) wants Xn lock on rowid BMUFVUAAABcAAAACBA, table ORATT.AWTTAB. But tran 19.18 (pid 3754) has it in Xn (request was Xn). Holder SQL (update awttab set b='tt2' where a=1) - from grid member MYGRID_tt2_2 0 rows found. The command failed.
Процесс 3775 - это pid кэш агента на узле tt2.
Такое поведение кэша стало для меня полной неожиданностью.
Кроме того, изменение данных может проводить, только владелец объекта.
Например, в моем случае, всеми строками в таблице awttab владеет хост tt2 и если я попытаюсь изменить данные через глобальный запрос с узла tt1, то получу ошибку.
Пример:
Узел tt2.
Command> connect "DSN=db_cache2;UID=oratt;PWD=oracle;"; Connection successful: DSN=db_cache2;UID=oratt;DataStore=/u01/app/oracle/datastore/db_cache2; DatabaseCharacterSet=WE8MSWIN1252;ConnectionCharacterSet=US7ASCII; DRIVER=/u01/app/oracle/product/11.2.1/TimesTen/tt2/lib/libtten.so; PermSize=32;TempSize=32;TypeMode=0;PLSQL_TIMEOUT=1000;OracleNetServiceName=ORCL; (Default setting AutoCommit=1) Command> select count(*) from awttab; < 100 > 1 row found. Command>
Узел tt1.
Command> connect "DSN=db_cache1;UID=oratt;PWD=oracle;"; Connection successful: DSN=db_cache1;UID=oratt;DataStore=/u01/app/oracle/datastore/db_cache1; DatabaseCharacterSet=WE8MSWIN1252;ConnectionCharacterSet=US7ASCII; DRIVER=/u01/app/oracle/product/11.2.1/TimesTen/tt1/lib/libtten.so; PermSize=32;TempSize=50;TypeMode=0;PLSQL_TIMEOUT=1000;OracleNetServiceName=ORCL; (Default setting AutoCommit=1) Command> select * from awttab; 0 rows found. Command>
Теперь попытаемся выполнить изменение строки с узла tt1.
Command> update awttab set b='tt1' where a=30; 805: Global statements other than select and unload has not been implemented The command failed. Command>
Как видно, изменения данных может делать только владелец объекта. Но каким образом сделать так, чтобы строки очутились на необходимом узле?
Это можно сделать опять с помощью распределения загружаемых данных или с помощью динамических кэш групп. В TimesTen Cache Grid можно создавать глобальные динамические AWT кэш группы.
Итог
На мой взгляд, данная конфигурация имеет свои плюсы и минусы. К минусам можно отнести неудобство, что на каждом из узлов грида необходимо выполнить одни и теже действия (кроме создания грида), изменение данных может проводить только владелец объектов и самое большое ограничение, на мой взгяд, невозможностью причитать изменяемые данные с разных узлов. Но сама по себе возможность выполнения распределенных запросов является безусловным плюсом данной конфигурации и может достаточно эффективно использоваться с read only данными, ну и конечно, будем надеяться, что в последующих версиях, данные недочеты будут устранены.
Комментариев нет:
Отправить комментарий