Happy New Year!

Dear friends,

2012 year is coming and I think it is the best time for summarizing the year's result. Well, lets start. In this year I've written 8 technical articles and some of them was published by OTN. I've left Oracle CIS, so I am not Oracle Employee anymore :( I was nominated to Oracle ACE and I'm very proud of this nomination. I've recently relocated in London, UK.So, I think that 2011 year was not so bad for me.

I have some resolutions on next 2012 year:
- I have to find a job
- I have to write at least 12 technical articles (some of them in English of course).
- Participate at some Events.

But I forgot about people how is reading this blog. Friends, I want to wish you all the best in the New Year.
Happy New Year!!!

Best regards,
Gena

Official TimesTen blog

I've found very interesting message from Chris Jenkins on TimesTen forum.

"One of my colleagues here at Oracle has started a TimesTen blog. He is one of the architects in the development team and has been working on TimesTen even longer than I have (around 15 years now I believe). I recommend anyone interested in TimesTen to pay it a visit. If anyone has requests for articles on specific topics, please let us know.

The blog can be found here: http://blogs.oracle.com/timesten/

Chris"

Actually it is a great news. Sam works in TimesTen development team at Oracle. I know it because he helped me sometimes with my "tricky questions". Now, Sam Drake has official TimesTen blog and I advice you visit it.

TimesTen video (High Load conference)

 
Решил выложить видео с конференции High Load, на которой я и Игорь Мельников выступали два раза. На данной презентации я рассказываю о TimesTen, а Игорь показываем Демо. Демо было настолько внушительным, что монитор не выдержал :))), но думаю мы сумели выкрутиться из положения.

PS. Скучаю по работе.

OOW 2011. Exalytics

На ежегодной конференции Oracle Open World, был анонсирован Exalytics (Oracle Exalytics Business Intelligence Machine) - программно аппаратный комплекс предназначенный для аналитики. Подробную информацию можно посмотреть здесь.

Я очень ждал данного анонса, т.к. составной частью данного комплекса является TimesTen. На прошедшем мероприятии, посвященном альтернативным источникам данным для Oracle BI, я со своими коллегами показывал, как именно можно использовать TimesTen для бизнес аналитики.
Кроме того, в данном комплексе будет использоваться новая возможность TimesTen, а именно - columnar compression. В общем, очень интересно "потрогать" данный комплекс руками, особенно интересует In-Memory MOLAP.

My last day in Oracle CIS

Сегодня мой последний день в Oracle CIS.

Я очень рад, что мне довелось работать с такими профессионалами, как
Андрей Пивоваров, Игорь Мельников, Сергей Иванович Томин, Марк Ривкин, Андрей Забелин, Саша Рындин, Вадим Гусев, Дмитрий Севостьянов, Ольга Горчинская, в общем, я могу очень долго перечислять весь Российский PreSales департамент. Также, благодаря работе в Oracle, я познакомился с огромным количеством гуру (Женя Горбоконенко, Андрей Криушин, Дмитрий Безруков, Валерий Юринский, Harald van Breederode, Chris Jenkins, Tim Vincent и многими другими), отличными продавцами (Катя Кобер, Марина Тищенко, Алексей Лапиров и т.д.) и другими уникальными личностями в Российском представительстве Oracle и вообще в Oracle Community. Я получил неоценимый опыт и очень сожалею, что мне пришлось покинуть компанию.

PS. Я переезжаю в Лондон и надеюсь найти там работу и продолжить то, чем я занимался в прекрасной компании Oracle

PPS. Фото взято здесь (http://dreamvoyage.ru/blog/2007-11-03-100)

OFF: Oracle Database 10g: Real Application Clusters Administrator Certified Expert

На днях, сдал 1z0-048. Общие впечатления.
Сам экзамен не очень сложный, учитывая даже то, что смысл некоторых вопросов я не понял :)). Вопросы про CRS показались гораздо легче чем по функционалу RAC, ну в общем, заветные 60% по каждой из секций я набрал.

PS. На фото, почти high end storage, сделанный собственными руками. Собрал это чудо, как вы понимаете, мастер на все руки - Игорь Мельников

Перенос PL/SQL в TimesTen и ttSrcScan


В версии 11g, TimesTen стал поддерживать PL/SQL, а точнее, движок PL/SQL Oracle Database 11g, был портирован в TimesTen, т.е., теперь, приложения, использующие PL/SQL могут работать и в TimesTen. Но, вы прекрасно понимаете, что TtimesTen не поддерживает ВСЕГО функционала Oracle Database, например нет триггеров, нельзя создавать типы (CREATE TYPE) и т.д. Кроме того, как показывает практика, приложения содержат огромное количество кода (сотни тысяч или миллионы строк) и анализ кода на проверку работоспособности в TimesTen может занять огромное количество времени, поэтому разработчики создали специальную утилиту (ttSrcScan), которая должна автоматизировать данный процесс.

Данная утилита доступна после установки TimesTen 11.2.1 в каталоге $TIMESTEN_HOME/quickstart/sample_util (правда нужно не забыть поставить quickstart), но если не хочется ставить лишнее программное обеспечение, то можно обратиться в Oracle и получить ее отдельно.

Итак, данная утилита принимает на вход директории в которых содержатся файлы с кодом и анализирует их, после чего выдает отчеты (HTML и текстовый) об обнаруженных ошибках. Очень удобная утилита, но, конечно существует ряд нюансов.
Например, попробуем создать пакет.

create or replace package test_1 as

  procedure p_test;

end test_1;
/
create or replace package body test_1 as

  procedure p_test
  is
     v_rec number (10);  
  begin
    for v_rec in ( select level from dual connect by level <=10 ) loop
      dbms_output.put_line ('1');
    end loop;
  end p_test;   
end test_1;
/
Т.е. я явно указываю SQL конструкцию, которую TimesTen не поддерживает.
Command> select level from dual connect by level <=10;
 1001: Syntax error in SQL statement before or at: "by", character position: 32
select level from dual connect by level <=10
                               ^^
The command failed.
Command>
Проверим данный пакет с помощью ttSrcScan.
[oracle@tt1 ~]$ cd /u01/app/oracle/product/11.2.1.8/TimesTen/tt2/quickstart/sample_util/
[oracle@tt1 sample_util]$ ./ttSrcScan -i /home/oracle/source -o /home/oracle/result


  ***************************************
  * Oracle TimesTen Source Code Scanner *
  ***************************************

  Options used:
  =============
  -input           = /home/oracle/source
  -output          = /home/oracle/result
  -nestedDir       = TRUE
  -version         = 11.2.1.8.0
  -summaryPrefix   = ttSrcScan
  -maxRows         = 15


  Summary Statistics:
  ===================

  Files Processed:
  Input files and sub-directories processed :         1
  Sub-directories processed                 :         0
  Unsupported file types                    :         0
  Files Scanned                             :         1

  Files Scanned:
  Scanned files with no source code issues  :         1
  Scanned files with source code issues     :         0

  Lines Of Code Scanned:
  Lines of code                             :        19
  Lines of code with issues                 :         0
  Percentage of lines of code with issues   :         0.00%


  Detail Statistics:
  ==================
  Summary Report           /home/oracle/result/ttSrcScan_summary.html
  Files Processed Report   /home/oracle/result/ttSrcScan_all_input_files.html
  Files With Issues Report /home/oracle/result/ttSrcScan_issue_files.html
  Log File                 /home/oracle/result/ttSrcScan_log_file.log


