13 нояб. 2013 г.

Oracle Database 12c R1: новое в Edition Base Redefinition

В последнее время к мне, один за другим, обратилось уже три крупных российских ISV-разработчика приложений с вопросами по технологии Edition Base Redefinition [EBR]. Причем все они разрабатывают ПО для банков. Я думаю, что Вы поняли, чем вызван их интерес. Ведь каждое обновление приложения - это вынужденный простой для заказчика, что особенно болезненно для банковского сектора. Вообще говоря, минимизация плановых простоев - это важная задача в любой организации.






Технология версионирования PL/SQL-объектов Edition Base Redefinition появилась в Oracle Database версии 11.2. EBR позволяет проводить обновление приложения (вернее изменять код его хранимых процедур) "на лету", без остановки приложения. При этом, компиляция новой версии PL/SQL-объекта (пакета, объектного типа, функции или процедуры) производится в новой версии; работающие в этот момент пользователи НЕ получают исключение "ORA-04068 existing state of packages has been discarded", а продолжают работу с старой версией PL/SQL-кода.

Помимо чисто технических вопросов, главные вопросы, которые задавали мне представители этих компаний, звучали примерно так: "Есть ли примеры крупных внедрений этой технологии, что будет с этой технологией в дальнейшем, и можно ли воообще полагаться на нее?".

Что касается примеров использования этой технологии.
В сентябре этого года была выпущена новая версия ERP-системы от Oracle - Oracle E-Business Suite 12.2. Начиная с версии 12.2, процедура "наката" обновлений на Oracle EBS происходит без остановки, на уровне БД это достигается с помощью технологии EBR. Oracle EBS - это очень сложное приложение, которое содержит десятки тысяч таблиц и миллионы строк PL/SQL-кода. На мой взгляд, использование EBR в таком приложении, говорит о зрелости технологии. Конечно, поставщик технологии (то есть Oracle Corp.), а EBR не является готовым продуктом, а представляет собой базовую технологию, не использовал бы ее в своем основном приложении, если бы не был уверен в ее надежности и не имел бы планов по ее дальнейшему развитию.

Рис.1 Дистрибутив Oracle EBS 12.2 доступен на сайте edelivery.oracle.com

По поводу дальнейшего развития технологии EBR.
В недавно вышедшей СУБД Oracle Database 12c R1, технология EBR получила свое дальнейшее развитие - в ней появились очень полезные новые возможности. Давайте рассмотрим их более подробно.

1. Потенциальная версионируемость отдельного объекта, а не всех объектов схемы.
  1.1 В Oracle Database 11g версионируемость включается для всех объектов схемы

В версии Oracle Database 11.2 потенциальная версионируемость включалась на уровне всей схемы. То есть, когда Вам нужно было включить версионирование объектов, это производилось на уровне всей схемы:

[oracle@**** ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.3.0 Production on Sun Nov 1 12:50:56 2013

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


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

rem --Включаем возможность версионирования в схеме RSCOTT: в 11gR2 включается для всех объектов схемы!
SQL> ALTER USER rscott ENABLE EDITIONS;

User altered.
Таким образом, при помощи команды "ALTER USER <имя_схемы> ENABLE EDITIONS" версионируемость включалась для всех объектов схемы! Как Вы помните, неверсионируемый объект не может зависеть от версионируемого объекта. Если, например, мы создадим объектный тип PL/SQL в схеме, для которой включена потенциальная версионируемость, то мы не сможем создать таблицы с столбцом этого объектного типа (поскольку таблицы не версионируются!):
SQL> conn rscott/rtiger
Connected.
SQL> CREATE TYPE TMyType AS OBJECT
  2  (
  3    Id NUMBER(9)
  4  );
  5  /

Type created.

SQL> CREATE TABLE MyTable 
  2  ( 
  3    Id TMyType
  4  );
CREATE TABLE MyTable
*
ERROR at line 1:
ORA-38818: illegal reference to editioned object RSCOTT.TMYTYPE
В вышеприведенном примере объектный тип TMyType потенциально может иметь другие версии, поэтому невозможно использовать его в качестве типа для столбца таблицы, несмотря на то, что мы не собираемся иметь другие версии этого типа. Это происходит потому-что потенциальная версионируемость была включена для всех объектов схемы RSCOTT. По этой причине, кстати, в версии 11.2 нельзя было создавать очереди Advanced Queuing с типом из схемы для которой включено версионирование:
SQL> BEGIN
  dbms_aqadm.create_queue_table(queue_table        => 'MY_QUEUE',
                                queue_payload_type => 'TMyType');
END;
/

BEGIN
*
ERROR at line 1:
ORA-38818: illegal reference to editioned object RSCOTT.TMYTYPE
ORA-06512: at "SYS.DBMS_AQADM", line 81
ORA-06512: at line 2

Для решения вышеописанной проблемы, в Oracle Database 11.2 приходилось использовать обходной путь (workaround), заключающийся в выводе НЕверсионируемых объектов в отдельную схему, для которой версионируемость не включалась:
[oracle@**** ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.3.0 Production on Sun Nov 1 13:11:26 2013

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

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

rem -- Создаем отдельную схему для неверсионируемых объектов:
SQL> CREATE USER rscott_nonvers IDEBTIFIED BY rtiger_nonvers;

User created.

SQL> GRANT connect, resource, create synonym TO rscott_nonvers;

Grant succeeded.

rem --Создаем неверсионируем тип TMyType
SQL> CONN rscott_nonvers/rtiger_nonvers
Connected.

SQL> CREATE TYPE TMyType AS OBJECT
  2  (
  3    Id NUMBER(9)
  4  );
  5  /

Type created.

rem -- Не забываем дать права на этот тип пользователю RSCOTT
SQL> GRANT execute ON TMyType TO rscott; 

Grant succeeded.


SQL> CONN rscott/rtiger
Connected.
SQL> 
rem -- Для удобства создаем локальный синоним на тип TMyType в схеме RSCOTT_nonvers
SQL> CREATE SYNONYM TMyType FOR rscott_nonvers.TMyType;

Synonym created.
rem -- Наконец, успешно создаем таблицу c столбцом неверсионируемого типа TMyType!
SQL> CREATE TABLE MyTable
  2  (
  3    Id TMyType
  4  );

Table created.

SQL>   
  1.2 В Oracle Database 12с версионируемость включается для уровне объекта

Начиная с Oracle Database версии 12.1 в вышеприведенных дополнительных действиях нет необходимости, поскольку теперь потенциальная версионируемость PL/SQL-объекта может включаться для отдельного объекта. При создании PL/SQL-объекта указывается ключевое слово EDITIONABLE, если объект потенциально может версионироваться, NONEDITIONABLE - если объект не будет версионироваться:

[oracle@****]$ sqlplus rscott/rtiger

SQL*Plus: Release 12.1.0.1.0 Production on Mon Nov 2 11:09:43 2013

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

Last Successful login time: Mon Nov 02 2013 11:08:16 +04:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

SQL> 
rem -- Cоздаем неверсионируемый тип 
SQL> CREATE NONEDITIONABLE TYPE TMyType AS OBJECT
  2  (
  3    Id NUMBER(9)
  4  );
  5  /

Type created.
rem -- Cоздаем таблицу c столбцом неверсионируемого типа TMyType!
SQL> CREATE TABLE MyTable
  2  (
  3    Id TMyType
  4  );

Table created.
2. Ограничение версий для выражений вычисляемых столбцов в таблицах и материализованных представлениях
  2.1 Особенности использования виртуальных столбцов в Oracle Database 11g

Еще начиная с версии 11g Release 1, в СУБД Oracle появилась поддержка виртуальных столбцов, то есть столбцов, которые заданы вычисляемым выражением. В выражении виртуального столбца также могут участвовать хранимые PL/SQL-функции, как например в следующем случае:

[oracle@**** ~]$ sqlplus rscott/rtiger

SQL*Plus: Release 11.2.0.4.0 Production on Wed Nov 6 16:31:47 2013

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


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning and Real Application Testing options

SQL> CREATE OR REPLACE FUNCTION getMyId RETURN NUMBER 
  DETERMINISTIC IS
BEGIN
  RETURN 1;
END;
 /

Function created.

rem --создаем таблицу с виртуальным столбцом в выражении которого участвует PL/SQL-функция
SQL>  CREATE TABLE myTable
(      
  Id    NUMBER(9),
  MyId  as (getMyId())
);

Table created.
Обратите внимание, что нам удалось создать неверсионируемый объект (таблицу), который зависит от версионируемого объекта (PL/SQL-функции).
Поскольку значение виртуального столбца на диске не сохраняется, мы смогли это сделать!

Занесем одну строку в таблицу и проверим значение виртуального столбца:
SQL> INSERT INTO MyTable(Id) VALUES(0);

1 row created.

SQL> SELECT * FROM MyTable;

 ID  MYID
---------- ----------
  0     1

SQL> 
Как Вы наверно догадались, наc подстерегает одна очевидная опасность: при смене версии функции, виртуальный столбец изменит свое значение!
Например:
SQL> conn / as sysdba
Connected.

rem -- Создаем новую версию
SQL> CREATE EDITION MyVersion1 AS CHILD OF ORA$BASE;

Edition created.

SQL> GRANT USE ON EDITION MyVersion1 TO RSCOTT;

Grant succeeded.
Понятно, что если если наша функция getMyId изменит свое поведение в новой версии, то значение виртуального столбца будет зависеть от текущей версии в сессии пользователя:
SQL> conn rscott/rtiger
Connected.

SQL> ALTER SESSION SET EDITION=MyVersion1;

Session altered.

SQL> create or replace function getMyId return number 
  deterministic is
begin
  return 2;
end;
 /

Function created.

SQL> SELECT * FROM MyTable;

 ID  MYID
---------- ----------
  0     2

rem -- Переключаемся в старую версию:
SQL> ALTER SESSION SET EDITION=ORA$BASE;

Session altered.

SQL> SELECT * FROM MyTable;

 ID  MYID
---------- ----------
  0     1

SQL> 
  2.2 Определение доступных версий для виртуальных столбцов в Oracle Database 12c
Начиная с Oracle Database 12c для виртуальных столбцов можно задавать различные ограничения на используемые версии. С помощь модификатора EVALUATE USING CURRENT EDITION мы жестко фиксируем версию для виртуального столбца на версию, которая была в момент создания таблицы (либо в момент выдачи оператора ALTER TABLE):
[oracle@**** ~]$ sqlplus rscott/rtiger

SQL*Plus: Release 12.1.0.1.0 Production on Wed Nov 6 14:12:11 2013

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

Last Successful login time: Wed Nov 06 2013 14:07:51 -05:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Advanced Analytics and Real Application Testing options

SQL> CREATE TABLE myTable
(
  Id    NUMBER(9),
  MyId  as (getMyId()) EVALUATE USING CURRENT EDITION
);
 /
Table created.

SQL> INSERT INTO MyTable(Id) VALUES(0);

1 row created.

SQL> SELECT * FROM MyTable;

        ID       MYID
---------- ----------
         0          1

SQL> ALTER SESSION SET EDITION=MyVersion1;

Session altered.

SQL> SELECT * FROM MyTable;

        ID       MYID
---------- ----------
         0          1

SQL>

Как видите, несмотря на переключение версий, виртуальный столбец всегда использует версию которая была в момент выдачи DDL-оператора. Также мы можем явно указать используемую версию для виртуального столбца:
SQL> ALTER TABLE myTable MODIFY MyId as (getMyId())
  EVALUATE USING EDITION MyVersion1;
  /
Table altered.

SQL> ALTER SESSION SET EDITION=ORA$BASE;

Session altered.

SQL>  SELECT * FROM MyTable;

        ID       MYID
---------- ----------
         0          2

Если для виртуального столбца указать EVALUATE USING NULL EDITION, то поведение виртуального столбца будет как в Oracle 11gR2 - значение будет вычисляться в текущей версии в которой происходит обращение к столбцу. Это поведение будет работать по умолчанию, - если фраза EVALUATE USING для столбца не задана:
SQL> ALTER TABLE myTable MODIFY MyId as (getMyId())
  EVALUATE USING NULL EDITION;
/

Table altered.

Дополнительно, c помощью фразы UNUSABLE BEGINNING WITH указывается версия, начиная с которой в иерархии версий, будет запрещено использование виртуального столбца:

SQL> CREATE TABLE myTable
(
  Id    NUMBER(9),
  MyId  as (getMyId()) UNUSABLE BEGINNING WITH EDITION MyVersion1
);
  
Table created.

SQL> INSERT INTO myTable(Id) VALUES(1);

1 row created.

SQL> COMMIT;

Commit complete.

SQL> SELECT * FROM mytable;

        ID       MYID
---------- ----------
         1          1

SQL> ALTER SESSION SET EDITION=myversion1;

Session altered.

SQL> SELECT * FROM mytable;
 SELECT * FROM mytable
*
ERROR at line 1:
ORA-00904: "RSCOTT"."GETMYID": invalid identifier
Наоборот, c помощью фразы UNUSABLE BEFORE, можно указать версию, для всех родительских версий которой будет запрещено использование виртуального столбца.

  2.3 Поддержка версионированных PL/SQL-функций в материализованных представлениях в Oracle Database 12c

До Oracle Database 12c было запрещено использование версионированных PL/SQL-функций в материализованных представлениях:

[oracle@**** ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.3.0 Production on Sun Nov 11 15:02:16 2013

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


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

SQL> CREATE MATERIALIZED VIEW mymview AS
2  SELECT * FROM all_objects 
3  WHERE getMyId=1;


CREATE MATERIALIZED VIEW mymview AS
          *
ERROR at line 1:
ORA-38818: illegal reference to editioned object RSCOTT.GETMYID
Начиная с Oracle Database 12c стало возможным обращение к версионируемым PL/SQL-объектам внутри материализованного представления. Для этого необходимо при создании материализованного представления указать фразу EVALUATE USING ..., либо фразу UNUSABLE BEGINNING .... Назначение этих модификаторов установки версии для PL/SQL-вызовов внутри материализованных представлений, полностью совпадает с их назначением в рассмотренных ранее примерах версионированиия виртуальных столбцов:
[oracle@**** ~]$ sqlplus rscott/rtiger

SQL*Plus: Release 12.1.0.1.0 Production on Wed Nov 13 13:11:08 2013

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

Last Successful login time: Wed Nov 13 2013 13:07:37 -05:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Advanced Analytics and Real Application Testing options

SQL> CREATE MATERIALIZED VIEW mview
2 EVALUATE USING EDITION MyVersion1 AS
3 SELECT * FROM all_objects 
4 WHERE getmyid=1;


Materialized view created.

В вышерассмотренном примере, для вызова функции getMyId жестко устанавливается версия MyVersion1.
Как Вы могли заметить, установка версии действует на все PL/SQL-вызовы внутри материализованного представления: в вычисляемых столбцах, и в предикатах фразы WHERE.

  3 Версионирование для публичных синонимов (public synonym)

В Oracle Database 11g Release 2 (11.2) публичный синоним не мог ссылаться на версионируемый объект:

[oracle@**** ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.3.0 Production on Sun Nov 11 16:23:16 2013

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


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

SQL> CREATE PUBLIC SYNONYM getMyId FOR getMyId;

CREATE PUBLIC SYNONYM getMyId FOR getMyId;
*
ERROR at line 1:
ORA-38818: illegal reference to editioned object RSCOTT.GETMYID
В версии 12с эта проблема решена и теперь публичный синоним может версионироваться. Для создания версионируемого синонима при его создании необходимо указать ключевое слово EDITIONABLE
[oracle@**** ~]$ sqlplus rscott/rtiger

SQL*Plus: Release 12.1.0.1.0 Production on Wed Nov 13 13:54:07 2013

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

Last Successful login time: Wed Nov 13 2013 13:11:08 -05:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Advanced Analytics and Real Application Testing options

SQL> CREATE EDITIONABLE PUBLIC synonym getMyId FOR getMyId;

Synonym created.

  Заключение

В новейшей версии СУБД Oracle Database - 12c, технология обновления PL/SQL-кода без остановки - Edition Base Redefinition, получила свое дальнейшее развитие. Появились такие мощные возможности, как потенциальное версионирование на уровне отдельного объекта, версионирование виртуальных столбцов, версионирование кода в материализованных представлениях. Также следует отметить очень полезную новую возможность - версионирование публичных синонимов.