Интернет-журнал «FORS» Архив номеров На Главную

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

Юрий Челпанов

ведущий преподавателей УКЦ ФОРС
по линейке продуктов Oracle,
Oracle Certified Master

На момент написания статьи официальный выпуск новой версии 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:

Мне такая архитектурная конструкция стала напоминать объектную модель таких языков программирования, как 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.

В данный момент PDB 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.