[oracle@tt1 sample_util]$
Следовательно, ошибок нет. Скомпилируем данный пакет в TimesTen.

Command> create or replace package test_1 as
       >
       >   procedure p_test;
       >
       > end test_1;
       > /

Package created.

Command> create or replace package body test_1 as
       >
       >   procedure p_test
       >   is
       >      v_rec number (10);
       >   begin
       >     for v_rec in ( select level from dual connect by level <=10 ) loop
       >       dbms_output.put_line ('1');
       >     end loop;
       >   end p_test;
       >
       > end test_1;
       > /

Package body created.


Что удивительно, здесь также ошибок нет и только при выполнении получаем

Command> exec test_1.p_test;
 1001: Syntax error in SQL statement before or at: "BY", character position: 32
SELECT LEVEL FROM DUAL CONNECT BY LEVEL <=10
                               ^^
 8507: ORA-06512: at "ORACLE.TEST_1", line 7
 8507: ORA-06512: at line 1
The command failed.
Command>
Следовательно, ошибки, связанные с неподдерживаемыми SQL операторами, получим только в runtime, это нужно учитывать. Кроме того, TimesTen поддерживает работу с некоторыми системными пакетыми (UTL_FILE, DBMS_LOCK и др.), полный список можно посмотреть в документации. Но, содержание пакетов может быть разным. Например:
Command> # TimesTen
Command> desc dbms_lock
       > ;

Package SYS.DBMS_LOCK:

  Procedure SLEEP:
    Arguments:
      SECONDS                         IN     NUMBER

1 PL/SQL object found.
и Oracle Database.
SQL> desc dbms_lock;

PROCEDURE ALLOCATE_UNIQUE

FUNCTION CONVERT RETURNS NUMBER(38)

FUNCTION CONVERT RETURNS NUMBER(38)

FUNCTION RELEASE RETURNS NUMBER(38)

FUNCTION RELEASE RETURNS NUMBER(38)

FUNCTION REQUEST RETURNS NUMBER(38)

FUNCTION REQUEST RETURNS NUMBER(38)

PROCEDURE SLEEP
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 SECONDS                        NUMBER                  IN

Поэтому, при анализе кода, ttSrcScan добавляет строки содержащие системные пакеты, как "потенциально ошибочные". Например, проанализируем данный код:
create or replace package test_1 as

  procedure p_test;

end test_1;
/
create or replace package body test_1 as

  procedure p_test
  is
  begin
    dbms_lock.sleep(10);
  end p_test;

end test_1;
/
[oracle@tt1 sample_util]$ ./ttSrcScan -i /home/oracle/source -o /home/oracle/result


  ***************************************
  * Oracle TimesTen Source Code Scanner *
  ***************************************

  Options used:
  =============
  -input           = /home/oracle/source
  -output          = /home/oracle/result
  -nestedDir       = TRUE
  -version         = 11.2.1.8.0
  -summaryPrefix   = ttSrcScan
  -maxRows         = 15


  Summary Statistics:
  ===================

  Files Processed:
  Input files and sub-directories processed :         1
  Sub-directories processed                 :         0
  Unsupported file types                    :         0
  Files Scanned                             :         1

  Files Scanned:
  Scanned files with no source code issues  :         0
  Scanned files with source code issues     :         1

  Lines Of Code Scanned:
  Lines of code                             :        16
  Lines of code with issues                 :         1
  Percentage of lines of code with issues   :         6.25%


  Detail Statistics:
  ==================
  Summary Report           /home/oracle/result/ttSrcScan_summary.html
  Files Processed Report   /home/oracle/result/ttSrcScan_all_input_files.html
  Files With Issues Report /home/oracle/result/ttSrcScan_issue_files.html
  Log File                 /home/oracle/result/ttSrcScan_log_file.log


[oracle@tt1 sample_util]$ 
 
А в файле test.sql__source_issues.html видим.


Собственно, нужно также быть очень осторожным при переносе системных пакетов.

Конечно, данная утилита имеет свои ограничения, но все же она позволяет очень быстро проверить основные конструкции кода. Игорь Мельников обещал написать (если будет время конечно :) ) свою утилиту ttChecker, аналогичную RacChecker.

Семинар для партнеров по TimesTen

12 сентября, то есть уже в ближайший понедельник, в офисе Oracle состоится семинар для партнеров. Основная тема – Oracle TimesTen и In-Memory Database Cache. Вести семинар буду я :), так что welcome.
  • За дополнительной информацией по семинару, просьба обращаться в Представительство корпорации Oracle к Елизавете Матвеевой по тел. +7 (495) 795 2276 или по электронной почте: elizaveta.x.matveeva@oracle.com
  • По вопросам регистрации, просьба обращаться в Представительство корпорации Oracle к Валерии Хоменковой по тел. +7 (495) 641 1569 или по электронной почте: valeria.khomenkova@oracle.com

Установка Enterprise Manager Grid Control 11G

Решил я на днях установить EM GC 11g. Скачав дисрибутив EM GC 11g с OTN, я начал установку. Устанавливать буду как всегда на хост OVM. В качестве гостевой ОС - OEL 5.5 x86.

Начнем с prerequisites, благо Hardware и Operating System Requirements соблюдены. 
Теперь проверим Package Requirements.

[root@em ~]# rpm -qa | grep rng-utils
rng-utils-2.0-1.14.1.fc6
[root@em ~]# rpm -qa | grep make-3.81
make-3.81-3.el5
[root@em ~]# rpm -qa | grep binutils-2.17.50.0.6
binutils-2.17.50.0.6-14.el5
[root@em ~]# rpm -qa | grep libaio-0.3.106
libaio-0.3.106-5
[root@em ~]# rpm -qa | grep glibc-common
glibc-common-2.5-49
[root@em ~]# rpm -qa | grep gcc-4
libgcc-4.1.2-48.el5
gcc-4.1.2-48.el5
[root@em ~]# rpm -qa | grep compat-libstdc
compat-libstdc++-33-3.2.3-61
compat-libstdc++-296-2.96-138
[root@em ~]# rpm -qa | grep libstdc
compat-libstdc++-33-3.2.3-61
libstdc++-devel-4.1.2-48.el5
compat-libstdc++-296-2.96-138
libstdc++-4.1.2-48.el5
[root@em ~]# rpm -qa | grep libstdc++-devel
libstdc++-devel-4.1.2-48.el5
[root@em ~]# rpm -qa | grep setarch
setarch-2.0-1.1
[root@em ~]# rpm -qa | grep sysstat
sysstat-7.0.2-3.el5
[root@em ~]# rpm -qa | grep compat-db
compat-db-4.2.52-5.1

Как видно, все необходимые пакеты установлены. Далее проверим Operating System Groups and Users Requirements.

[oracle@em ~]$ id
uid=500(oracle) gid=501(oinstall) groups=500(dba),501(oinstall),502(oper)

Далее, проверим Unique Host Name and Static IP Address Requirements.
Главное использовать статический IP адресс, иначе, установить софт не получится.

[root@em ~]# ifconfig
eth0      Link encap:Ethernet  HWaddr 00:16:3E:48:36:E1
          inet addr:192.168.2.100  Bcast:192.168.2.255  Mask:255.255.255.0
          inet6 addr: fe80::216:3eff:fe48:36e1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:579 errors:0 dropped:0 overruns:0 frame:0
          TX packets:103 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:49210 (48.0 KiB)  TX bytes:14149 (13.8 KiB)
