Oracle Database 12.2: Application Containers - Parte I

Por Deiby Gómez Oracle ACE Director e Alex Zaballa Oracle ACE Director
Postado em Janeiro 2017

Revisado por Marcelo Pivovar - Solution Architect

Introdução

A Oracle lançou em novembro de 2016 a documentação do Oracle Database 12.2.0.1.0 e os binários para a Oracle Public Cloud. Diversos recursos novos foram introduzidos, especialmente para a arquitetura Multitenant. Esta arquitetura foi introduzida na versão 12.1.0.1 de 2013 em conjunto com os novos conceitos de Container Database, Pluggable Database, Seed, Common Users e Local Users.

No Oracle Database 12.2.0.1.0 a Oracle introduziu uma grande mudança, assim como o fez em 2013. Dentre elas: Application Root, Application PDB, Application Seed, Application Container e Application Common Users. Este conjunto de características é muito interessante, especialmente para os desenvolvedores. Os Application Containers são muito úteis para quem precisa manter o mesmo conjunto de objetos em bancos de dados diferentes e ao mesmo tempo. Por exemplo, um dos requisitos mais comuns entre os desenvolvedores é ter um banco de dados baseado na produção. Geralmente o refresh dessas informações para outros ambientes é realizado manualmente, podendo levar muitas horas de trabalho aumentando a complexidade e tende a exigir que os administradores de bancos de dados sejam responsáveis por extrair essas informações do banco de dados principal e atualizem os outros bancos de dados.
O conceito de Application Containers veio para resolver este cenário. Basicamente, ele permite ter um conjunto de objetos e dados em um banco de dados principal e que outros bancos de dados façam referências (não aos dados físicos armazenados) para esses objetos. As bases de dados dependentes são sincronizadas em período de tempo ou manualmente para a nova versão do conjunto de objetos.

Nesta primeira parte deste artigo iremos demonstrar os conceitos básicos relacionados com os Application Containers com exemplos para ajudar a compreender esta nova funcionalidade.

NOTA: Este artigo foi escrito utilizando os binários do Oracle Database 12.2.0.1.0 Enterprise Edition Extreme Performance (Oracle Public Cloud). 

Conceitos Básicos:

Application Root

O Application Root é uma Pluggable Database onde está instalada uma ou várias aplicações. Com isso todas as alterações serão realizadas nela e em seguida são sincronizadas com as Application Pluggable Databases. Um Application Root pode pertencer a apenas um Application Container.

Application Pluggable Database

Um Application PDB é uma Pluggable Database que faz parte de um Application Container e pode visualizar os dados e metadados de uma determinada versão de um Application que está sendo compartilhado a partir de um Application Root. Este tipo de PDB também pode ser chamado de Application Tenant. Um Application PDB pertence somente a um único Application Container e sincronizar dados de um único Application Root.

Application Seed

Um Application Seed tem a mesma funcionalidade do PDB$SEED, que foi introduzido na arquitetura Multitenant em 2013 no Oracle Database 12cR1. O PDB$SEED é uma Pluggable Database que é utilizada como base para criar novos Pluggable Databases. O Application Seed tem um comportamento semelhante dentro de um Application Container, onde novos Applications podem ser criados a partir desta aplicação modelo.
Só pode existir um Application Seed dentro de um Application Container.

Application

Um Application é um conjunto de objetos e dados que possui uma versão e um nome único entre todos os Application Containers. Cada vez que é feita uma alteração nos objetos ou dados, uma nova versão do Application é gerada. As operações que podem ser realizadas em um Application são: instalar, atualizar, corrigir e desinstalar.
Um Application não pode ser instalado no CBD$ROOT, eles são instalados no Application Root.
Ao longo da vida de um Application podem existir diversas versões diferentes e todas elas são mantidas dentro do Application Container e cada uma destas versões pode ser compartilhada com diferentes Application PDBs. Isso é muito interessante pois cada Application PDB poderia ver objetos e dados de diferentes versões do mesmo Application.
A forma como esses objetos e dados são compartilhados depende do nível de compartilhamento que está sendo usado. Em um Application Container podemos ter os seguintes níveis:

Metadata-linked: São objetos que compartilham apenas os seus metadados do Application Root com os Application PDBs, portanto os dados armazenados podem ser diferentes.

Data-linked: Neste nível de compartilhamento os objetos compartilham seus metadados e também os dados do Application Root com os Application PDBs. Porém, estes dados estarão em read-only.

Extended Data-Linked: Particularmente preferimos chamar este nível Row-Linked, porque apenas alguns registros das tabelas serão compartilhados no Application Root com os Application PDBs. Neste caso, os dados compartilhados (referenciados) nos Application PDBs estarão em read-only, enquanto os que não forem compartilhados  estarão em modo read-write.

Application Container

Um Application Container possui um Application Root e nenhum ou vários Application PDBs. Pode ou não pode ter um Application Seed e armazena os objetos e dados para um ou mais Applications. Este componente é opcional em uma base de dados Multitenant, isso significa que se você optar por utilizar um Application Container, cada uma das partes deve ser criada manualmente. Um banco de dados do tipo Multitenant (Container Database) pode ter vários Application Containers.
Um Container Database que possui vários Application Containers é representando conforme a imagem abaixo:

Criação de um Application Container:

Basicamente um Application Container é criado quando se cria uma Pluggable Database e esta PDB é do tipo Application Root.  
Isto significa que um Application Container pode ser criado a partir do PDB$SEED, ou clonando uma Pluggable Database existente, ou criado a partir de um Non-CDB, etc. Basicamente de todos os métodos de criação de uma Pluggable Database convencional, bastando apenas adicionar a cláusula AS APPLICATION CONTAINER ao comando CREATE PLUGGABLE DATABASE.

Vamos a um exemplo.

Conectar-se com um Common User ao CDB:

SQL> show user 
USER is "SYS" 

Verificar se está conectado ao CDB$ROOT:

SQL> show con_name 

CON_NAME 
------------------------------ 
CDB$ROOT 

Criar um Application Container: Basicamente o que se cria é um Application Container, que é composto de um Application Root e nenhuma Application PDB

SQL> create pluggable database NuvolaAppRoot as application container admin user pdbadmin identified by Nuvola1; 

Pluggable database created.

Neste exemplo, atribuímos o nome de NuvolaAppRoot ao Application Root.

Abrir o Application Root:

SQL> alter pluggable database NuvolaAppRoot open;

Pluggable database altered.

Verificar se o Application Root foi criado:

SQL> select con_id, name , application_root  from v$pdbs where application_root='YES'

CON_ID NAME           APPLICATION_ROOT
------ -------------- ----------------
     6 NUVOLAAPPROOT  YES

Criação de um Application Pluggable Database:

Conectar-se ao Application Root:

SQL> alter session set container=NuvolaAppRoot;

Session altered.

Para criar um Application PDB é necessário estar conectado a um Application Root.

Verificar se está conectado ao Application Root correto:

SQL> show con_name

CON_NAME
------------------------------
NUVOLAAPPROOT

Criar o Application PDB:

SQL> create pluggable database NuvolaAppPDB1 admin user app1admin identified by Nuvola1;

Pluggable database created.

Abrir o Application PDB:

SQL> alter pluggable database NuvolaAppPDB1 open;

Pluggable database altered.

Verificar que o Application PDB foi criado e depende do Application Root correto:

SQL> select con_id "PDBID", name "PDBName", application_root "AppRoot", application_pdb "AppPDB", 
application_seed "AppSeed" , application_root_con_id "AppRootID" from v$pdbs

PDBID PDBName        AppRoot AppPDB AppSeed AppRootID
----- --------------- ------- ------ ------- ----------
5 NUVOLAAPPPDB1   NO      YES    NO      6 
6 NUVOLAAPPROOT   YES     NO     NO

