Oracle Database 12c R2: краткий предварительный обзор новых возможностей

Поделиться
Ссылка скопирована

Введение

На момент написания статьи официальный выпуск новой версии Oracle Database 12.2.0.1 еще не состоялся, но уже есть документация и возможность опробовать предварительную версию 12.2.0.1 RC4 от 14.09.2016 в живую в рамках курса Oracle University «Oracle Database 12c R2: New Features for 12c R1 Administrators». Здесь я поделюсь впечатлениями о том, что удалось опробовать и показалось наиболее интересным из этих возможностей.

Контейнерная архитектура

В 12c R2 контейнерная архитектура базы данных получила довольно существенное развитие. Если в 12c R1 удалось реализовать совместное использование компонент инфраструктуры (процессы, память, метаданные) между слабо связанными между собой базами данных, то в 12c R2 через контейнеры приложений появилась возможность совместного использования метаданных и общих данных приложений. С другой стороны появились новые инструменты распределения критичных ресурсов (память, ввод-вывод) между отдельными контейнерами. Архитектура начала приобретать свойство древовидности (с фиксированным количеством уровней).


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

SQL> CREATE PLUGGABLE DATABASE toys_root AS APPLICATION CONTAINER ADMIN USER admin IDENTIFIED BY oracle_4U ROLES=(CONNECT) CREATE_FILE_DEST='/u02/app/oracle/oradata/ORCL/toys_root';

Pluggable database created.

SQL> ALTER PLUGGABLE DATABASE toys_root OPEN;

 

Pluggable database altered.

Ключевым понятием данного слоя является понятие — Приложение:

·       приложения первоначально устанавливаются в корневые контейнеры приложений

·       обязательными атрибутами приложения являются его имя и версия

·       в рамках инсталляции создаются общие метаданные и данные приложения

·       приложения в рамках одного корневого контейнера приложений устанавливаются строго последовательно

·       в один контейнер можно разместить несколько приложений

·       при первом открытии корневого контейнера создается встроенное приложение с именем APP$GUID, где GUID — это глобальный идентификатор корневого контейнера приложений и для него создается дополнительное логическое имя (или алиас) APP$CON

SQL> SELECT STATEMENT_ID, CAPTURE_TIME, APP_STATEMENT, APP_NAME FROM DBA_APP_STATEMENTS ORDER BY APP_NAME,STATEMENT_ID;

 

STATEMENT_ID CAPTURE_T APP_STATEMENT                                                                    APP_NAME

------------ --------- -------------------------------------------------------------------------------- ----------

           1 18-DEC-16 SYS                                                                              APP$43EEE5

                                                                                                        DCD146115B

                                                                                                        E053AA7AA8

                                                                                                        C013FC

 

           2 18-DEC-16 ALTER PLUGGABLE DATABASE APPLICATION APP$CON BEGIN INSTALL '1.0'                 APP$43EEE5

                                                                                                        DCD146115B

                                                                                                        E053AA7AA8

                                                                                                        C013FC

 

           3 18-DEC-16 ALTER PLUGGABLE DATABASE APPLICATION APP$CON END INSTALL '1.0'                   APP$43EEE5

                                                                                                        DCD146115B

                                                                                                        E053AA7AA8

                                                                                                        C013FC

·       инсталляция приложения начинается с команды ALTER PLUGGABLE DATABASE APPLICATION name BEGIN INSTALL 'version'

·       после начала инсталляции приложения начинается захват SQL кода, который выполняется в корневом контейнере приложений в рамках одной или нескольких сессий (так по документации, а пробной версии 12.2.0.1 такой захват в рамках нескольких сессий производился некорректно). Кроме обычного SQL осуществляется захват сессий SQL*Loader. В дальнейшем этот код будет использован при синхронизации PDB приложений с корневым контейнером приложений. Поэтому необходимо, например, избегать указания полного имени файла при создании табличных пространств. При синхронизации будет попытка создания такого же табличного пространства с тем же самым именем файла и синхронизация окончится ошибкой. Посмотреть захваченный SQL код можно в представлении DBA_APP_STATEMENTS:

SQL> SELECT STATEMENT_ID, CAPTURE_TIME, APP_STATEMENT, APP_NAME FROM DBA_APP_STATEMENTS ORDER BY APP_NAME,STATEMENT_ID;

STATEMENT_ID CAPTURE_T APP_STATEMENT                                                                    APP_NAME

------------ --------- -------------------------------------------------------------------------------- ----------

           4 18-DEC-16 SYS                                                                              TOYS_APP

           5 18-DEC-16 ALTER PLUGGABLE DATABASE APPLICATION toys_app begin install '1.0'                TOYS_APP

           6 18-DEC-16 create user toys_owner identified by  VALUES 'S:99933694205B2A9B127C888C8A6A81EC TOYS_APP

           7 18-DEC-16 grant create session, dba to toys_owner container=all                            TOYS_APP

           8 18-DEC-16 create table toys_owner.sales_data sharing=metadata                              TOYS_APP

                       (year       number(4),

                        regi

 

           9 18-DEC-16 create table toys_owner.codes sharing=object                                     TOYS_APP

                       (code  number(4), label varchar2(10

 

          10 18-DEC-16 insert into toys_owner.codes values (1,'Puppet')                                 TOYS_APP

          11 18-DEC-16 insert into toys_owner.codes values (2,'Car')                                    TOYS_APP

          12 18-DEC-16 commit                                                                           TOYS_APP

          13 18-DEC-16 ALTER PLUGGABLE DATABASE APPLICATION toys_app end install '1.0'                  TOYS_APP

·       инсталляция приложения заканчивается с командой ALTER PLUGGABLE DATABASE APPLICATION name END INSTALL 'version'. По документации закончить инсталляцию можно в произвольной сессии к корневому контейнеру приложений. Но в пробной версии я натыкался на такое сообщение:

SQL> ALTER PLUGGABLE DATABASE APPLICATION toys_app END INSTALL '1.0';

ALTER PLUGGABLE DATABASE APPLICATION toys_app END INSTALL '1.0'

*

ERROR at line 1:

ORA-65328: cannot end an application action in the current session

·       если на момент инсталляции приложения уже существовали другие (не корневые) PDB приложений в этом контейнере, то для того чтобы общие метаданные и данные приложения стали видны в таких PDB, их нужно синхронизировать командой ALTER PLUGGABLE DATABASE APPLICATION … SYNC, подключившись к такой PDB. То же самое относится и к вновь создаваемым PDB при отсутствии в этом корневом контейнере специальной предзаполненной PDB, создаваемой с опцией AS SEED, либо если такая SEED PDB не была предварительно синхронизирована с корневым контейнером. При наличии  SEED PDB, другие  PDB в этом контейнере приложений создаются как ее клон. Встроенное приложение APP$CON можно синхронизировать, как и любое другое.

·       изменить приложение можно операцией Upgrade либо Patch. Разница между операциями состоит в наборе допустимых SQL команд в корневом контейнере после выполнения команды ALTER PLUGGABLE DATABASE APPLICATION … BEGIN [UPGRADE | PATCH]. Крупные изменения обычно оформляются как операция Upgrade, а более мелкие как Patch. При этом в рамках операции Patch недопустимы, например, разрушающие команды (DROP ..). Обе операции меняют версию приложения в корневом контейнере приложений.

·       после начала изменения приложения и до команды ALTER PLUGGABLE DATABASE APPLICATION … END [UPGRADE | PATCH] производится такой же захват SQL кода, как и при инсталляции приложения.

·       для обеспечения работоспособности существующих некорневых PDB автоматически создается клон корневого контейнера со старой версией приложения.

·       если при выполнении SQL кода явно не была начата ни одна из операций  Upgrade либо Patch, то считается что изменение относится к встроенному приложению APP$CON и оформляется как операция Patch для него. Может появится искушение не создавать свои приложения, а воспользоваться тем что есть по умолчанию. Но не всегда это может быть возможным — в APP$CON может быть захвачен код, который имеет смысл только для корневого контейнера приложений и оканчивающийся ошибкой в обычной PDB приложений. В примере ниже в APP$CON захвачена операция, которая может быть успешно выполнена (если только в этой PDB уже не был создан локальный пользователь с таким же именем) при синхронизации в любой PDB. Результатом синхронизации будет создание пользователя toys_test в синхронизируемой PDB.

SQL> SELECT STATEMENT_ID, CAPTURE_TIME, APP_STATEMENT, APP_NAME FROM DBA_APP_STATEMENTS ORDER BY APP_NAME,STATEMENT_ID;

 

STATEMENT_ID CAPTURE_T APP_STATEMENT                                                                    APP_NAME

------------ --------- -------------------------------------------------------------------------------- ----------

          21 18-DEC-16 SYS                                                                              APP$43EEE5

                                                                                                        DCD146115B

                                                                                                        E053AA7AA8

                                                                                                        C013FC

 

          22 18-DEC-16 ALTER PLUGGABLE DATABASE APPLICATION APP$CON BEGIN PATCH 1                       APP$43EEE5

                                                                                                        DCD146115B

                                                                                                        E053AA7AA8

                                                                                                        C013FC

 

          23 18-DEC-16 CREATE USER toys_test IDENTIFIED BY  VALUES 'S:54D4AEF3B2DA6B584A0E9C645AFA5320F APP$43EEE5

                                                                                                        DCD146115B

                                                                                                        E053AA7AA8

                                                                                                        C013FC

 

          24 18-DEC-16 ALTER PLUGGABLE DATABASE APPLICATION APP$CON END PATCH 1                         APP$43EEE5

                                                                                                        DCD146115B

                                                                                                        E053AA7AA8

                                                                                                        C013FC

·       для того чтобы остальные (в том числе и SEED) PDB могли использовать новую версию приложения, их необходимо синхронизировать с корневым контейнером приложений

Кроме пользователей, ролей, профилей и многие другие объекты базы данных, в том числе таблицы и PL/SQL код могут рассматриваться как общие для данного контейнера приложений и создаваться в рамках операций Install, Upgrade и Patch с разными значениями атрибута SHARING:

·       METADATA — метаданные такого объекта рассматриваются как общие (принадлежат корневому контейнеру приложений), но данные будут уникальны для каждой PDB (размещаются в них). Это является поведением по умолчанию

·       DATA — метаданные и данные такого объекта рассматриваются как общие и размещаются в корневом контейнере приложений, а остальные PDB видят эти метаданные и данные по ссылке

·       EXTENDED DATA — метаданные и часть данных принадлежат корневому контейнеру приложений, но каждая из PDB может иметь и собственную порцию данных

·       NONE — объект не используется совместно

Мне такая архитектурная конструкция стала напоминать объектную модель таких языков программирования, как Java. Осталось только допустить (сейчас запрещено) вложенность корневых контейнеров приложений друг в друга с возможностью наследования и переопределения метаданных, то мы фактически получили бы иерархию классов не ограниченную как сейчас тремя уровнями. Объекты, разделяемые в режиме DATA могли бы выступать в качестве в качестве статических элементов класса, METADATA как объектные элементы и т. д.

Еще одним вариантом использования контейнерных баз данных, является возможность расщепить большую таблицу на фрагменты и каждый фрагмент обрабатывать независимо от других в своей PDB. А с появлением возможности, которую предоставляют proxy PDB, то и разнести нагрузку по обработке данных на разные контейнерные СУБД, находящихся на разных хостах. Перемещение же PDB с одной контейнерной базы данных в другую контейнерную базу данных тоже в свою значительно упростилось и теперь может быть осуществлено практически без остановки обслуживания пользователей в этой PDB. И если раньше для создания запроса по набору PDB требовалось использование специального синтаксиса с конструкцией CONTAINERS(), то теперь с помощью контейнерных карт можно это сделать не меняя исходный код приложения.

Теперь обо всем по порядку:

·       Имеем 2 контейнерные базы данных: CDB1 и CDB2. Подключаемся к ним в разных сессиях и настраиваем SQLPROMPT для удобства:

[oracle@virt05-cdb1 ~]$ . oraenv

ORACLE_SID = [cdb2] ? cdb1

The Oracle base remains unchanged with value /u01/app/oracle

[oracle@virt05-cdb1 ~]$ sqlplus / as sysdba

SQL> set sqlprompt "CDB1> "

CDB1> show pdbs

 

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED

---------- ------------------------------ ---------- ----------

         2 PDB$SEED                       READ ONLY  NO

[oracle@virt05-cdb2 ~]$ . oraenv

ORACLE_SID = [cdb2] ? cdb2

The Oracle base remains unchanged with value /u01/app/oracle

[oracle@virt05-cdb2 ~]$ sqlplus / as sysdba

SQL> set sqlprompt "CDB2> "

CDB2> show pdbs

 

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED

---------- ------------------------------ ---------- ----------

         2 PDB$SEED                       READ ONLY  NO

 

·       В CDB1 создаем корневой контейнер приложений app_root:

CDB1> create pluggable database app_root as application container

admin user admin identified by oracle_4U roles=(connect) file_name_convert=('pdbseed','app_root');

Pluggable database created.

CDB1> alter pluggable database app_root open;

Pluggable database altered.

CDB1> conn sys/oracle_4U@app_root as sysdba

Connected.

·       Инсталлируем приложение app1:

CDB1> alter session set db_create_file_dest='/u01/app/oracle/oradata/cdb1/app_root';

System altered.

CDB1> alter pluggable database application app1 begin install '1.0';

Pluggable database altered.

·       При создании табличного пространства используем OMF, иначе мы не сможем выполнить захваченный код в PDB приложений при синхронизации.

CDB1> create tablespace salestbs datafile size 100m autoextend on;

Tablespace created.

CDB1> create user sales_mgr identified by oracle_4U default tablespace salestbs quota unlimited on salestbs container=all;

User created.

CDB1> grant create session,dba to sales_mgr container=all;

Grant succeeded.

·       У таблиц будут общими только метаданные, а данные в каждой PDB будут свои

CDB1> create table sales_mgr.regions sharing=metadata

(

            region_id    number(2) constraint pk_regions primary key,

            region_name varchar(30)

);

Table created.

CDB1> create table sales_mgr.sales sharing=metadata

(

            region_id    number(2) constraint fk_sales_regid references sales_mgr.regions,

            sdate                   date,

            ssum                   number(10, 2)

);

Table created.

CDB1> create index sales_mgr.sales_reg_date_idx on sales_mgr.sales( region_id, sdate );

·       Настраиваем возможность создания запросов к таблицам через контейнерную карту. Свойство таблицы containers_default позволяет её использовать во фразе CONTAINERS(table_name) запроса. А свойство container_map позволяет делать отсечку секций (фактически целиком PDB) при выполнении запроса основываясь на ключе секционирования  использованном во фразе WHERE. Например WHERE region_id = 2.

CDB1> alter table sales_mgr.regions enable container_map;

Table altered.

CDB1> alter table sales_mgr.sales enable container_map;

Table altered.

CDB1> alter table sales_mgr.regions enable containers_default;

Table altered.

CDB1> alter table sales_mgr.sales enable containers_default;

Table altered.

·       Вспомогательную процедуру load_sales, при помощи которой будем заполнять таблицу sales случайными тестовыми данными, тоже сделаем частью приложения:

create or replace procedure sales_mgr.load_sales( p_regid in number )

--sharing=metadata

authid current_user

as

            recnum     constant pls_integer := 10000;

            type        datetab is table of sales_mgr.sales.sdate%type index by pls_integer;

            type        numtab is table of sales_mgr.sales.ssum%type index by pls_integer;

            pdates      datetab;

            pnums      numtab;

begin

            for i in 1..recnum

            loop

                        pdates(i) := trunc( sysdate - 7 + dbms_random.value * 7, 'DD' );

                        pnums(i) := dbms_random.value * 10000;

            end loop;

 

            forall i in 1..recnum

                        insert into sales_mgr.sales values ( p_regid, pdates(i), pnums(i) );

            commit;

end;

/

·       Заканчиваем инсталляцию приложения

CDB1> alter pluggable database application app1 end install '1.0';

·       Создаем таблицу контейнерной карты, имена секций в ней должны совпадать с именами PDB приложений, а данные в каждой PDB будут соответствовать своему региону в соответствии с ключом секционирования region_id:

CDB1> create table sales_mgr.maptable

(

            region_id    number(2),

            region_name varchar(30)

) partition by list (region_id)

(

            partition europa values (1),

            partition asia values (2)

);

·       Создадим шаблонную PDB (SEED), на основе которой будут создаваться другие PDB и синхронизируем ее с корневым контейнером приложений

CDB1> create pluggable database as seed admin user admin identified by oracle_4U roles=(connect) file_name_convert=('pdbseed','app_root/app_seed');

Pluggable database created.

CDB1> alter pluggable database app_root$seed open;

Pluggable database altered.

CDB1> conn sys/oracle_4U@app_root$seed as sysdba

Connected.

CDB1> alter session set db_create_file_dest='/u01/app/oracle/oradata/cdb1/app_root/app_seed';

System altered.

CDB1> alter pluggable database application app1 sync;

CDB1> conn sys/oracle_4U@app_root as sysdba

Connected.

CDB1> alter pluggable database app_root$seed close;

Pluggable database altered.

CDB1> alter pluggable database app_root$seed open read only;

Pluggable database altered.

·       Теперь можно создать PDB содержащие данные. Они будут создаваться как клон app_root$seed и поэтому их синхронизация с корневым контейнером не понадобиться:

CDB1> !mkdir -p /u01/app/oracle/oradata/cdb1/app_root/europa

CDB1> create pluggable database europa admin user admin identified by oracle_4U

roles=(connect) create_file_dest='/u01/app/oracle/oradata/cdb1/app_root/europa';

Pluggable database created.

CDB1> !mkdir -p /u01/app/oracle/oradata/cdb1/app_root/asia

CDB1> create pluggable database asia admin user admin identified by oracle_4U

roles=(connect) create_file_dest='/u01/app/oracle/oradata/cdb1/app_root/asia';

Pluggable database created.

CDB1> alter pluggable database europa open;

Pluggable database altered.

CDB1> alter pluggable database asia open;

Pluggable database altered.

·       Заполним данными наши таблицы и соберем статику по ним. Статистика по общим объектам собирается по месту нахождения данных.

CDB1> conn sales_mgr/oracle_4U@europa

Connected.

CDB1> insert into regions values ( 1, 'Europa' );

1 row created.

CDB1> commit;

Commit complete.

CDB1> exec load_sales( 1 )

PL/SQL procedure successfully completed.

CDB1> exec dbms_stats.gather_table_stats(null, 'regions', cascade => true, method_opt => 'FOR ALL COLUMNS SIZE AUTO' )

PL/SQL procedure successfully completed.

CDB1> exec dbms_stats.gather_table_stats(null, 'sales', cascade => true, method_opt => 'FOR ALL COLUMNS SIZE AUTO' )

PL/SQL procedure successfully completed.

CDB1> conn sales_mgr/oracle_4U@asia

Connected.

CDB1> insert into regions values ( 2, 'Asia' );

1 row created.

CDB1> commit;

Commit complete.

CDB1> exec load_sales( 2 )

PL/SQL procedure successfully completed.

CDB1> exec dbms_stats.gather_table_stats(null, 'regions', cascade => true, method_opt => 'FOR ALL COLUMNS SIZE AUTO' )

PL/SQL procedure successfully completed.

CDB1> exec dbms_stats.gather_table_stats(null, 'sales', cascade => true, method_opt => 'FOR ALL COLUMNS SIZE AUTO' )

PL/SQL procedure successfully completed.

·       Устанавливаем таблицу maptable в качестве контейнерной карты:

CDB1> conn sys/oracle_4U@app_root as sysdba

Connected.

CDB1> alter database set container_map='sales_mgr.maptable';

Database altered.

·       Теперь запрос сделанный из корневого контейнера приложений должен вернуть данные из обеих PDB без использования фразы CONTAINERS, а таблицы содержать псевдостолбец CON_ID. Проверяем:

CDB1> conn sales_mgr/oracle_4U@app_root

Connected.

CDB1> alter session set statistics_level=all;

CDB1> select * from regions;

 REGION_ID REGION_NAME                    CON_ID

---------- ------------------------------ ------

         2 Asia                                5

         1 Europa                              4

·       Создадим консолидированный отчет и посмотрим план выполнения такого запроса:

CDB1> select region_name, sdate, count(*), sum(ssum)

from regions natural join sales

group by region_name, sdate

order by region_name, sdate;

REGION_NAME                    SDATE       COUNT(*)  SUM(SSUM)

------------------------------ --------- ---------- ----------

Asia                           26-DEC-16        670 3394452.92

Asia                           27-DEC-16       1481 7439305.88

Asia                           28-DEC-16       1394 6904729.47

Asia                           29-DEC-16       1376 6770055.16

Asia                           30-DEC-16       1471 7502937.79

Asia                           31-DEC-16       1403 7223986.58

Asia                           01-JAN-17       1421 6991020.73

Asia                           02-JAN-17        784 3920130.94

Europa                         26-DEC-16        682 3406421.12

Europa                         27-DEC-16       1415 7238801.51

Europa                         28-DEC-16       1416 6949857.66

Europa                         29-DEC-16       1496  7507359.6

Europa                         30-DEC-16       1413 7048534.64

Europa                         31-DEC-16       1464 7374674.52

Europa                         01-JAN-17       1405 6904727.33

Europa                         02-JAN-17        709 3529188.03

16 rows selected.


Теперь посмотрим как можно перемещать наши PDB в другие контейнерные базы данных не изменяя код приложения создающий консолидированную отчетность. Это может понадобиться, например, при исчерпании ресурсов на данном сервере или для того чтобы сбалансировать нагрузку по серверам. Переносить будем PDB asia в CDB2. Для этого на понадобиться сделать клон корневого контейнера app_root на CDB2, а на CDB1 создать proxy PDB, которая будет прозрачно для приложения перенаправлять запросы на другую базу данных через Database Link. Обе базы данных должны работать в режиме локального UNDO и архивирования журнальных файлов.

·       Склонируем корневой контейнер приложений app_root с CDB1 на CDB2 под именем app_rr:

oracle@virt05-cdb2 ~]$ sqlplus / as sysdba

SQL> set sqlprompt "CDB2> "

CDB2> create public database link link_cdb1 connect to system identified by oracle_4U using 'CDB1';

Database link created.

CDB2> alter session set db_create_file_dest='/u02/app/oracle/oradata/cdb2/app_rr';

Session altered.

CDB2> create pluggable database app_rr as application container from app_root@link_cdb1;

Pluggable database created.

CDB2> alter pluggable database app_rr open;

Pluggable database altered.

·       На CDB1 создадим proxy PDB для перенаправления запросов на CDB2:

CDB1> conn sys/oracle_4U@app_root as sysdba

Connected.

CDB1> !mkdir -p /u01/app/oracle/oradata/cdb1/app_root/px_app_rr

CDB1> create public database link link_cdb2 connect to system identified by oracle_4U using 'CDB2';

Database link created.

CDB1> alter session set db_create_file_dest='/u01/app/oracle/oradata/cdb1/app_root/px_app_rr';

Session altered.

CDB1> create pluggable database px_app_rr as proxy from app_rr@link_cdb2;

Pluggable database created.

CDB1> alter pluggable database px_app_rr open;

Pluggable database altered.

·       Для перемещения PDB мы должны дать на базе источнике привилегию SYSOPER пользователю, через которого работает Database Link на приемнике:

CDB1> conn / as sysdba

Connected.

CDB1> grant sysoper to system container=all;

Grant succeeded.

·       Готовим базу данных приемник:

CDB2> conn sys/oracle_4U@app_rr as sysdba

Connected.

CDB2> create public database link link_cdb1 connect to system identified by oracle_4U using 'CDB1';

Database link created.

CDB2> !mkdir -p /u01/app/oracle/oradata/cdb2/app_rr/asia

CDB2> alter session set db_create_file_dest='/u01/app/oracle/oradata/cdb2/app_rr/asia';

·       Перемещаем PDB asia на CDB2:

CDB2> create pluggable database asia from asia@link_cdb1 relocate;

Pluggable database created.

·       В данный момент PDB2 asia у нас присутствует на обеих CDB. На CDB1 она открыта на чтение/запись, а на CDB2 она закрыта:

CDB2> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED

---------- ------------------------------ ---------- ----------

         3 APP_RR                         READ WRITE NO

         5 ASIA                           MOUNTED

CDB1> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED

---------- ------------------------------ ---------- ----------

         3 APP_ROOT$SEED                  READ WRITE NO

         4 EUROPA                         READ WRITE NO

         5 ASIA                           READ WRITE NO

         6 APP_ROOT                       READ WRITE NO

         7 PX_APP_RR                      READ WRITE NO

·       Но при первом открытии на чтение/запись PDB asia в CDB2, на старом месте в CDB1 её автоматически закроют и удалят. При необходимости, можно было бы воспользоваться режимом AVAILABILITY MAX, чтобы не обрывать существующие сессии пользователей к перемещаемой PDB.

CDB2> alter pluggable database asia open;

Pluggable database altered.

CDB2> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED

---------- ------------------------------ ---------- ----------

         3 APP_RR                         READ WRITE NO

         5 ASIA                           READ WRITE NO

CDB1> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED

---------- ------------------------------ ---------- ----------

         3 APP_ROOT$SEED                  READ WRITE NO

         4 EUROPA                         READ WRITE NO

         6 APP_ROOT                       READ WRITE NO

         7 PX_APP_RR                      READ WRITE NO

·       Осталось проверить что наш запрос создания консолидированной отчетности по прежнему работает:

CDB1> conn sales_mgr/oracle_4U@app_root

Connected.

CDB1> select region_name, sdate, count(*), sum(ssum)

from regions natural join sales

group by region_name, sdate

order by region_name, sdate;

REGION_NAME                    SDATE       COUNT(*)  SUM(SSUM)

------------------------------ --------- ---------- ----------

Asia                           26-DEC-16        670 3394452.92

Asia                           27-DEC-16       1481 7439305.88

Asia                           28-DEC-16       1394 6904729.47

Asia                           29-DEC-16       1376 6770055.16

Asia                           30-DEC-16       1471 7502937.79

Asia                           31-DEC-16       1403 7223986.58

Asia                           01-JAN-17       1421 6991020.73

Asia                           02-JAN-17        784 3920130.94

Europa                         26-DEC-16        682 3406421.12

Europa                         27-DEC-16       1415 7238801.51

Europa                         28-DEC-16       1416 6949857.66

Europa                         29-DEC-16       1496  7507359.6

Europa                         30-DEC-16       1413 7048534.64

Europa                         31-DEC-16       1464 7374674.52

Europa                         01-JAN-17       1405 6904727.33

Europa                         02-JAN-17        709 3529188.03

16 rows selected.

 

Поделиться
Ссылка скопирована

Возврат к списку