...
[root@em ~]# hostname
em
[root@em ~]# ping em
PING em.us.oracle.com (192.168.2.100) 56(84) bytes of data.
64 bytes from em.us.oracle.com (192.168.2.100): icmp_seq=1 ttl=64 time=0.017 ms
64 bytes from em.us.oracle.com (192.168.2.100): icmp_seq=2 ttl=64 time=0.009 ms
...

Далее, UMASK Value и File Descriptor Requirements. Добавляем в .bash_profile строку с umask 022.

[oracle@em ~]$ /bin/sh -c "ulimit -n"
131072

Далее, JDK Requirements. Я использую OEL х86, поэтому отдельно устанавливать JDK не нужно (дистрибутив WLS содержит JDK). Но если вы планируете устанавливать на другие ОС, то нужно иметь в виду, что может потребоваться поставить отдельно JDK.

На этом проверка хоста закончена. Теперь приступим к установке Oracle WebLogic Server.

Установка OWLS хорошо описана в note 1063762.1.
Скачиваем дистрибутив WLS 10.3.2. и запускаем установку.

[oracle@em ~]$ chmod a+x wls1032_linux32.bin
[oracle@em ~]$ ls -l
total 4713056
-rw-r--r-- 1 oracle oinstall 1346829079 Aug 15 08:08 GridControl_11.1.0.1.0_Linux_1of3.zip
-rw-r--r-- 1 oracle oinstall 1504566656 Aug 16 15:12 GridControl_11.1.0.1.0_Linux_2of3.zip
-rw-r--r-- 1 oracle oinstall 1336577721 Aug 16 15:08 GridControl_11.1.0.1.0_Linux_3of3.zip
-rwxr-xr-x 1 oracle oinstall  633454825 Aug 18 09:12 wls1032_linux32.bin
[oracle@em ~]$ ./wls1032_linux32.bin
Extracting 0%....................................................................................................100%

ВАЖНО. Перед установкой убедитесь, что у вас правильно прописан /etc/hosts. А именно, нет задвоений записей и шаблон следующий:

127.0.0.1 localhost.localdomain localhost 
<ip address> <fqdn> <short name> 
В противном случае - BUG 11821959, решение в note 1302190.1.

Мой /etc/hosts

[root@em ~]# cat /etc/hosts
127.0.0.1 localhost.localdomain localhost
192.168.2.100 em.us.oracle.com em
[root@em ~]#

Вернемся к установке.

Нажимаем next.


Выбираем Middleware хоум и нажимаем Next.


Вводим имя пользователя и пароль для доступа на support.oracle.com. Или отказываемся от этого (в моем случае).


Обязательно нужно выбрать Typical и опять next.


Выбираем WLS хоум и нажимаем Next.


Нажимаем Next.


Процесс установки.


Установка WLS закончена.

Далее необходимо установить патч на WLS (note 1072763.1). Скачиваем Patch WDJ7. Копируем его в middleware_home/utils/bsu/cache_dir и устанавливаем его с помощью bsu.

[oracle@em cache_dir]$ unzip WDJ7.zip
Archive:  WDJ7.zip
  inflating: 4D53.jar
  inflating: NIXN.jar
  inflating: patch-catalog.xml
  inflating: prod-info.xml
  inflating: WDJ7.jar
  inflating: XLXA.jar
[oracle@em cache_dir]$
[oracle@em ~]$ cd /u01/app/oracle/product/middleware/utils/bsu/
[oracle@em bsu]$ ./bsu.sh


Выбираем патч WDJ7 и нажимаем Apply.


На этом установка патча закончена. Также, необходимо убедиться, что в middleware_home/registry.xml прописан правильное имя хоста.

[oracle@em middleware]$ cat registry.xml | grep host 
 <host home="/u01/app/oracle/middleware" name="em">
 </host>
[oracle@em middleware]$

Теперь установим Oracle Database. Я не буду детально описывать процесс установки, я лишь опишу ряд требований.

1. Необходимо использование Partitioning
2. Необходимо удалить пользователя SYSMAN.

[oracle@em ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.2.0 Production on Tue Aug 23 10:40:44 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> SELECT COUNT(*) FROM ALL_USERS WHERE USERNAME='SYSMAN';

  COUNT(*)
----------
         1

SQL>  alter user sysman account unlock;

User altered.

SQL> alter user sysman identified by oracle;

User altered.

SQL> exit
[oracle@em ~]$ lsnrctl start

LSNRCTL for Linux: Version 11.2.0.2.0 - Production on 23-AUG-2011 10:47:53

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

Starting /u01/app/oracle/product/11.2.0/dbhome_1/bin/tnslsnr: please wait...

TNSLSNR for Linux: Version 11.2.0.2.0 - Production
Log messages written to /u01/app/oracle/diag/tnslsnr/em/listener/alert/log.xml
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=em)(PORT=1521)))

Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 11.2.0.2.0 - Production
Start Date                23-AUG-2011 10:47:53
Uptime                    0 days 0 hr. 0 min. 0 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Log File         /u01/app/oracle/diag/tnslsnr/em/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=em)(PORT=1521)))
The listener supports no services
The command completed successfully
[oracle@em ~]$
[oracle@em ~]$ $ORACLE_HOME/bin/emca -deconfig dbcontrol db -repos drop -SYS_PWD oracle -SYSMAN_PWD oracle

STARTED EMCA at Aug 23, 2011 10:48:19 AM
EM Configuration Assistant, Version 11.2.0.0.2 Production
Copyright (c) 2003, 2005, Oracle.  All rights reserved.

Enter the following information:
Database SID: em
Listener port number: 1521

----------------------------------------------------------------------
WARNING : While repository is dropped the database will be put in quiesce mode.
----------------------------------------------------------------------
Do you wish to continue? [yes(Y)/no(N)]: Y
Aug 23, 2011 10:48:27 AM oracle.sysman.emcp.EMConfig perform
INFO: This operation is being logged at /u01/app/oracle/cfgtoollogs/emca/em/emca_2011_08_23_10_48_19.log.
Aug 23, 2011 10:48:28 AM oracle.sysman.emcp.EMDBPreConfig performDeconfiguration
WARNING: EM is not configured for this database. No EM-specific actions can be performed. Some of the possible reasons may be:
 1) EM is configured with different hostname then physical host. Set environment variable ORACLE_HOSTNAME= and re-run EMCA script
 2) ORACLE_HOSTNAME is set. Unset it and re-run EMCA script
Aug 23, 2011 10:48:28 AM oracle.sysman.emcp.EMReposConfig invoke
INFO: Dropping the EM repository (this may take a while) ...
Aug 23, 2011 10:58:16 AM oracle.sysman.emcp.EMReposConfig invoke
INFO: Repository successfully dropped
Enterprise Manager configuration completed successfully
FINISHED EMCA at Aug 23, 2011 10:58:16 AM
[oracle@em ~]$

SQL> SELECT COUNT(*) FROM ALL_USERS WHERE USERNAME IN ('SYSMAN','SYSMAN_MDS');

  COUNT(*)
----------
         0

SQL> SELECT FILE_NAME FROM DBA_DATA_FILES WHERE UPPER (TABLESPACE_NAME) LIKE 'MGMT%';

no rows selected

SQL>

3. Fine-Grained Access Control Requirements
SQL> select value from v$option where parameter = 'Fine-grained access control';

VALUE
----------------------------------------------------------------
TRUE

SQL>

4. UNDO Tablespace Size Requirements

SQL> alter database datafile '/u02/em/undotbs01.dbf' resize 200M;

Database altered.

SQL>