Com SELECT acima, é possível ver que o Application Root é o PDB de número 6 e que o PDB chamado NuvolaAppPDB1 é um Application PDB depende do Application Root.

Instalar um Application em um Application Container:

Conectar-se ao Application Root:

SQL> show con_name

CON_NAME
------------------------------
NUVOLAAPPROOT

Para instalar um Application, é necessário informar o nome do Application e a versão:

SQL> alter pluggable database application NuvolaApplication begin install '1.0';

Pluggable database altered.

Todas as operações executadas depois do Begin Install fazem parte da instalação de um Application e cada uma dessas operações é armazenada no Application Container. Para este Application será criado um usuário com alguns privilégios e uma tabela com algumas linhas:

SQL> create user AppUser1 identified by Nuvola;

User created.

SQL> grant connect, resource , unlimited tablespace to AppUser1;

Grant succeeded.

SQL> create table AppUser1.Country (name varchar2(20));

Table created.

SQL>  insert into AppUser1.Country values ('Guatemala');

1 row created.
SQL> insert into AppUser1.Country values ('Canada');

1 row created.

SQL> insert into AppUser1.Country values ('Brazil');

1 row created.

SQL> insert into AppUser1.Country values ('USA');

1 row created.

SQL> commit;

Commit complete.

Quando o usuário e os objetos forem criados, podemos finalizar a criação do Application com o comando End Install.

SQL> alter pluggable database application NuvolaApplication end install '1.0';

Pluggable database altered. 

Consultar um Application:

Agora serão mostradas algumas consultas muito úteis que nos ajudam a obter mais informações sobre os Applications que estão instalados no Application Container.

Para verificar se há algum erro em um Application PDB após uma atualização, pode usar a seguinte consulta:

SQL> select app_name, app_statement, errornum, errormsg , sync_time from dba_app_errors;

Com a consulta abaixo, podemos listar todos os Applications existentes no Application Container que estamos conectados e suas versões:

SQL> select app_name, app_version from dba_app_versions where app_name like '%NUVOLA%'

APP_NAME        APP_VERSION
-------------------- -----------
NUVOLAAPPLICATION    1.0

Com a consulta abaixo, podemos ver todas as operações que foram realizadas como parte da instalação ou atualização de um Application existente:

SQL> select capture_time "CaptureTime", patch_number "Patch#", statement_id "Stat#", app_statement 
from dba_app_statements where app_name='NUVOLAAPPLICATION'

CaptureTime      Patch# Stat# APP_STATEMENT
---------------- ------ ----- ----------------------------------------
11-30-2016 05:01      0     4 SYS
11-30-2016 05:01      0     5 alter pluggable database application Nuv
olaApplication begin install '1.0'

11-30-2016 05:01      0     6 create user AppUser1 identified by  VALU
ES 'S:E7CC7FF3348A4ACFAC80BC5083C60B1A77

11-30-2016 05:02      0     7 create table AppUser1.Country (name varc
har2(20))

