Oracle In-Memory Database Cache
Introdução
Nesse artigo vamos apresentar o timesten database e mostrar sua funcionalidade que é o timesten in memory cache database. Nessa primeira parte vamos instalar o timesten criar algumas estruturas realizar o cachê de algumas tabelas. No próximo artigo irei explicar melhor os conceitos apresentados aqui e um benchmarking.
Oracle TimesTen In-Memory Database (TimesTen) é utilizado para o gerenciamento de dados em tempo real na camada da aplicação; Utilizamos ele como armazenamento em cache para armazenar tabelas acessadas com frequência de um servidor de banco de dados Oracle para a camada da aplicação(cachê) mantendo a consistência dos dados armazenados; e um componente de replicação de dados transacionais para garantir a alta disponibilidade entre camadas.
O Oracle In-Memory Database Cache (IMDB Cache) usa uma abordagem exclusiva ao permitir o armazenamento em cache de tabelas e fragmentos de tabelas a partir de um banco de dados Oracle para a camada de aplicativos. Os fragmentos de tabela são descritos através de uma sintaxe SQL estendida e são armazenados em um Oracle TimesTen In-Memory Database (TimesTen). Os aplicativos lêem e atualizam os dados armazenados em cache usando SQL, PL/SQL ou ProC e o Timesten Cache propaga atualizações automaticamente a partir de um banco de dados Oracle para o armazenamento em cache e vice-versa, através de APIs de ODBC, JDBC, Oracle Call Interface (OCI) e TTClasses , bem como através do ProC/C++. Ao oferecer suporte a interfaces padrão e interfaces conhecidas da Oracle, o TimesTen garante a facilidade de adoção por aplicativos já existentes.
Embora o TimesTen opere em dados que estão na memória principal, os bancos de dados TimesTen são persistentes e recuperáveis em caso de falha de software, hardware ou falta de energia. A durabilidade é garantida através de pontos de verificação e registro no disco. Os aplicativos podem escolher as propriedades ACID de suas transações, mas opções mais flexíveis também estão disponíveis para obter maior desempenho.
Existem outras soluções no mercado que oferecerem a possibilidade de carregar os dados do banco de dados para a memória criando um cache, o memcached é uma opção open source, porém o timesten se diferencia por ser totalmente integrado ao Oracle Database, ele é realmente uma solução incrível que permite colocar tabelas totalmente em memória de forma simples, ao longo desse e de outros artigos irei mostrar de que forma ele pode ajudar quando precisamos escalar a aplicação com muita performance.
Instalando o Timesten Database
Vamos instalar o timesten database, o sistema operacional que utilizei é Linux red hat 6, mas o timesten tem versões para outros sistemas operacionais. Abaixo o link para download do software.
http://www.oracle.com/technetwork/products/timesten/downloads/index.html
Após download com o root vamos criar o usuário owner do timesten e o grupo.
[ttadmin@sslvdbdob01 ~]$ useradd ttadmin
[ttadmin@sslvdbdob01 ~]$ groupadd timesten
[ttadmin@sslvdbdob01 ~]$ usermod -a -G timesten ttadmin
No linux precisamos criar um local para registro da instancia do timesten, ainda precisamos realizar essa operação com o usuário root.
[ttadmin@sslvdbdob01 ~]$ mkdir /etc/TimesTen
[ttadmin@sslvdbdob01 ~]$ chgrp ttadmin /etc/TimesTen
[ttadmin@sslvdbdob01 ~]$ chmod 770 /etc/TimesTen/
Ainda como root vamos executar as adequações no sistema operacional.
Habilitar o large pages
Ele somente pode ser habilitado se o kernel do linux tem suporte ao large pages ou tambem chamado “huge pages”
[root@sslvdbdob01 ~]# echo 32 > /proc/sys/vm/nr_hugepages
Instalar as libs: libaio and libelf.
[root@sslvdbdob01 ~]# yum install libaio
[root@sslvdbdob01 ~]# yum install libelf
Aumentar a shared memory para 2048MB no /etc/sysctl.conf
kernel.shmmax=2147483648
Alterar também os parâmetros abaixo no nosso caso que utilizaremos para cache:
net.ipv4.tcp_rmem=4096 4194304 4194304
net.ipv4.tcp_wmem=98304 4194304 4194304
net.core.rmem_default=262144
net.core.wmem_default=262144
net.core.rmem_max=4194304
net.core.wmem_max=4194304
net.ipv4.tcp_window_scaling=1
net.ipv4.ip_local_port_range="1024 65000"
Com o usuário ttadmin vamos descompactar os binários e iniciar a instalação.
[ttadmin@sslvdbdob01 ~]$tar -xf timesten112241.linux86.gz
[ttadmin@sslvdbdob01 ~]$cd linux86/
[ttadmin@sslvdbdob01 ~]$./setup.sh
Na instalação vamos utilizar as opções abaixo.
- Instance name: tt1122 (Podemos deixar o nome default, vale ressaltar que cada instancia do timesten tem um nome único, caso outra instalação ocorra um nome diferente tem que ser atribuido)
- Install the “Client/Sever and Data manager”(Vamos utilizar a opção numero 1 que corresponde a linha Client/Server and Data Manager)
- Install into /home/ttadmin (A Opção Default é a home do usuário ttadmin, vamos utilizar essa opção)
- Create the daemon directory /home/ttadmin/TimesTen/tt1122/info (Vamos utilizar essa opção default)
- Daemon logs are in /home/ttadmin/TimesTen/tt1122/info (opção default)
- Default port for the TimesTen daemon: 53396 (Opção default)
- Do not restrict access to the ttadmin group. Restrict it to the timesten group. (Vamos habilitar essa opção e restringir o acesso ao timesten para somente usuários do grupo)
- Enable PL/SQL(Habilitar essa opção)
- TNS_ADMIN is skipped and left unset (Nessa opção precisamos passar o valor de onde esta o nosso tnsnames.ora , essa informação é necessária porque estamos utilizando o timesten para cache de tabelas do Oracle, Caso fossemos utilizar ele independente do Oracle database não precisaríamos passar essa informação.
No meu caso : /u01/app/oracle/product/11.2.0/db_1/network/admin/
- The TimesTen server listens on 53397 (Default)
- Install the QuickStart and Documentation: yes ( cuidado nao é default)
- Create the DemoDataStore in /home/ttadmin/TimesTen/tt1122/info (opção default)
- Do not use Replication with Oracle Clusterware(não)
Ao finalizar iremos validar a instalação seguindo os seguintes passos:
[ttadmin@sslvdbdob01 linux8664]$ cd/home/ttadmin/TimesTen/tt1122
[ttadmin@sslvdbdob01 linux8664]$ cd/Bin
[ttadmin@sslvdbdob01 linux8664]$ ls ttenv.*
[ttadmin@sslvdbdob01 linux8664]$ chmod 755 ttenv.*
[ttadmin@sslvdbdob01 linux8664]$./ttenv.sh
O script ttenv.sh serve para habilitar as variáveis de ambiente, recomendo colocar as variáveis desse arquivo dentro do profile do usuário. O comando ttstatus nos fornece o status da instancia do timesten e o ttversion informações sobre a instalação.
[ttadmin@sslvdbdob01 bin]$ ttstatus
TimesTen status report as of Tue Mar 19 14:42:33 2013
Daemon pid 27513 port 53396 instance tt1122
TimesTen server pid 27522 started on port 53397
------------------------------------------------------------------------
Accessible by group ttadmin
End of report
[ttadmin@sslvdbdob01 bin]$ ttversion
TimesTen Release 11.2.2.4.1 (64 bit Linux/x86_64) (tt1122:53396) 2012-10-30T07:17:51Z
Instance admin: ttadmin
Instance home directory: /home/ttadmin/TimesTen/tt1122
Group owner: ttadmin
Daemon home directory: /home/ttadmin/TimesTen/tt1122/info
PL/SQL enabled.
Caso precise alterar a variável TNS_ADMIN e as portas utilizadas podemos utilizar o utilitário ttmodinstall
Precisamos testar a conectividade do timesten com o Oracle database, vamos logar no sqlplus utilizando a entrada presente no tnsnames.ora passado na instalação.
[ttadmin@sslvdbdob01 ~]$ sqlplus hudson @iraja
SQL*Plus: Release 11.2.0.2.0 Production on Thu Mar 21 17:46:33 2013
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL>
Nesse ponto o timesten já esta instalado e com conexão com o Oracle database, agora vamos passar a configurar o timesten para criarmos o nosso cachê em memória das tabelas do Oracle database.
Para se conectar ao timesten precisamos de um Data Source Name(DSN) para se conectar ao timesten database.
Um DSN identifica um banco de dados TimesTen, um banco de dados pode ser referenciado por vários DSNs. A diferença entre cada um destes únicos DSNs está na especificação dos atributos de ligação à base de dados. Esta fornece nomes convenientes para configurações de conexão diferentes para um único banco de dados.
Precisamos editar o arquivo localizado no diretório de instalação do timesten
$TimesTen_install_dir/info/sys.odbc.ini
Na aba[ODBC Data Sources] Vamos adicionar o nome da nossa DSN como o exemplo abaixo, iremos utilizar o nome: ora_cache_1
[ODBC Data Sources]
TT_1122=TimesTen 11.2.2 Driver
ora_cache1=TimesTen 11.2.2 Driver
sampledb_1122=TimesTen 11.2.2 Driver
cachedb1_1122=TimesTen 11.2.2 Driver
repdb1_1122=TimesTen 11.2.2 Driver
repdb2_1122=TimesTen 11.2.2 Driver
sampledbCS_1122=TimesTen 11.2.2 Client Driver
cachedb1CS_1122=TimesTen 11.2.2 Client Driver
repdb1CS_1122=TimesTen 11.2.2 Client Driver
repdb2CS_1122=TimesTen 11.2.2 Client Driver
Na aba NEW Data source e vamos adicionar o ora_cache_1, porem antes verificaremos o characterset do Oracle, no sqlplus executaremos a seguinte query.
SQL> SELECT value FROM nls_database_parameters WHERE parameter='NLS_CHARACTERSET';
VALUE
----------------------------------------
WE8MSWIN1252
Insira os valores abaixo, lembrando que o diretório “/home/ttadmin/Timesten/tt1122” é o meu diretório default , caso tenha alterado essas opções na instalação lembre-se de alterar também esses valores.
[ora_cache_1]
Driver= /home/ttadmin/TimesTen/tt1122/lib/libtten.so
DataStore= /home/ttadmin/TimesTen/tt1122/ttdata/datastore/ora_cache_1
LogDir= /home/ttadmin/TimesTen/tt1122/ttdata/logdir
PermSize=64
TempSize=32
OracleNetServiceName=iraja
DatabaseCharacterSet= WE8MSWIN1252
Driver é o local onde fica armazenado os binários ODBC
Datastore é o local com o nome de onde os checkpoints do database vão ser armazenados
LogDir vai armazenar os logs transacionais
PermSize é o valor em MB permanente para uma partição do timesten
TempSize é o valor em MB permanenten para uma partição temporária
OracleNetServiceName é a entrada do tnsnames.ora que o timesten vai se conectar
DatabaseCharacterSet é o characterset que verificamos no Oracle, ele precisar ser idêntico.
Precisaremos preparar o Oracle database para configurar os caches no timesten, execute as ações abaixo:
[ttadmin@sslvdbdob01 ~]$ cd $TimesTen_install_dir/oraclescripts
É necessário logar no Oracle database com um usuário com privilégios administrativos no meu caso eu loguei com o sys.
[ttadmin@sslvdbdob01 ~]$ sqlplus sys @iraja as sysdba
Vamos criar um tablespace para o timesten armazenar as informações so grid.
CREATE TABLESPACE CACHETIMESTEN DATAFILE '/u01/app/oracle/oradata/cachetimesten.dbf' SIZE 100M
Autoextend on
Next 10M;
Após a criação execute o script @initCacheGlobalSchema passando como parâmetro o nome do tablespace que acabamos de criar.Esse script cria o usuário timesten, cria as tabelas de sistemas deixando como owner o timesten user,cria a role TT_CACHE_ADMIN_ROLE que da privilegio para nas tabelas do Oracle.
SQL> @initCacheGlobalSchema "CACHETIMESTEN"
Please enter the tablespace where TIMESTEN user is to be created
The value chosen for tablespace is CACHETIMESTEN
******* 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.
Criaremos um schema para criar as tabelas que vão ser utilizadas no cachê do timesten.
SQL> CREATE USER oratab IDENTIFIED BY abc123;
SQL> GRANT CREATE SESSION, RESOURCE TO oratab;
Também precisamos criar um usuário que será administrador do cache do timesten.
CREATE USER cacheuser IDENTIFIED BY abc123
DEFAULT TABLESPACE CACHETIMESTEN QUOTA UNLIMITED ON CACHETIMESTEN;
@grantCacheAdminPrivileges "cacheuser"
Executamos a procedure grantCacheAdminPrivileges.sql para passar os privilégios necessários para o usuário administrador do timesten.
SQL> CREATE USER cacheuser IDENTIFIED BY abc123
2 DEFAULT TABLESPACE CACHETIMESTEN QUOTA UNLIMITED ON CACHETIMESTEN;
User created.
SQL> @grantCacheAdminPrivileges "cacheuser"
Please enter the administrator user id
The value chosen for administrator user id is cacheuser
***************** Initialization for cache admin begins ******************
0. Granting the CREATE SESSION privilege to CACHEUSER
1. Granting the TT_CACHE_ADMIN_ROLE to CACHEUSER
2. Granting the DBMS_LOCK package privilege to CACHEUSER
3. Granting the RESOURCE privilege to CACHEUSER
4. Granting the CREATE PROCEDURE privilege to CACHEUSER
5. Granting the CREATE ANY TRIGGER privilege to CACHEUSER
6. Granting the DBMS_LOB package privilege to CACHEUSER
7. Granting the SELECT on SYS.ALL_OBJECTS privilege to CACHEUSER
8. Granting the SELECT on SYS.ALL_SYNONYMS privilege to CACHEUSER
9. Checking if the cache administrator user has permissions on the default
tablespace Permission exists
11. Granting the CREATE ANY TYPE privilege to CACHEUSER
12. Granting the SELECT on SYS.GV$LOCK privilege to CACHEUSER (optional)
13. Granting the SELECT on SYS.GV$SESSION privilege to CACHEUSER (optional)
14. Granting the SELECT on SYS.DBA_DATA_FILES privilege to CACHEUSER (optional)
15. Granting the SELECT on SYS.USER_USERS privilege to CACHEUSER (optional)
16. Granting the SELECT on SYS.USER_FREE_SPACE privilege to CACHEUSER
(optional)
17. Granting the SELECT on SYS.USER_TS_QUOTAS privilege to CACHEUSER (optional)
18. Granting the SELECT on SYS.USER_SYS_PRIVS privilege to CACHEUSER (optional)
********* Initialization for cache admin user done successfully *********
SQL>
Agora vamos logar no timesten utilizando a DSN que criamos com o utilitario ttisql
[ttadmin@sslvdbdob01 info]$ ttisql ora_cache_1
Copyright (c) 1996-2011, Oracle. All rights reserved.
Type ? or "help" for help, type "exit" to quit ttIsql.
connect "DSN=ora_cache_1";
Connection successful: DSN=ora_cache_1;UID=ttadmin;DataStore=/u01/ttdata/datastore/ora_cache_1;DatabaseCharacterSet=WE8MSWIN1252;
ConnectionCharacterSet=US7ASCII;DRIVER=/home/ttadmin/TimesTen/tt1122/lib/libtten.so;LogDir=/u01/ttdata/logdir;PermSize=64;TempSize=32;
TypeMode=0;OracleNetServiceName=iraja;
(Default setting AutoCommit=1)
Podemos executar o comando dssize para ver o tamanho do database no momento
Command> dssize
PERM_ALLOCATED_SIZE: 65536
PERM_IN_USE_SIZE: 8976
PERM_IN_USE_HIGH_WATER: 8997
TEMP_ALLOCATED_SIZE: 32768
TEMP_IN_USE_SIZE: 11053
TEMP_IN_USE_HIGH_WATER: 13204
Podemos executar o comando ttstatus via host e verificar a nossa conexão
Command> host ttstatus;
TimesTen status report as of Tue Mar 19 18:23:18 2013
Daemon pid 27513 port 53396 instance tt1122
TimesTen server pid 27522 started on port 53397
------------------------------------------------------------------------
Data store /u01/ttdata/datastore/ora_cache_1
There are 12 connections to the data store
Shared Memory KEY 0x020309da ID 3080195
PL/SQL Memory KEY 0x030309da ID 3112964 Address 0x7fa0000000
Type PID Context Connection Name ConnID
Process 29547 0x00000000006300b0 ora_cache_1 1
Subdaemon 27518 0x0000000000544850 Manager 142
Subdaemon 27518 0x000000000059b1e0 Rollback 141
Subdaemon 27518 0x00007f98ac0008c0 IndexGC 133
Subdaemon 27518 0x00007f98b40008c0 HistGC 132
Subdaemon 27518 0x00007f98b80008c0 Log Marker 135
Subdaemon 27518 0x00007f98bc0008c0 AsyncMV 134
Subdaemon 27518 0x00007f98c00008c0 Aging 138
Subdaemon 27518 0x00007f98c40008c0 Deadlock Detector 137
Subdaemon 27518 0x00007f98c80008c0 Checkpoint 136
Subdaemon 27518 0x00007f98cc0008c0 Monitor 139
Subdaemon 27518 0x00007f98e00008c0 Flusher 140
Replication policy : Manual
Cache Agent policy : Manual
PL/SQL enabled.
------------------------------------------------------------------------
Accessible by group ttadmin
Precisamos criar o usuário cacheuser e o usuario oratab dentro do timesten database
Command> CREATE USER cacheuser IDENTIFIED BY abc123;
Command> GRANT CREATE SESSION, CACHE_MANAGER, CREATE ANY TABLE TO cacheuser;
Command> CREATE USER oratab IDENTIFIED BY abc123;
Após a criação precisamos passar para o TimesTen o nome do administrador do cache criado no Oracle com a procedure ttCacheUidPwdSet passando o nome do usuário e a senha.
% ttIsql "DSN=ora_cache_1;UID=cacheuser;PWD=abc123;OraclePWD=abc123"
Command> call ttCacheUidPwdSet('cacheuser','abc123');
Agora precisamos criar os Caches Grids
Precisamos criar o cache grid para definir um framework para o timesten realizar o cache das tabelas do Oracle. Nos próximos artigos irei explicar o conceito de cache grid mais afundo.
Para criar o cache vamos usar a procedure ttGridCreate dentro do ttisql
Command> call ttGridCreate('ora_1_grid');
Apos criarmos o cache grid precisamos associar a o timesten database a esse cache grid.
Command> call ttGridNameSet('ora_1_grid');
Agora vamos criar as tabelas dentro do Oracle Database que vão estar no cachê do timesten database.
SQL> CREATE TABLE TAB_LET (keyval NUMBER NOT NULL PRIMARY KEY, str VARCHAR2(32));
SQL> CREATE TABLE TAB_ESC (pk NUMBER NOT NULL PRIMARY KEY, attr VARCHAR2(40));
SQL> INSERT INTO TAB_LET VALUES (1, 'Hello');
SQL> INSERT INTO TAB_LET VALUES (2, 'World');
SQL> INSERT INTO TAB_ESC VALUES (100, 'TimesTen');
SQL> INSERT INTO TAB_ESC VALUES (101, 'IMDB');
SQL> COMMIT;
É necessário passar os privilégios para o usuário cacheuser nas tabelas.
SQL> GRANT SELECT ON TAB_LET TO cacheuser;
SQL> GRANT SELECT ON TAB_ESC TO cacheuser;
SQL> GRANT INSERT ON TAB_ESC TO cacheuser;
SQL> GRANT UPDATE ON TAB_ESC TO cacheuser;
SQL> GRANT DELETE ON TAB_ESC TO cacheuser;
Precisamos executar a procedure ttcacheStart para iniciar o cacheagente do timesten database.
Command> call ttCacheStart;
Criando os Cache Groups
Um cache group é uma coleção de tabelas do Oracle Database que irão fazer cache dentro do timesten in memory database. Um Cache group pode ser de dois tipos, readonly(somente leitura) e updatble (atualizaveis)
ReadOnly Cache group é um grupo de tabelas ou fragmentos de tabelas do Oracle database que fazem cache no timesten com somente operações de leitura, as tabelas são atualizadas no Oracle database e periodicamente são atualizadas no timesten database.
Asynchronous writethrough (AWT) é um grupo de tabelas ou fragmentos de tabelas do oracle que fazem cache no timesten que podem ser atualizadas (read/write) para transações dentro do timesten, as atualizações são propagadas para o Oracle database , essa atualização pode ser feita de forma assíncrona ou síncrona.
Command CREATE READONLY CACHE GROUP readcache
AUTOREFRESH INTERVAL 5 SECONDS
FROM oratab.TAB_LET
(keyval NUMBER NOT NULL PRIMARY KEY, str VARCHAR2(32));
Command> CREATE DYNAMIC ASYNCHRONOUS WRITETHROUGH GLOBAL CACHE GROUP writecache FROM oratab.TAB_ESC (pk NUMBER NOT NULL PRIMARY KEY, attr VARCHAR2(40));
Agora que os cachegroups foram criados podemos executar o comando abaixo para visualizar a definição dos dois.
Command> cachegroups;
Cache Group CACHEUSER.READCACHE:
Cache Group Type: Read Only
Autorefresh: Yes
Autorefresh Mode: Incremental
Autorefresh State: Paused
Autorefresh Interval: 5 Seconds
Autorefresh Status: ok
Aging: No aging defined
Root Table: ORATAB.TAB_LET
Table Type: Read Only
Cache Group CACHEUSER.WRITECACHE:
Cache Group Type: Asynchronous Writethrough global (Dynamic)
Autorefresh: No
Aging: LRU on
Root Table: ORATAB.TAB_ESC
Table Type: Propagate
Realizando operações com o ReadOnly Cache
Nesse momento vamos carregar a tabelas tab_let no timesten database utilizando o cache group readonly.Quando carregamos a tabela do Oracle para o Timesten colocamos essa tabela em memória.
Command> LOAD CACHE GROUP readcache COMMIT EVERY 256 ROWS;
2 cache instances affected.
Precisamos conectar com ttIsql no nossa DSN a ora_cache_1 como administrador da instancia do timesten. Para passar privilegio de leitura na tabela oratab.tab_let para o administrador do cache.
[ttadmin@sslvdbdob01 ~]$ ttisql ora_cache_1
Copyright (c) 1996-2011, Oracle. All rights reserved.
Type ? or "help" for help, type "exit" to quit ttIsql.
connect "DSN=ora_cache_1";
Connection successful: DSN=ora_cache_1;UID=ttadmin;DataStore=/u01/ttdata/datastore/ora_cache_1;DatabaseCharacterSet=WE8MSWIN1252;
ConnectionCharacterSet=US7ASCII;DRIVER=/home/ttadmin/TimesTen/tt1122/lib/libtten.so;LogDir=/u01/ttdata/logdir;PermSize=64;TempSize=32;TypeMode=0;
OracleNetServiceName=iraja;
(Default setting AutoCommit=1)
Command> GRANT SELECT ON oratab.tab_let TO cacheuser;
Command> exit
Dentro da nossa DSN com o usuário administrador do cachê vamos realizar uma consulta.
[ttadmin@sslvdbdob01 ~]$ ttIsql "DSN=ora_cache_1;UID=cacheuser;PWD=abc123;OraclePWD=abc123"
Copyright (c) 1996-2011, Oracle. All rights reserved.
Type ? or "help" for help, type "exit" to quit ttIsql.
connect "DSN=ora_cache_1;UID=cacheuser;PWD=abc123;OraclePWD=abc123";
Connection successful: DSN=ora_cache_1;UID=cacheuser;DataStore=/u01/ttdata/datastore/ora_cache_1;DatabaseCharacterSet=WE8MSWIN1252;
ConnectionCharacterSet=US7ASCII;DRIVER=/home/ttadmin/TimesTen/tt1122/lib/libtten.so;LogDir=/u01/ttdata/logdir;PermSize=64;
TempSize=32;TypeMode=0;OracleNetServiceName=iraja;
(Default setting AutoCommit=1)
Command> select * from oratab.tab_let;
< 1, Hello >
< 2, World >
2 rows found.
Esses dados já estão em memória.
Agora vamos atualizar o cache “readcache”.
Vamos abrir uma sessão no Oracle Database e realizar as seguintes instruções SQL.
SQL> INSERT INTO tab_let VALUES (3, 'Welcome');
SQL> DELETE FROM tab_let WHERE keyval=2;
SQL> UPDATE tab_let SET str='Hi' WHERE keyval=1;
SQL> COMMIT;
Depois de 5 segundos já podemos visualizar as modificações no timesten database.
Realizando operações com os Cache Atualizaveis (Asynchronous writethrough)
Nessa etapa vamos realizar operações com os caches atualizáveis os AWT, as atualizações que faremos no timesten poderemos visualizar no Oracle database.
Vamos conectar com ttIsql no nossa DSN a ora_cache_1 como administrador da instancia do timesten. E vamos dar privilegio de leitura na tabela oratab.tab_esc para o administrador do cache.
[ttadmin@sslvdbdob01 ~]$ ttisql ora_cache_1
Copyright (c) 1996-2011, Oracle. All rights reserved.
Type ? or "help" for help, type "exit" to quit ttIsql.
connect "DSN=ora_cache_1";
Connection successful: DSN=ora_cache_1;UID=ttadmin;DataStore=/u01/ttdata/datastore/ora_cache_1;DatabaseCharacterSet=WE8MSWIN1252;ConnectionCharacterSet=US7ASCII;
DRIVER=/home/ttadmin/TimesTen/tt1122/lib/libtten.so;LogDir=/u01/ttdata/logdir;PermSize=64;TempSize=32;TypeMode=0;OracleNetServiceName=iraja;
(Default setting AutoCommit=1)
Command> GRANT SELECT ON oratab.tab_esc TO cacheuser;
Vamos logar na nossa DSN com o usuário administrador do cachê e realizar uma consulta e associar o grid ao timesten.
Antes de realizar operações em cache groups globais nas tabelas cacheadas precisamos associar o timesten database ao cache grid da sessão.
A procedure abaixo realiza essa associação, aonde os valores iraja1 é o identificador único do membro nesse grid, sslvdbdob01 é nome do host e 5001 é o valor da porta tcp/ip utilizada no cacheagent.
call ttGridAttach(1,'IRAJA1',' sslvdbdob01',5001);
[ttadmin@sslvdbdob01 ~]$ ttIsql "DSN=ora_cache_1;UID=cacheuser;PWD=abc123;OraclePWD=abc123"
Copyright (c) 1996-2011, Oracle. All rights reserved.
Type ? or "help" for help, type "exit" to quit ttIsql.
connect "DSN=ora_cache_1;UID=cacheuser;PWD=abc123;OraclePWD=abc123";
Connection successful: DSN=ora_cache_1;UID=cacheuser;DataStore=/u01/ttdata/datastore/ora_cache_1;DatabaseCharacterSet=WE8MSWIN1252;ConnectionCharacterSet=US7ASCII;
DRIVER=/home/ttadmin/TimesTen/tt1122/lib/libtten.so;LogDir=/u01/ttdata/logdir;PermSize=64;TempSize=32;TypeMode=0;OracleNetServiceName=iraja;
(Default setting AutoCommit=1)
Command> call ttGridAttach(1,'IRAJA1','sslvdbdob01',5001);
Command> SELECT * FROM oratab.tab_esc WHERE pk=100;
< 100, TimesTen >
1 row found.
Nos caches groups dinâmicos o cache é carregado com os valores das tabelas por demanda. Só é caregado em memória o que é solicitado. As instruções select,delete,update ou insert no timesten cachê são identificadas no cachê da instancia e automaticamente carregadas nas tabelas do Oracle caso não existam.
Agora vamos atualizar o cachê vamos logar como administrador da instancia e executar os grants necessários.
[ttadmin@sslvdbdob01 ~]$ ttisql ora_cache_1
Copyright (c) 1996-2011, Oracle. All rights reserved.
Type ? or "help" for help, type "exit" to quit ttIsql.
connect "DSN=ora_cache_1";
Connection successful: DSN=ora_cache_1;UID=ttadmin;DataStore=/u01/ttdata/datastore/ora_cache_1;DatabaseCharacterSet=WE8MSWIN1252;
ConnectionCharacterSet=US7ASCII;DRIVER=/home/ttadmin/TimesTen/tt1122/lib/libtten.so;LogDir=/u01/ttdata/logdir;PermSize=64;TempSize=32;TypeMode=0;
OracleNetServiceName=iraja;
(Default setting AutoCommit=1)
GRANT INSERT ON oratab.tab_esc TO cacheuser;
GRANT DELETE ON oratab.tab_esc TO cacheuser;
GRANT UPDATE ON oratab.tab_esc TO cacheuser;
Após passar os grants vamos realizar instruções sql no timesten database e visualizar as alterações no Oracle database.
ttadmin@sslvdbdob01 ~]$ ttIsql "DSN=ora_cache_1;UID=cacheuser;PWD=abc123;OraclePWD=abc123"
Copyright (c) 1996-2011, Oracle. All rights reserved.
Type ? or "help" for help, type "exit" to quit ttIsql.
connect "DSN=ora_cache_1;UID=cacheuser;PWD=abc123;OraclePWD=abc123";
Connection successful: DSN=ora_cache_1;UID=cacheuser;DataStore=/u01/ttdata/datastore/ora_cache_1;DatabaseCharacterSet=WE8MSWIN1252;
ConnectionCharacterSet=US7ASCII;DRIVER=/home/ttadmin/TimesTen/tt1122/lib/libtten.so;LogDir=/u01/ttdata/logdir;PermSize=64;TempSize=32;
TypeMode=0;OracleNetServiceName=iraja;
(Default setting AutoCommit=1)
INSERT INTO oratab.tab_esc VALUES (102, 'Cache');
DELETE FROM oratab.tab_esc WHERE pk=101;
UPDATE oratab.tab_esc SET attr='Oracle' WHERE pk=100;
COMMIT;
Dentro do oracle database com o sqlplus
SQL> select * from tab_esc
PK ATTR
---------- ----------------------------------------
102 Cache
100 Oracle
Conclusão
Nesse artigo aprendemos a instalar o timesten database e a criar um cache de tabelas Oracle dentro dele, vimos alguns conceitos do timesten de forma superficial. No próximo artigo eu vou abordar melhor os seus conceitos e mostrar como podemos utilizá-lo para auxiliar a aplicação criando uma camada consistente de cache.
Appendice A
Caso queria limpar o ambiente criado e realizar as operações novamente, basta realizar os passos abaixo.
Desassociar o cachê group com o cachê grid executando a procedure abaixo.
Command> call ttGridDetach;
Para dropar os caches groups.
Command> GRANT DROP ANY TABLE TO cacheuser;
Command> DROP CACHE GROUP readcache;
Command> DROP CACHE GROUP writecache;
Para destruir o cache grid
call ttGridDestroy('myGrid');
Para realizar o stop do agent
call ttCacheStop;
Referências
- http://docs.oracle.com/cd/E11882_01/timesten.112/e21634/gettingstarted.htm
- http://www.oracle.com/webfolder/technetwork/tutorials/obe/db/timesten/tt1121/2_caching_imdbcache/2_caching_imdbcache.htm
- http://www.oracle.com/webfolder/technetwork/tutorials/obe/db/timesten/tt1121/1_creating_imdbcache_win/1_creating_imdbcache_win.htm
- http://www.oracle.com/technetwork/pt/database/timesten/documentation/tutorial-in-memory-database-cache-1721639-ptb.pdf