5. База данных должна быть в режиме Archivelog.

SQL> select log_mode from v$database;

LOG_MODE
------------
ARCHIVELOG

SQL>

6. Инициализационные параметры

SQL> show parameter remote_login_passwordfile

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
remote_login_passwordfile            string      EXCLUSIVE
SQL>



SQL> show parameter statistics_level

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
statistics_level                     string      TYPICAL
SQL>

SQL> show parameter timed_statistics

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
timed_statistics                     boolean     TRUE
SQL>
SQL> show parameter undo_management

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
SQL>
SQL> show parameter workarea_size_policy

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
workarea_size_policy                 string      AUTO
SQL>
SQL> show parameter db_block_size

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_block_size                        integer     8192
SQL>
SQL> show parameter job_queue_processes

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
job_queue_processes                  integer     1000
SQL>
SQL> alter system set session_cached_cursors=200 scope=spfile;

System altered.

SQL> alter system set processes=500 scope=spfile;

System altered.

SQL> alter system set log_buffer=10485760 scope=spfile;

System altered.

SQL> show parameter db_dom

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_domain                            string      us.oracle.com

SQL> show parameter open_cursors

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
open_cursors                         integer     300
SQL>

Если параметры не удовлетворяют требованиям, при установке EM, вы получите сообщение об ошибке.

После этого, можно устанавливать EM GC. Запускаем runInstaller.

[oracle@em ~]$ ./runInstaller
Starting Oracle Universal Installer...

Checking Temp space: must be greater than 150 MB.   Actual 10504 MB    Passed
Checking swap space: must be greater than 150 MB.   Actual 3199 MB    Passed
Checking monitor: must be configured to display at least 256 colors.    Actual 65536    Passed
Preparing to launch Oracle Universal Installer from /tmp/OraInstall2011-08-29_10-16-08AM. Please wait ...


Вводим имя пользователя и пароль для доступа на support.oracle.com или отказываемся от этого (в моем случае).


Выбираем Skip и нажимаем Next.


Выбираем Install a new и нажимаем Next.


Нажимаем Next.


Оставляем все без изменений. Нажимаем Next.


Вводим пароли. Нажимаем Next.


Вводим атрибуты базы данных. Нажимаем Next.


Вводим пароль для пользователя SYSMAN. Нажимаем Next.


Вводим пароли и отключаем security агентов. Нажимаем Next.


Нажимаем Next.



Нажимаем Install.



Выполняем скрипт из под root.

[root@em ~]# /u01/app/oracle/middleware/oms11g/allroot.sh

Starting to execute allroot.sh .........

Starting to execute /u01/app/oracle/middleware/oms11g/root.sh ......
Running Oracle 11g root.sh script...

The following environment variables are set as:
    ORACLE_OWNER= oracle
    ORACLE_HOME=  /u01/app/oracle/middleware/oms11g

Enter the full pathname of the local bin directory: [/usr/local/bin]:
The file "dbhome" already exists in /usr/local/bin.  Overwrite it? (y/n)
[n]:
The file "oraenv" already exists in /usr/local/bin.  Overwrite it? (y/n)
[n]:
The file "coraenv" already exists in /usr/local/bin.  Overwrite it? (y/n)
[n]:

Entries will be added to the /etc/oratab file as needed by
Database Configuration Assistant when a database is created
Finished running generic part of root.sh script.
Now product-specific root actions will be performed.
Adding entry to /etc/oratab file...
Finished execution of  /u01/app/oracle/middleware/oms11g/root.sh ......


Starting to execute /u01/app/oracle/middleware/agent11g/root.sh ......
Running Oracle 11g root.sh script...

The following environment variables are set as:
    ORACLE_OWNER= oracle
    ORACLE_HOME=  /u01/app/oracle/middleware/agent11g

Enter the full pathname of the local bin directory: [/usr/local/bin]:
The file "dbhome" already exists in /usr/local/bin.  Overwrite it? (y/n)
[n]:
The file "oraenv" already exists in /usr/local/bin.  Overwrite it? (y/n)
[n]:
The file "coraenv" already exists in /usr/local/bin.  Overwrite it? (y/n)
[n]:

Entries will be added to the /etc/oratab file as needed by
Database Configuration Assistant when a database is created
Finished running generic part of root.sh script.
Now product-specific root actions will be performed.
Finished product-specific root actions.
Adding entry to /etc/oratab file...
Finished execution of  /u01/app/oracle/middleware/agent11g/root.sh ......
[root@em ~]#

Нажимаем Ok.



Соответственно, на данном этапе установка EM GC 11g завершена.

Проверим конфигурацию.

[oracle@em ~]$ echo $ORACLE_HOME
/u01/app/oracle/middleware/oms11g
[oracle@em ~]$ emctl status oms
Oracle Enterprise Manager 11g Release 1 Grid Control
Copyright (c) 1996, 2010 Oracle Corporation.  All rights reserved.
WebTier is Up
Oracle Management Server is Up
[oracle@em ~]$
[oracle@em ~]$ export ORACLE_HOME=$ORACLE_BASE/middleware/agent11g
[oracle@em ~]$ $ORACLE_HOME/bin/emctl status agent
Oracle Enterprise Manager 11g Release 1 Grid Control 11.1.0.1.0
Copyright (c) 1996, 2010 Oracle Corporation.  All rights reserved.
---------------------------------------------------------------
Agent Version     : 11.1.0.1.0
OMS Version       : 11.1.0.1.0
Protocol Version  : 11.1.0.0.0
Agent Home        : /u01/app/oracle/middleware/agent11g
Agent binaries    : /u01/app/oracle/middleware/agent11g
Agent Process ID  : 25152
Parent Process ID : 25135
Agent URL         : https://em.us.oracle.com:3872/emd/main/
Repository URL    : https://em.us.oracle.com:4900/em/upload
Started at        : 2011-08-29 12:54:42
Started by user   : oracle
Last Reload       : 2011-08-29 12:56:01
Last successful upload                       : 2011-08-29 13:12:37
Total Megabytes of XML files uploaded so far :    26.82
Number of XML files pending upload           :        0
Size of XML files pending upload(MB)         :     0.00
Available disk space on upload filesystem    :     9.78%
Last successful heartbeat to OMS             : 2011-08-29 13:12:49
---------------------------------------------------------------
Agent is Running and Ready
[oracle@em ~]$
[oracle@em ~]$ $ORACLE_HOME/bin/emctl upload
Oracle Enterprise Manager 11g Release 1 Grid Control 11.1.0.1.0
Copyright (c) 1996, 2010 Oracle Corporation.  All rights reserved.
---------------------------------------------------------------
EMD upload completed successfully
[oracle@em ~]$

Следовательно, конфигурация работает.

Заключение.
Установка Enterprise Manager Grid Control 11g заняла у меня совсем немного времени (по сравнению с RAC например). Также хочется отметить очень хорошую документацию по установке данного продукта - все очень подробно и с картинками. Единственное, что немного не удобно, так это то, что кроме дистрибутива EM, еще нужно скачивать дистрибутив WLS и дополнительный патч к нему, надеюсь в следующей версии Grid Control данный недостаток будет устранен.

Renaming tables in TimesTen

Недавно, на форуме получил вопрос от заказчика - как переименовать таблицу в TimesTen?
Первым делом, как настоящий пацан, я открыл документацию и не обнаружил команды 'alter table rename', следовательно, единственный способ переименовать таблицу - создать таблицу CTAS и после удалить старую.
Небольшой пример:
Command> create table my_all_source as select * from all_source;
7566 rows inserted.
Command> create table my_raname_tab as select * from my_all_source;
7566 rows inserted.
Command> drop table my_all_source;
Command> tables;
  ORATT.MY_RANAME_TAB