11-30-2016 05:02      0     8 grant connect, resource to AppUser1
11-30-2016 05:03      0     9 grant unlimited tablespace to AppUser1
11-30-2016 05:03      0    10 insert into AppUser1.Country values ('G
uatemala')

11-30-2016 05:03      0    11 grant connect, resource , unlimited tabl
espace to AppUser1

11-30-2016 05:04      0    12 insert into AppUser1.Country values ('Ca
nada')

11-30-2016 05:04      0    13 insert into AppUser1.Country values ('Br
azil')

11-30-2016 05:04      0    14 insert into AppUser1.Country values ('US
A')

11-30-2016 05:04      0    15 commit
11-30-2016 05:05      0    16 alter pluggable database application Nuv
olaApplication end install '1.0'

13 rows selected.

Como sincronizar uma aplicação com uma Application PDB

Até agora criamos um Application Root e implicitamente um Application Container. Após isso, criamos um Application PDB e fizemos a instalação de um Application. No entanto, o usuário e objetos criados ainda não são vistos pelos Application PDBs.
Isso pode ser confirmado através da seguinte consulta:

Conectar-se ao Application Root:

SQL> show con_name

CON_NAME
------------------------------
NUVOLAAPPROOT

SQL> select con_uid, app_name, app_id, app_version, app_status from dba_app_pdb_status;

no rows selected

A tabela DBA_APP_PDB_STATUS exibe informações das aplicações e as suas versões presentes nas Application PDBs.

Como não foram mostrados registros na consulta anterior, isto indica que o Application chamado NuvolaApplication que instalamos no Application Root não foi sincronizado ou não existe em nenhum Application PDB.

Outra maneira de confirmar isso é fazer um SELECT na tabela AppUser1.Country, que foi instalada no Application chamado NuvolaApplication:

Conectar-se ao Application PDB chamado NuvolaAppPDB1:

SQL> show con_name

CON_NAME
------------------------------
NUVOLAAPPPDB1

Consultar a tabela AppUser1.Country:

SQL> select * from AppUser1.Country;
select * from AppUser1.Country
                       *
ERROR at line 1:
ORA-00942: table or view does not exist

Como visto, esta tabela ainda não existe no Application PDB. Para sincronizar o Application com o Application PDB, deve-se executar o seguinte comando:

SQL> alter pluggable database application NuvolaApplication sync;

Pluggable database altered.

Uma vez sincronizado o Application ao Application PDB será possível consultar o usuário e objetos criados:

SQL> select * from AppUser1.Country;

NAME
--------------------
Guatemala
Canada
Brazil
USA

Após realizar a sincronia de um Application, é importante revisar se existem erros:

Conectar-se ao Application Root:

SQL> show con_name

CON_NAME
---------------------
NUVOLAAPPROOT

Verificar se ocorreram erros durante a sincronização:

SQL> select app_name, app_statement, errornum, errormsg , sync_time from dba_app_errors;

no rows selected

Ao consultarmos novamente a tabela DBA_APP_PDB_STATUS veremos que já existe um Application no Application PDB. Isso foi resultado da sincronização que realizamos. Também será mostrada a versão do Application e seu estado:

SQL> select con_uid, app_name, app_id, app_version, app_status from dba_app_pdb_status

   CON_UID APP_NAME         APP_ID APP_VERSION APP_STATUS
---------- ----------------- ------ ----------- ----------
1423057976 NUVOLAAPPLICATION     3         1.0     NORMAL

É importante salientar, que os objetos criados mantém um nível de compartilhamento chamado Metadata-Linked. Isso significa que os objetos em si (Por exemplo a tabela AppUser1.Country) são compartilhados pelos Application PDBs através de ponteiros no dicionário de dados, mas as linhas são armazenadas fisicamente em cada Application PDB. Por exemplo, os registros inseridos no Application Root serão armazenados no datafile do Application Root. Enquanto os registros inseridos enquanto conectado a um Application PDB serão armazenados nos datafiles deste Application PDB. A estrutura do objeto será compartilhada, mas os dados serão exclusivos de cada PDB:

SQL> select owner, object_name, sharing, application, created_appid, created_vsnid 
from dba_objects 
where object_name='COUNTRY'

OWNER     OBJECT_NAME SHARING        APPLICATION CREATED_APPID CREATED_VSNID
--------- ----------- -------------- ----------- ------------- -------------
APPUSER1  COUNTRY     METADATA LINK            Y              2            1

Outra maneira de confirmar que os dados são únicos para cada PDB e que apenas a estrutura da tabela está sendo compartilhada, é através do rowid, como mostrado abaixo.

Conectar-se ao Application Root:

SQL> alter session set container=NuvolaAppRoot;

Session altered.

SQL> select dbms_rowid.rowid_to_absolute_fno(rowid,'APPUSER1','COUNTRY') file_num, name from AppUser1.Country;

FILE_NUM NAME
-------- ---------- 
31       Guatemala
31       Canada
31       Brazil
31       USA

Conectar-se ao Application PDB:

SQL> show con_name

CON_NAME
------------------
NUVOLAAPPPDB1

SQL> select dbms_rowid.rowid_to_absolute_fno(rowid,'APPUSER1','COUNTRY') file_num, name from AppUser1.Country;

FILE_NUM NAME
-------- ---------- 
34       Guatemala
34       Canada
34       Brazil
34       USA

Podemos ver que os registros do Application Root estão sendo armazenados em um datafile enquanto os registros inseridos Application PDB estão sendo armazenados em outro datafile.

É possível inserir mais registros no Application PDB, mas esses registros serão armazenados apenas no Application PDB ao qual se está conectado:

SQL> insert into AppUser1.Country values ('Italy');

1 row created.

SQL> commit;

Commit complete.

SQL> select dbms_rowid.ROWID_TO_ABSOLUTE_FNO(rowid,'APPUSER1','COUNTRY') file_num,name from AppUser1.Country;

FILE_NUM NAME
-------- --------------------
34       Guatemala
34       Canada
34       Brazil
34       USA
34       Italy

Através da consulta abaixo, podemos confirmar que o datafile com o identificador 31 pertence ao Application Root chamado NuvolaAppRoot e o datafile com identificador 34 pertence ao Application PDB chamado NuvolaAppPDB1:

SQL> select f.con_id, c.name, f.file# from v$pdbs c, v$datafile f where c.con_id=f.con_id and file# in (31,34);

CON_ID NAME                 FILE#
------ -------------------- ----------
5      NUVOLAAPPPDB1        34
6      NUVOLAAPPROOT        31 

Conclusão

Application Containers é um conceito muito inovador e moderno que foi introduzido na versão 12.2.0.1.0. Ele vem para automatizar tarefas que são frequentemente realizadas por desenvolvedores, como a criação de múltiplas aplicações (conjunto de dados e objetos) e a manutenção de diferentes versões dessas aplicações.

Neste artigo foram introduzidos novos conceitos como Application Root, Application PDBs, Applications, entre outros.

Sem dúvida, os Application Containers serão bem recebidos pelos desenvolvedores, porque irão agilizar suas tarefas diárias.

No próximo artigo você verá conceitos como Data-Linked e Extended Data-Linked, incluindo as configurações novas e avançadas dos Application Containers.



Deiby Gomez é "Oracle ACE Director", "A Oracle Certified Master 11g" e "A Oracle 12c Certified Master". Ele tem sido um orador na Oracle Open World nos EUA e no Brasil; em Colaborar, Las Vegas e OTN Tour em vários países da América Latina. Vencedor do "SELECT Choice Award da revista Editor de 2016". Ele é um membro da "OraWorld-Team" foi "Beta Tester" da versão 12cR2. Deiby é Presidente o Grupo usuários Oracle de Guatemala (GOUG) e atualmente é Consultor bancos de dados Oracle em Nuvola Consulting Group (www.nuvolacg.com). Twitter @hdeiby.

Alex Zaballa, formado em Análise de Sistemas, é especialista em Banco de Dados Oracle com sólidos conhecimentos em Servidores de Aplicação e Sistemas Operacionais; trabalha com Oracle há 16 anos, é Oracle ACE Director, certificado OCM Database 12c/11G/Cloud e conta com mais de 200 outras certificações em produtos da Oracle. Alex também é membro do Groupo de Usuários Oracle do Brasil (GUOB), fundador do Grupo de Usuários Oracle de Angola (GUOA) e membro do time OraWorld.

Este artigo foi revisto pela equipe de produtos Oracle e está em conformidade com as normas e práticas para o uso de produtos Oracle.