1 table found.
Command>

Ну это и дети знают. Но что происходит с констрайнтами, индексами при CTAS. Конечно они отсутствуют. Вопрос в том, как переименовать таблицу, и потом восстановить все констрэйнты и индексы.

Предположим у нас есть таблицы:

Command> create table tab1 (id number not null primary key, sum number);
Command> create table tab2 (id number not null primary key, name varchar2(50));
Command> create table tab_for_rename (id_1 number not null primary key, id_tab1 number, id_tab2 number);
Command> create table tab3 (id number not null primary key, id_tab_for_rename number);
Command> create table tab4 (id number not null primary key, id_tab_for_rename number);
Command> tables;
  ORATT.TAB1
  ORATT.TAB2
  ORATT.TAB3
  ORATT.TAB4
  ORATT.TAB_FOR_RENAME
5 tables found.
Command>

Необходимо переименовать таблицу tab_for_rename. Предположим, что в данной таблице существует первичный ключ, и несколько внешних ключей. Кроме того, предположим, что существуют таблицы (которые мы не знаем), которые ссылаются на первичный ключ tab_for_rename.

Command> ALTER TABLE tab_for_rename ADD FOREIGN KEY (id_tab1) REFERENCES tab1 (id);
Command> ALTER TABLE tab_for_rename ADD FOREIGN KEY (id_tab2) REFERENCES tab2 (id);
Command> ALTER TABLE tab3 ADD FOREIGN KEY (id_tab_for_rename) REFERENCES tab_for_rename (id_1);
Command> ALTER TABLE tab4 ADD FOREIGN KEY (id_tab_for_rename) REFERENCES tab_for_rename (id_1);
Command>

Заполним таблицы данными:

Command> insert into tab1 (id, sum) select rownum, rownum from all_source;
7566 rows inserted.
Command> insert into tab2 (id, name) select rownum, to_char(rownum) from all_source;
7566 rows inserted.
Command> insert into tab_for_rename (id_1, id_tab1, id_tab2) select rownum, rownum,rownum from all_source;
7566 rows inserted.
Command> insert into tab3 select rownum, rownum from all_source;
7566 rows inserted.
Command> insert into tab4 select rownum, rownum from all_source;
7566 rows inserted.
Command>

Вначале, создадим таблицу с новым именем.

Command> create table renamed_tab as select * from tab_for_rename;
7566 rows inserted.
Command> indexes renamed_tab;

Indexes on table ORATT.RENAMED_TAB:
  No indexes found.

0 indexes found on 1 table.
Command>

Теперь необходимо создать все констрэйнты и индексы.
Command> indexes TAB_FOR_RENAME;

Indexes on table ORATT.TAB_FOR_RENAME:
  TAB_FOR_RENAME: unique T-tree index on columns:
    ID_1
    (referenced by foreign key index TTFOREIGN_20 on table ORATT.TAB3)
    (referenced by foreign key index TTFOREIGN_21 on table ORATT.TAB4)
  TTFOREIGN_18: non-unique T-tree index on columns:
    ID_TAB1
    (foreign key index references table ORATT.TAB1(ID))
  TTFOREIGN_19: non-unique T-tree index on columns:
    ID_TAB2
    (foreign key index references table ORATT.TAB2(ID))
  3 indexes found.

3 indexes found on 1 table.
Command>

Следовательно, с помощью команды indexes, можно получить все необходимые данные для пересоздания всех индексов и констрэйнтов.

Пересоздадим их.

Command> ALTER TABLE renamed_tab ADD constraint new_pk Primary key (id_1);
Command> ALTER TABLE renamed_tab ADD FOREIGN KEY (id_tab1) REFERENCES tab1 (id);
Command> ALTER TABLE renamed_tab ADD FOREIGN KEY (id_tab2) REFERENCES tab2 (id);
Command> ALTER TABLE tab3 ADD FOREIGN KEY (id_tab_for_rename) REFERENCES renamed_tab (id_1);
Command> ALTER TABLE tab4 ADD FOREIGN KEY (id_tab_for_rename) REFERENCES renamed_tab (id_1);
Command>

После этого, наблюдаем удвоение индексов у таблиц tab1, tab2,tab3,tab4.

Command> indexes;

Indexes on table ORATT.RENAMED_TAB:
  NEW_PK: unique T-tree index on columns:
    ID_1
    (referenced by foreign key index TTFOREIGN_24 on table ORATT.TAB3)
    (referenced by foreign key index TTFOREIGN_25 on table ORATT.TAB4)
  TTFOREIGN_22: non-unique T-tree index on columns:
    ID_TAB1
    (foreign key index references table ORATT.TAB1(ID))
  TTFOREIGN_23: non-unique T-tree index on columns:
    ID_TAB2
    (foreign key index references table ORATT.TAB2(ID))
  3 indexes found.

Indexes on table ORATT.TAB1:
  TAB1: unique T-tree index on columns:
    ID
    (referenced by foreign key index TTFOREIGN_22 on table ORATT.RENAMED_TAB)
    (referenced by foreign key index TTFOREIGN_18 on table ORATT.TAB_FOR_RENAME)
  1 index found.

Indexes on table ORATT.TAB2:
  TAB2: unique T-tree index on columns:
    ID
    (referenced by foreign key index TTFOREIGN_23 on table ORATT.RENAMED_TAB)
    (referenced by foreign key index TTFOREIGN_19 on table ORATT.TAB_FOR_RENAME)
  1 index found.

Indexes on table ORATT.TAB3:
  TAB3: unique T-tree index on columns:
    ID
  TTFOREIGN_20: non-unique T-tree index on columns:
    ID_TAB_FOR_RENAME
    (foreign key index references table ORATT.TAB_FOR_RENAME(ID_1))
  TTFOREIGN_24: non-unique T-tree index on columns:
    ID_TAB_FOR_RENAME
    (foreign key index references table ORATT.RENAMED_TAB(ID_1))
  3 indexes found.

Indexes on table ORATT.TAB4:
  TAB4: unique T-tree index on columns:
    ID
  TTFOREIGN_21: non-unique T-tree index on columns:
    ID_TAB_FOR_RENAME
    (foreign key index references table ORATT.TAB_FOR_RENAME(ID_1))
  TTFOREIGN_25: non-unique T-tree index on columns:
    ID_TAB_FOR_RENAME
    (foreign key index references table ORATT.RENAMED_TAB(ID_1))
  3 indexes found.

Indexes on table ORATT.TAB_FOR_RENAME:
  TAB_FOR_RENAME: unique T-tree index on columns:
    ID_1
    (referenced by foreign key index TTFOREIGN_20 on table ORATT.TAB3)
    (referenced by foreign key index TTFOREIGN_21 on table ORATT.TAB4)
  TTFOREIGN_18: non-unique T-tree index on columns:
    ID_TAB1
    (foreign key index references table ORATT.TAB1(ID))
  TTFOREIGN_19: non-unique T-tree index on columns:
    ID_TAB2
    (foreign key index references table ORATT.TAB2(ID))
  3 indexes found.

14 indexes found on 6 tables.
Command>

Теперь удалим старую таблицу.

Command> ALTER TABLE tab3 DROP CONSTRAINT TTFOREIGN_20;
Command> ALTER TABLE tab4 DROP CONSTRAINT TTFOREIGN_21;
Command> drop table TAB_FOR_RENAME;
Command> indexes;

Indexes on table ORATT.RENAMED_TAB:
  NEW_PK: unique T-tree index on columns:
    ID_1
    (referenced by foreign key index TTFOREIGN_24 on table ORATT.TAB3)
    (referenced by foreign key index TTFOREIGN_25 on table ORATT.TAB4)
  TTFOREIGN_22: non-unique T-tree index on columns:
    ID_TAB1
    (foreign key index references table ORATT.TAB1(ID))
  TTFOREIGN_23: non-unique T-tree index on columns:
    ID_TAB2
    (foreign key index references table ORATT.TAB2(ID))
  3 indexes found.

Indexes on table ORATT.TAB1:
  TAB1: unique T-tree index on columns:
    ID
    (referenced by foreign key index TTFOREIGN_22 on table ORATT.RENAMED_TAB)
  1 index found.

Indexes on table ORATT.TAB2:
  TAB2: unique T-tree index on columns:
    ID
    (referenced by foreign key index TTFOREIGN_23 on table ORATT.RENAMED_TAB)
  1 index found.

Indexes on table ORATT.TAB3:
  TAB3: unique T-tree index on columns:
    ID
  TTFOREIGN_24: non-unique T-tree index on columns:
    ID_TAB_FOR_RENAME
    (foreign key index references table ORATT.RENAMED_TAB(ID_1))
  2 indexes found.

Indexes on table ORATT.TAB4:
  TAB4: unique T-tree index on columns:
    ID
  TTFOREIGN_25: non-unique T-tree index on columns:
    ID_TAB_FOR_RENAME
    (foreign key index references table ORATT.RENAMED_TAB(ID_1))
  2 indexes found.

9 indexes found on 5 tables.
Command>

Следовательно, переименовать таблицу в TimesTen не составляет большого труда, даже с учетом отсутствия команды 'alter table rename'. Правда, есть нюанс, т.к. новая таблица создается как CTAS, то в вашей базе данных должно быть достаточно места для хранения копии данных и индексов, поэтому данный метод применим не всегда.

Материализованные представления в Oralce TimesTen 11g

В Oracle TimesTen существует возможность создания материализованных представлений. Именно про данную возможность и пойдет речь далее. Согласно документации, в TimesTen существует два типа материализованных представлений: синхронные (Synchronous materialized view) и асинхронные (Asynchronous materialized view).

Синхронные материализованные представления

Синхронные материализованные представления существовали еще в версии 7.0.5. Они находятся постоянно в синхронном состоянии со всеми таблицами, на которые они ссылаются (detail tables). Это может сказываться на производительности, т.к. транзакция, меняющая таблицу, меняет и результат материализованного представления. Рассмотрим пример создания синхронного материализованного представления.

Триггеры в TimesTen (XLA application)

Иногда, заказчики задают вопрос относительно поддержки триггеров в TimesTen.
TimesTen поддерживает PL/SQL (процедуры, функции, пакеты и др.), но поддержка триггеров отсутствует, т.к. триггеры пагубно влияют на производительность. Но что делать, если необходимо реализовать триггерную логику?

Ответ - написать XLA приложение. Написать можно на С или Java, кому что ближе.
Ниже я буду описывать пример с использованием java :).

В документации (Java Developer's Guide) сказано:

"You can use the TimesTen JMS/XLA API (JMS/XLA) to monitor TimesTen for
changes to specified tables in a local data store and receive real-time notification of these changes. One of the purposes of JMS/XLA is to provide a high-performance, asynchronous alternative to triggers."

Т.е. вы можете написать java приложение, которое может использовать JMS/XLA API для получения сообщений (в асинхронном режиме) об изменениях в TimesTen. JMS/XLA использует JMS publish-subscribe interface для доступа к XLA изменениям. Подробнее про JMS можно почитать здесь (http://download.oracle.com/javaee/1.3/jms/tutorial).

Далее попробуем создать такое приложение.

Первоначально, создадим объекты в TimesTen.
[oracle@tt1 xla]$ ttisql dbxla

Copyright (c) 1996-2010, Oracle.  All rights reserved.
Type ? or "help" for help, type "exit" to quit ttIsql.

connect "DSN=dbxla";
Connection successful: DSN=dbxla;UID=oracle;DataStore=/u01/app/oracle/datastore/dbxla;DatabaseCharacterSet=WE8MSWIN1252;ConnectionCharacterSet=US7ASCII;DRIVER=/u01/app/oracle/product/11.2.1/TimesTen/tt1/lib/libtten.so;PermSize=32;TempSize=50;TypeMode=0;PLSQL=0;CacheGridEnable=0;
(Default setting AutoCommit=1)
Command> CREATE USER oratt IDENTIFIED BY oracle;

User created.

Command> grant create session, create table, XLA to oratt;
Command> connect "DSN=dbxla;UID=oratt;PWD=oracle;";
Connection successful: DSN=dbxla;UID=oratt;DataStore=/u01/app/oracle/datastore/dbxla;DatabaseCharacterSet=WE8MSWIN1252;ConnectionCharacterSet=US7ASCII;DRIVER=/u01/app/oracle/product/11.2.1/TimesTen/tt1/lib/libtten.so;PermSize=32;TempSize=50;TypeMode=0;PLSQL=0;CacheGridEnable=0;
(Default setting AutoCommit=1)
con1: Command> create table xlatest ( id   NUMBER NOT NULL PRIMARY KEY,
             >                        name VARCHAR2(100) );
con1: Command>

Теперь, создадим закладку (bookmark). XLA закладки используются для отметки позиции чтения в журналах транзакций. Данную закладку булем использовать для отслеживания изменений в таблице xlatest.
con1: Command> call ttXlaBookmarkCreate('bookmark');
con1: Command>

Далее, определим, изменения какой таблицы будем наблюдать. Для этого вызовем процедуру ttXlaSubscribe. В данном случае будем наблюдать за изменениями с таблицей xlatest с использованием закладки bookmark.
con1: Command> call ttXlaSubscribe('xlatest','bookmark');
con1: Command>

Далее, перейдем к настройке приложения.
Для соединения с XLA необходимо установить соединение с JMS Topic, который связан с опреденной базой данных TimesTen. Кофигурационный файл JMS/XLA обеспечивает привязку между именем топика и базой данных. По умолчанию, приложение ищет данный файл, названный jmsxla.xml, в текущей директории, но при желании можно определить другое имя и местоположение данного файла (см. документацию).

В данном случае я использую следующий файл jmsxla.xml:
<xlaconfig>
  <topics>

    <!-- topic for Xla demo -->
    <topic name="xlademo"
           connectionString="DSN=dbxla"
           xlaPrefetch="100"
    />

  </topics>
</xlaconfig>

Как видно, я связал имя топика xlademo с базой данных dbxla.

Теперь приступим, непосредственно, к написанию java Приложения.
Первоначально, инициализируем контекст.
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.timesten.dataserver.jmsxla.SimpleInitialContextFactory");
InitialContext ic = new InitialContext(env);

Далее, используем JMS connection factory для соединения с XLA. После чего, вызываем метод start() у соединения для активации отправки сообщений. После этого, используя данное соединение создаем сессию.
private javax.jms.TopicConnection connection; /** JMS connection */
private TopicSession session;  /** JMS session */
...
TopicConnectionFactory connectionFactory = (TopicConnectionFactory)ic.lookup("TopicConnectionFactory");
connection = connectionFactory.createTopicConnection();
...
// get Session
session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
...
Также при создании сессии необходимо указать транзакционность сессии и тип модели подтверждения (acknowledgment modes).
JMS/XLA поддерживается три модели (AUTO_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE, CLIENT_ACKNOWLEDGE), подробнее про модели можно почитать в документации. В примере я использую первую модель и транзакционность сессии устанавливаю в значение false.

Далее, необходимо определиться с режимом получения сообщений. Возможны два варианта: синхронный и асинхронный.

В синхронном варианте, сообщения обрабатываются последовательно (одно за другим). Это означает, что пока сообщение не обработано, другое ожидает.
Для синхронного варинта - вызываем метод start() у соединения, для активации отправки сообщений, создаем Topic, затем создаем подписчика и получаем сообщения с помощью методов receive() и receiveNoWait().

connection.start();
Topic topic = session.createTopic(topicName);     
TopicSubscriber subscriber = session.createDurableSubscriber(topic, bookmark);                 
..
MapMessage message = (MapMessage)subscriber.receive(); 
...

В асинхронном режиме необходимо создать листенер и в нем обрабатывать сообщения.

MyListener myListener = new MyListener(outStream);

Topic xlaTopic = session.createTopic(topic);
TopicSubscriber subscriber = session.createDurableSubscriber(xlaTopic, bookmark);
..
subscriber.setMessageListener(myListener);
connection.start();
..

Ниже представлен пример класса, реализующего синхронный режим (файл DemoXLA.java).
import java.util.Enumeration;
import java.util.Hashtable;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicConnection;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class DemoXLA {

    private TopicConnectionFactory connectionFactory;
    private TopicConnection connection;
    private TopicSession session;
    private Topic topic;
    private TopicSubscriber subscriber;

    public DemoXLA( String cf, 
                    String topicName, 
                    String selector) throws JMSException, NamingException {
        String key;
        Context messaging = getInitialContext(); // getting the context

 connectionFactory = (TopicConnectionFactory)messaging.lookup(cf);        
 connection = connectionFactory.createTopicConnection();
 connection.start();                        
 session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);                
        
 topic = session.createTopic(topicName);     
        subscriber = session.createDurableSubscriber(topic, selector);                 
        int i=0;
        while (i<10) {
            MapMessage message = (MapMessage)subscriber.receive();                        
            Enumeration e = message.getMapNames();

            while (e.hasMoreElements()) {
                key = (String)e.nextElement();
                System.out.println("[ " + key + " = " + message.getObject(key) + " ]");
            }
            System.out.println("----------------------------------------");                        
        }
        
        session.unsubscribe(selector);
        subscriber.close();
        session.close();
        connection.stop();
    }

    private Context getInitialContext() throws NamingException {
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.timesten.dataserver.jmsxla.SimpleInitialContextFactory");        
        InitialContext initialContext = new InitialContext(env);
        return initialContext;
    }

    public static void main(String[] args) throws JMSException, NamingException {
        DemoXLA demo = new DemoXLA("TopicConnectionFactory", "Level2Demo", "bookmark");
    }
}
Ниже представлен пример классов, реализующих асинхронный режим (MyListener.java, DemoXLA2.java). MyListener.java
import java.util.Enumeration;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;


public class MyListener implements MessageListener   {
    public MyListener() {}

    public void onMessage(Message message) {
        MapMessage mp = (MapMessage)message;
        Enumeration e;
        try {
            e = mp.getMapNames();
        } catch (JMSException s) {
            e = null;
            System.out.println("error 1");
        }
        while (e.hasMoreElements()) {
            String key = (String)e.nextElement();
            try {
                System.out.println("[ " + key + " = " + mp.getObject(key) + " ]");
            } catch (JMSException f) {
                System.out.println("error 2");
            }
        }
        System.out.println("----------------------------------------");
    }
}
DemoXLA2.java
import java.util.Hashtable;
import javax.jms.JMSException;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class DemoXLA2 {

    private javax.jms.TopicConnectionFactory connectionFactory;
    private javax.jms.TopicConnection connection;
    private TopicSession session;
    private Topic topic;
    private TopicSubscriber subscriber;

    public DemoXLA2( String cf,
                    String topicName,
                    String selector) throws JMSException, NamingException, InterruptedException {

        Context messaging = getInitialContext();
        Object connectionFactoryObject = messaging.lookup(cf);
        connectionFactory = (TopicConnectionFactory)connectionFactoryObject;
        connection = connectionFactory.createTopicConnection();

        MyListener myListener = new MyListener();
        session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
        topic = session.createTopic(topicName);
        subscriber = session.createDurableSubscriber(topic, selector); 
 
subscriber.setMessageListener(myListener);
        connection.start();
        Thread.sleep(60000);

        session.unsubscribe(selector);
        subscriber.close();
        session.close();
        connection.stop();
    }

    private Context getInitialContext() throws NamingException {
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.timesten.dataserver.jmsxla.SimpleInitialContextFactory");
        InitialContext initialContext = new InitialContext(env);
        return initialContext;
    }


    public static void main(String[] args) throws JMSException,
                                                  NamingException,
                                                  InterruptedException {
        DemoXLA2 demo = new DemoXLA2("TopicConnectionFactory", "xlademo", "bookmark");

    }

}
Далее, запускаем любой из примеров и попытаемся внести, изменить и удалить данные из таблицы xlatest.
Command> insert into xlatest values (2, 'w');
1 row inserted.
Command> update xlatest set name = 'test' where id=2;
1 row updated.
Command> delete from xlatest;
1 row deleted.
Command>
Соответственно, в приложении получаем:
[ __TYPE = 10 ]
[ __COMMIT = true ]
[ __FIRST = true ]
[ __NULLS =  ]
[ __TBLNAME = XLATEST ]
[ __TBLOWNER = ORATT ]
[ __mver = 5621355056449191939 ]
[ __mtyp = null ]
[ ID = 2 ]
[ NAME = w ]
----------------------------------------
[ __TYPE = 11 ]
[ __COMMIT = true ]
[ __FIRST = true ]
[ __UPDCOLS = NAME ]
[ __NULLS =  ]
[ __TBLNAME = XLATEST ]
[ __TBLOWNER = ORATT ]
[ __mver = 5621355056449191942 ]
[ __mtyp = null ]
[ _ID = 2 ]
[ ID = 2 ]
[ _NAME = w ]
[ NAME = test ]
----------------------------------------
[ __TYPE = 12 ]
[ __COMMIT = true ]
[ __FIRST = true ]
[ __NULLS =  ]
[ __TBLNAME = XLATEST ]
[ __TBLOWNER = ORATT ]
[ __mver = 5621355056449191945 ]
[ __mtyp = D ]
[ ID = 2 ]
[ NAME = test ]
----------------------------------------

Как видно, мы получили сообщения о прошедших с таблицей xlatest операциях.
Сообщения имеют следующий формат:
Системные атрибуты начинаются с двойного подчеркивания, например:
__TYPE - тип операции (Insert (10), Update(11), Delete(12)) также возможны другие типы (см. документацию). Для определения типа операции присутствуют константы.
__COMMIT - сигнализирует об завершении транзакции (если true).
__FIRST - сигнализирует о первой операции в транзакции (если true).
__TBLNAME - имя таблицы
__TBLOWNER - владелец таблицы
__NULLS - сигнализирует об атрибутах, в которых содержется значение null
__mver и __mtyp - системные атрибуты.
и т.д. (см. документацию)
Атрибуты без подчеркивания - колонки таблиц, имеющие определенные значения, например:
[ ID = 2 ]
[ NAME = test ]
Атрибуты начинающиеся на одно подчеркивание - старые значения полей (появляются при операции Update), например:
[ _ID = 2 ]
[ ID = 2 ]
[ _NAME = w ]
[ NAME = test ]

Итог

Следовательно, имея достаточно поверхностные знания по java, можно написать XLA приложение, которое может обрабатывать различные сообщения, полученнные из TimesTen. Кроме того, XLA приложение работает в асинхронном режиме, что практически не влияет на производительность Oracle TimesTen.

Доступ ко всем данным из TimesTen (Passthrough=1)

Недавно ко мне обратился заказчик с задачей:
существуют "огромные партиционированные таблицы (терабайты данных), к части из которых идет частое обращение. Возможно ли чтобы из ТТ были доступны определенные партиции, а остальные брались из оракла по тому же подключению ТТ".

Попробуем решить данную задачу.

Предположим у насть есть партицированная таблица в Oracle Database.

[oracle@tt1 cache_article]$ sqlplus oratt/oracle@orcl

SQL*Plus: Release 11.1.0.7.0 - Production on Tue May 24 09:22:15 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 table accounts (
  2  Id number,
  3  Name varchar2 (50),
  4  Surname varchar2(50),
  5  constraint accounts_pk primary key (id)
  6      using index (create unique index account_pk_idx on accounts(id))
  7  )
  8  partition by range (id) (
  9  partition part1 values less than (1000),
 10  partition part2 values less than (2000),
 11  partition part3 values less than (3000)
 12  );

Table created.

SQL> begin
2  for i in 1 .. 100 loop
3    insert into accounts values (i, 'Pit'||i, 'Jounes'||i);
4  end loop;
5 end;
6/
  
PL/SQL procedure successfully completed.

SQL> begin
2  for i in 1001 .. 1100 loop
3    insert into accounts values (i, 'Pit'||i, 'Jounes'||i);
4  end loop;
5 end;
6/
  
PL/SQL procedure successfully completed.

SQL> begin
2  for i in 2001 .. 2100 loop
3    insert into accounts values (i, 'Pit'||i, 'Jounes'||i);
4  end loop;
5 end;
6/
  
PL/SQL procedure successfully completed.

SQL> select count(*) from accounts;

  COUNT(*)
----------
       300

SQL> grant select on accounts to cacheadmin;

Grant succeeded.


Предположим, что частое обращение происходит к первой партиции, т.е. будем кэшировать первую партицию (ограничим ее условием where в определении кэш группы).

Command> CREATE READONLY CACHE GROUP read_cg
       >   AUTOREFRESH INTERVAL 5 SECONDS
       > FROM oratt.accounts (   Id number not null primary key,
       >                       Name varchar2 (50),
       >                    Surname varchar2(50)
       > ) where id <= 999;
Command> load cache group read_cg commit every 265 rows;
100 cache instances affected.


Но как получить данные из других партиций?
Для этого будем использовать параметр Passthrough.
Если данный параметр имеет значение 1, то каждый запрос, выполненный к несуществующим обектам в TimesTen будет перенаправлен в Oracle Database для исполнения.

Следовательно, создаем представление в Oracle Database, которое будет содержать данные из остальных партиций.

SQL> create view accounts_all as select * from accounts where id > 999;

View created.

SQL> grant select on accounts_all to cacheadmin;

Grant succeeded.


После чего можем иметь доступ ко всей информации через одно подключение (но, к сожалению, через разные таблицы).

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;CacheGridEnable=0;OracleNetServiceName=ORCL;
(Default setting AutoCommit=1)
Command> select count(*) from accounts;
< 100 >
1 row found.
Command> select count(*) from accounts_all;
 2206: Table ORATT.ACCOUNTS_ALL not found
The command failed.
Command> set autocommit 0;
Command> call ttOptSetFlag('PassThrough', 1);
Command> select count(*) from accounts_all;
< 200 >
1 row found.
Command>
Command> set showplan 1;
Command> select count(*) from accounts;

Query Optimizer Plan:

  STEP:                1
  LEVEL:               1
  OPERATION:           TblLkSerialScan
  TBLNAME:             ACCOUNTS
  IXNAME:              
  INDEXED CONDITION:   
  NOT INDEXED:         

< 100 >
1 row found.
Command>  select count(*) from accounts_all;

Query Optimizer Plan:

  STEP:                1
  LEVEL:               1
  OPERATION:           Oracle PassThrough
  TBLNAME:             
  IXNAME:              
  INDEXED CONDITION:   
  NOT INDEXED:         

< 200 >
1 row found.
Command>


Следовательно, получили доступ ко всей таблице Accounts через одно подключение в Oracle TimesTen.

Igor Melnikov's Blog!!!

I wrote about Russian Exadata-man - Igor Melnikov! 
And now he is starting the technical blog!
Welcome!!!

In-Memory Database Cache Grid

Ну вот я наконец то добрался до рассмотрения появившегося в TimesTen 11g функционала - In-Memory Database Cache Grid.
Начнем с настройки. В документации процесс создания 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 (об этом можно почитать здесь).


Tech: Настройка In-Memory Database Cache 11g

Давно я что-то не писал не чего технического (да и на русском :) ), вот и решил это исправить. Так как литературы по TimesTen мало, то я решил обновить статью Jonathan Gennick -а о кэшировании. В данном посте рассматривается возможность кэширования данных из Oracle Database в Oracle TimesTen.

Примечание: в данной статье не будет рассматриваться функциональность In-Memory Database Cache Grid, т.е. будет рассмотрена возможность создания только локальных кэш групп.

Используемое окружение (две виртуальные машины):
OEL 5.3 (x86) - Oracle Database EE 11.2.0.2.0 (Linux/x86), ip - 192.168.2.131 (hostname - db)
OEL 5.3 (x86) - Oracle TimesTen 11.2.1.7.0 (Linux/x86), ip - 192.168.2.132 (hostname - tt1)






Russian Exadata-man!

Update 1. The Igor Melnikov's presentation about loading data in Exadata, you can download here

On foto, my colleague Igor Melnikov. He is testing some application on Oracle Exadata V2-8 in Edinburgh now, and i think he is one of the first people in Russia, who can looking on this machine in real life :))

PS. Igor developed a very good method of loading a lot of data in Exadata (tens of terabytes) and tested it in Edinburgh. He promised, that he posted the presentation about it in blog.

Oracle TimesTen 11.2.1.8.0 is now available in OTN

New version Oracle TimesTen is now available on OTN.

I have written about "feature" Oracle TimesTen in Active-Standby pair configuration. In previous versions, if you wanted to add some abject (table, index and etc/) in your Active-Standby pair replication you had to restart your replication (stop, add your tables and start). It it not convenient, isn't it?
In 11.2.1.8.0 version you can create or drop a table, index or synonym in an active standby pair without stopping the replication agent. You can choose to have these statements replicated to the standby database. You can include a table in an active standby pair when the table is created. Use the DDLReplicationLevel and DDLReplicationAction connection attributes to control what is replicated.

More information you can find in documentation

PS. Foto - Santorini, Greece. I like this island :)).

Learning, learning and learning


Dear friends,

Yesterday, I graduated from second HIGHER EDUCATION!!!! 

URA!!!!!
URA!!!!!
URA!!!!!

PS. I got it with honors :)))))

TimesTen on YouTube

Very good video about TimesTen.