Para melhor visualização, recomendo resolução de no mínimo 1280 x 800 e navegador Mozilla Firefox


segunda-feira, 3 de fevereiro de 2014

Oracle Multitenant: Abordando a arquitetura e criação do Container Database (CDB) e Pluggable Databases no Oracle 12c

Por Eduardo Legatti

Olá, 



Como já foi abordado no artigo de Junho/2013, o Oracle Database 12c agora suporta uma nova arquitetura (option) chamada Multitenant que permite que tenhamos um ou mais "sub-bancos de dados" dentro e um único "super banco de dados". Este "super banco de dados" é chamado de CDB (Container Database) e os "sub-bancos de dados" são chamados de PDBs (Pluggable Databases) ou containers de bancos de dados plugáveis. O CDB também pode ser chamado de container ROOT (CDB$ROOT). Em outras palavras, essa nova arquitetura permite a criação de muitos PDBs dentro de um único CDB. A idéia principal por trás deste conceito consiste em permitir um uso mais eficiente dos recursos do sistema, além de oferecer um gerenciamento mais simplificado.

Até o Oracle 12c release 12.1, o número máximo de PDBs que podem ser criados é de 252. O Oracle 12c suporta tanto a criação de bancos de dados CDBs quanto a criação de bancos de dados não-CDBs que são aqueles que temos o costume de usar e que possuem a arquitetura que conhecemos nas versões 11g, 10g, 9i, 8i, etc. Aliás, é possível atualizarmos um banco de dados Oracle pré 12c (não-CDB) para o Oracle 12c e continuarmos a operá-lo como tal. Do ponto de vista de um cliente que se conecta via Oracle Net a uma instância do Oracle, o PDB é o banco de dados. Do ponto de vista do sistema operacional, o CDB é que é o banco de dados. No mais, neste artigo irei demonstrar a criação de um banco de dados CDB usando o DBCA (Database Configuration Assistant) e a criação de dois bancos PDBs (um via DBCA e outro manualmente via SQL*Plus). A minha intenção é demonstrar algumas propriedades e características dessa nova arquitetura de forma simples e objetiva.

Vale a pena salientar que essa arquitetura permite que tenhamos vários PDBs no mesmo CDB cada um tendo usuários, tablespaces, database links, directories, etc... com o mesmo nome. Por exemplo, poderemos ter o usuário SCOTT tanto no banco de dados PDB01 quanto no banco PDB02. Do ponto de vista da arquitetura, veremos mais abaixo que um CDB é composto de um container root chamado de CDB$ROOT responsável por armazenar o dicionário de dados, o motor PL/SQL e usuários comuns (common users). Outro componente é o seed de um banco de dados PDB chamado PDB$SEED que é utilizado como template para criação de novos PDBs.

Segue abaixo algumas características e peculiaridades da arquitetura física e lógica do Oracle 12c Multitenant:

  • Multitenant é uma option do Oracle Enterprise Edition.
  • Um container é definido como uma coleção de data files e metadados que existem dentro de um CDB. Pode ser root, seed ou PDB.
  • Um container CDB é definido como um banco de dados capaz de abrigar um ou mais banco de dados plugáveis (PDBs).
  • Um PDB (banco de dados plugável) é um tipo especial de container que pode ser facilmente clonado. Se necessário, um PDB também pode ser transferido de um CDB para outro.
  • Um container CDB pode conter zero, um ou mais PDBs (Até o release 12.1 máximo de 252).
  • As tablespaces SYSTEM e SYSAUX existem tanto no container root CDB quanto nos PDBs.
  • Existe apenas uma tablespace de UNDO para todo o CDB, ou seja, a tablespace de UNDO é compartilhada.
  • Existe apenas um conjunto de control files e online redo log files para todo o CDB, ou seja, os mesmos são compartilhados.
  • Pode ser criada uma tablespace TEMP default para todo o CDB, mas cada PDB pode ter tablespaces temporárias adicionais.
  • Os arquivos relacionados ao Oracle Net como listener.ora, tnsnames.ora, e sqlnet.ora são válidos para todo o CDB. Portanto, todos os PDBs utilizam esses mesmos arquivos.
  • Existe apenas um conjunto de processos de segundo plano (background processes) que são compartilhados pelo CDB e todos os PDBs.
  • Existe apenas uma única SGA (System Global Area) compartilhada para todos os PDBs.
  • Quando o CDB sofre shutdown todos os PDBs também sofrerão automaticamente shutdown.
  • Quando o CDB é aberto (startup) os PDBs permanecem no estado MOUNT e precisam ser abertos individualmente através do comando ALTER PLUGGABLE DATABASE.
  • Existe somente um arquivo de inicialização spfile para todo o CDB. Os PDBs podem ter configurações próprias, mas essas configurações são persistidas no dicionário de dados do Oracle e não em spfiles adicionais para cada PDB criado.
  • Além das views de dicionário de dados DBA/ALL/USER uma nova categoria com o prefixo CDB foi criada para disponibilizar informações e metadados dos bancos de dados PDBs dentro de um CDB.

Em resumo, veremos que o container ROOT (CDB$ROOT) contém as tablespaces SYSTEM, SYSAUX, TEMP, e UNDO além dos control files e redo log files. O SEED container (PDB$SEED) contém as tablespaces SYSTEM, SYSAUX, TEMP (opcional). Vale a pena salientar que este artigo terá com foco apenas a criação dos bancos de dados CDB e PDBs com o objetivo de demonstrar algumas propriedades de sua arquitetura. Demais demonstrações como ações de plugar, desplugar, clonar, alterações de configurações, backups, entre outros, serão apresentados em artigos posteriores.


Criando o banco de dados de container (CDB)

Bom, iniciarei a criação do banco de dados de container CDB01 (sem maiores detalhes) através do utilitário DBCA (Database Configuration Assistant) conforme demonstrado pela figura abaixo:




Após a criação do banco de dados CDB01 poderemos verificar abaixo consultando a view V$DATABASE que o mesmo se trata de um container database. Realizando uma consulta em uma nova view dinâmica de desempenho V$CONTAINER, poderemos verificar que, além do container CDB$ROOT, também temos um seed container chamado PDB$SEED. Através do resultado da view V$PDBS iremos notar que o banco de dados PDB$SEED é somente leitura. O propósito do mesmo é servir como um template para criação de novos PDBs. Consultando a view DBA_PDBS podemos verificar que o mesmo se encontra aberto.

C:\>sqlplus / as sysdba

SQL*Plus: Release 12.1.0.1.0 Production on Seg Fev 3 18:45:39 2014

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

Conectado a:
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> select name,cdb,con_id,con_dbid from v$database;

NAME           CDB     CON_ID   CON_DBID
-------------- --- ---------- ----------
CDB01          YES          0 1370556575

SQL> select con_id, name from v$containers;

    CON_ID NAME
---------- -----------------
         1 CDB$ROOT
         2 PDB$SEED

SQL> select name, open_mode from v$pdbs;

NAME                 OPEN_MODE
-------------------- ----------
PDB$SEED             READ ONLY

SQL> select pdb_id,pdb_name,dbid,status from dba_pdbs;

    PDB_ID PDB_NAME             DBID STATUS
---------- -------------- ---------- --------
         2 PDB$SEED       4076210644 NORMAL
  
Uma outra forma de verificar se um banco de dados é CDB ou não-CDB é verificando o parâmetro de inicialização ENABLE_PLUGGABLE_DATABASE.

SQL> show parameter enable_pluggable_database;

NAME                           TYPE        VALUE
------------------------------ ----------- -----------------
enable_pluggable_database      boolean     TRUE
  
Criando o banco de dados PDB com o DBCA

Com o banco de dados de container CDB01 criado, irei criar o primeiro banco de dados plugável através do DBCA. Este banco de dados terá o nome de PDB01 conforme demonstrado pelas figuras abaixo:

  


     



Criando o banco de dados PDB manualmente com o SQL*Plus

Podemos também criar bancos de dados plugáveis manualmente através do comando CREATE PLUGGABLE DATABASE. Utilizarei o SQL*Plus para criar o banco de dados PDB02 conforme demonstração abaixo:

SQL> create pluggable database PDB02
  2  admin user pdb_admin identified by manager
  3  file_name_convert =
  4  (
  5  'D:\oracle\app\oradata\CDB01\pdbseed',
  6  'D:\oracle\app\oradata\CDB01\PDB02'
  7  );

Banco de dados plugável criado.  

Após a criação dos bancos de dados plugáveis PDB01 e PDB02, irei comentar abaixo sobre algumas peculiaridades dos mesmos.

SQL> select a.con_id,
  2         a.name,
  3         a.dbid,
  4         b.status,
  5         a.open_mode,
  6         a.total_size
  7  from v$pdbs a, dba_pdbs b
  8  where a.con_id=b.pdb_id;

    CON_ID NAME            DBID STATUS        OPEN_MODE  TOTAL_SIZE
---------- --------- ---------- ------------- ---------- ----------
         2 PDB$SEED  4076210644 NORMAL        READ ONLY   283115520
         3 PDB01     3898013363 NORMAL        READ WRITE  288358400
         4 PDB02     3947824578 NEW           MOUNTED             0

No resultado da query acima, podemos verificar que o banco de dados plugável PDB$SEED é por padrão somente leitura e que o banco PBD02 encontra-se no estado NEW e no modo MOUNT. Diferentemente de utilizar o DBCA, que já faz o trabalho de abrir o banco plugável no modo de escrita/gravação, quando criamos um banco de dados plugável manualmente, precisaremos realizar o procedimento abaixo para deixá-lo no modo de escrita/gravação.

SQL> alter pluggable database PDB02 open read write;

Banco de dados plugável alterado.
  
Para facilitar o entendimento da arquitetura física dos arquivos de banco de dados envolvidos, segue abaixo a hierarquia dos diretórios criados após a criação dos bancos de dados:

D:\oracle\app\oradata> tree /F /A

D:.
\---CDB01
    |   CONTROL01.CTL
    |   CONTROL02.CTL
    |   REDO01.LOG
    |   REDO02.LOG
    |   REDO03.LOG
    |   SYSAUX01.DBF
    |   SYSTEM01.DBF
    |   TEMP01.DBF
    |   UNDOTBS01.DBF
    |   USERS01.DBF
    |
    +---PDB01
    |       PDB01_USERS01.DBF
    |       PDBSEED_TEMP01.DBF
    |       SYSAUX01.DBF
    |       SYSTEM01.DBF
    |
    +---PDB02
    |       PDBSEED_TEMP01.DBF
    |       SYSAUX01.DBF
    |       SYSTEM01.DBF
    |
    \---pdbseed
            PDBSEED_TEMP01.DBF
            SYSAUX01.DBF
            SYSTEM01.DBF

Podemos verificar também que os bancos de dados se registraram no LISTENER com sucesso. Segue abaixo a saída do comando "lsnrctl status".

C:\>lsnrctl status

LSNRCTL for 64-bit Windows: Version 12.1.0.1.0 - Production on 03-FEV-2014 18:50:05

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

Estabelecendo conexão com (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=PChome)(PORT=1521)))
STATUS do LISTENER
------------------------
Apelido              LISTENER
Versão               TNSLSNR for 64-bit Windows: Version 12.1.0.1.0 - Production
Data Inicial         03-FEV-2014 18:50:41
Funcionamento        0 dias 1 hr. 36 min. 27 seg
Nível de Análise     off
Segurança            ON: Local OS Authentication
SNMP                 OFF
Arq. Parâm. Listn.   D:\oracle\app\product\12.1.0\dbhome_1\network\admin\listener.ora
Arq. Log Listener    D:\oracle\app\diag\tnslsnr\PChome\listener\alert\log.xml
Resumo de Atendimento...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=PChome)(PORT=1521)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(PIPENAME=\\.\pipe\EXTPROC1521ipc)))
Resumo de Serviços...
O serviço "CDB01" tem 1 instância(s).
  Instância "cdb01", status READY, tem 1 handler(s) para este serviço...
O serviço "CDB01XDB" tem 1 instância(s).
  Instância "cdb01", status READY, tem 1 handler(s) para este serviço...
O serviço "CLRExtProc" tem 1 instância(s).
  Instância "CLRExtProc", status UNKNOWN, tem 1 handler(s) para este serviço...
O serviço "pdb01" tem 1 instância(s).
  Instância "cdb01", status READY, tem 1 handler(s) para este serviço...
O serviço "pdb02" tem 1 instância(s).
  Instância "cdb01", status READY, tem 1 handler(s) para este serviço...
O comando foi executado com êxito
  
A view dinâmica de desempenho V$SERVICES também pode ser utilizada para obter informações dos serviços de bancos de dados disponíveis como demonstrado abaixo:

SQL> select name,pdb from v$services;

NAME            PDB
--------------- -------------------
CDB01           CDB$ROOT
CDB01XDB        CDB$ROOT
pdb01           PDB01
pdb02           PDB02
SYS$BACKGROUND  CDB$ROOT
SYS$USERS       CDB$ROOT

6 linhas selecionadas. 
 

Navegando entre containers (CDB e PDBs)

Por padrão, quando conectamos no banco de dados como SYSDBA sem informar um serviço TNS, iremos nos conectar no container ROOT. Conectar no container ROOT é o mesmo que conectar em um banco de dados não-CDB como fazemos quando conectamos em um banco de dados de versões anteriores como o Oracle 11g ou 10g. Para confirmar isso, ou seja, mostrar o container corrente, é possível utilizar o comando SHOW CON_NAME do SQL*Plus conforme demonstrado a seguir:

SQL> show con_name

CON_NAME
------------------------
CDB$ROOT 
  
Ao consultar a view de dicionário de dados DBA_DATA_FILES abaixo, podemos confirmar que os arquivos de dados (data files) mostrados são provenientes do banco de dados CDB01.

SQL> select file_id,file_name from dba_data_files;

   FILE_ID FILE_NAME
---------- -----------------------------------------
         1 D:\ORACLE\APP\ORADATA\CDB01\SYSTEM01.DBF
         3 D:\ORACLE\APP\ORADATA\CDB01\SYSAUX01.DBF
         5 D:\ORACLE\APP\ORADATA\CDB01\UNDOTBS01.DBF
         6 D:\ORACLE\APP\ORADATA\CDB01\USERS01.DBF


Para navegarmos entre os containers existentes, poderemos executar o comando ALTER SESSION SET CONTAINER conforme demonstrado abaixo:

SQL> alter session set container = PDB01;

Sessão alterada.

SQL> show con_name

CON_NAME
------------------------------
PDB01

SQL> select file_id,file_name from dba_data_files;

   FILE_ID FILE_NAME
---------- ---------------------------------------------------
         7 D:\ORACLE\APP\ORADATA\CDB01\PDB01\SYSTEM01.DBF
         8 D:\ORACLE\APP\ORADATA\CDB01\PDB01\SYSAUX01.DBF
         9 D:\ORACLE\APP\ORADATA\CDB01\PDB01\PDB01_USERS01.DBF

SQL> alter session set container = CDB$ROOT;

Sessão alterada.

SQL> show con_name

CON_NAME
------------------------------
CDB$ROOT 
  
Realizando STARTUP e SHUTDOWN dos bancos de dados

Se quisermos realizar o shutdown de um banco de dados PDB específico, será necessário utilizar o comando ALTER PLUGGABLE DATABASE ... CLOSE IMMEDIATE conforme exemplo abaixo:

SQL> alter pluggable database PDB01 close immediate;

Banco de dados plugável alterado.
 
Para realizar a opção inversa, ou seja, abrir o banco de dados para leitura/escrita bastará utilizar o comando ALTER PLUGGABLE DATABASE ... OPEN conforme demonstrado a seguir:

SQL> alter pluggable database PDB01 open;

Banco de dados plugável alterado.
  

Uma observação importante que notei, está relacionado à inicialização dos bancos de dados PDBs quando realizamos o startup do banco de dados CDB. Não há um mecanismo default que inicializa automaticamente os bancos de dados PDBs quando o banco de dados CDB é inicializado. Poderemos ver abaixo que, ao realizar o startup do banco de dados CDB (CDB01), todos os bancos de dados PDBs (PDB01 e PDB02) permanecem no estado MOUNT.

C:\>sqlplus / as sysdba

SQL*Plus: Release 12.1.0.1.0 Production on Seg Fev 3 19:00:47 2014

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

Conectado a uma instância inativa.

SQL> startup
Instância ORACLE iniciada.

Total System Global Area 1068937216 bytes
Fixed Size                  2410864 bytes
Variable Size             373294736 bytes
Database Buffers          687865856 bytes
Redo Buffers                5365760 bytes
Banco de dados montado.
Banco de dados aberto.

SQL> select a.con_id,
  2         a.name,
  3         a.dbid,
  4         b.status,
  5         a.open_mode,
  6         a.total_size
  7  from v$pdbs a, dba_pdbs b
  8  where a.con_id=b.pdb_id;

    CON_ID NAME            DBID STATUS        OPEN_MODE  TOTAL_SIZE
---------- --------- ---------- ------------- ---------- ----------
         2 PDB$SEED  4076210644 NORMAL        READ ONLY   283115520
         3 PDB01     3898013363 NORMAL        MOUNTED             0
         4 PDB02     3947824578 NEW           MOUNTED             0

Para realizar o startup de todos os bancos de dados PDBs de uma única vez, poderemos executar o comando ALTER PLUGGABLE DATABASE ALL OPEN conforme demonstrado a seguir:

SQL> alter pluggable database all open;

Banco de dados plugável alterado.
 
Para evitar que precisemos executar o comando acima todas as vezes que inicializamos a instância CDB, poderemos criar uma trigger de banco de dados chamando o evento AFTER STARTUP ON DATABASE conforme exemplo abaixo:

SQL> create or replace trigger open_all_pdbs
  2  after startup on database
  3  begin
  4     execute immediate 'alter pluggable database all open';
  5  end open_all_pdbs;
  6  /

Gatilho criado.
 

Conectando nos bancos de dados (CDB e PDBs)

Em relação à conexão com os bancos de dados, sejam eles CDBs ou PDBs, os mesmos podem ser acessados da mesma forma que nas versões anteriores, seja utilizando o arquivo TNSNAMES.ora, seja utilizando via o método Easy Connect (EZCONNECT) conforme demonstrado nos exemplos a seguir:

  • sqlplus system/manager@localhost:1521/CDB01
  • sqlplus system/manager@localhost:1521/PDB01
  • sqlplus system/manager@localhost:1521/PDB02

Um dado interessante é que, ao conectarmos a um banco de dados PDB e consultarmos a view de dicionário de dados V$DATABASE, veremos que será mostrado o banco de dados CDB, e não o banco de dados PDB conforme demonstrado abaixo:

C:\>sqlplus system/manager@localhost:1521/PDB01

SQL*Plus: Release 12.1.0.1.0 Production on Ter Fev 3 19:15:00 2014

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

Horário do último log-in bem-sucedido: Ter Fev 3 2014 19:12:04 -02:00

Conectado a:
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> select name from v$database;

NAME
----------------------
CDB01 
  
O exemplo acima nos demonstra de forma mais clara o conceito de containers dentro da arquitetura Multitenant do Oracle 12c. Abaixo podemos verificar através do comando do SQL*Plus SHOW CON_NAME que o container corrente é o PDB01.

SQL> show con_name;

CON_NAME
-----------------------
PDB01  
 
Se quisermos obter o container corrente através de uma instrução SQL, poderemos utilizar a função SYS_CONTEXT conforme exemplo a seguir:

SQL> select sys_context('userenv','con_name') from dual;

SYS_CONTEXT('USERENV','CON_NAME')
---------------------------------
PDB01 
 
Criando usuários comuns e usuários locais

Em relação à criação de usuários no bancos de dados CDBs e PDBs, existe um conceito novo na arquitetura Multitenant do Oracle 12c. Nesse ambiente existem dois tipos de usuários: Usuários comuns (Common Users) e usuários locais (Local Users). Usuários comuns estão presentes em todos os containers (ROOT e PDBs). Já os usuários locais só estão presentes em seus PDBs específicos. Um mesmo usuário local pode existir em mais de um PDB, mas eles não tem qualquer relação um com o outro.

Da mesma forma que existem usuários comuns e locais, também existem roles comuns (Common Roles) e roles locais (Local Roles). Todo o banco de dados CDB possui um ambiente de usuários comuns. Um usuário que existe no container ROOT pode se conectar em qualquer PDB com os privilégios apropriados e, por padrão, são mapeados para todos os PDBs atuais e aos PDBs criados futuramente. Um usuário comum não pode ser criado em um banco de dados PDB, somente em um CDB. Os usuários comuns precisam ser criados utilizando o prefixo C## ou c##. Já os usuários locais podem somente ser criados nos PDBs. Veja o exemplo abaixo:

C:\>sqlplus system/manager@localhost/PDB01

SQL*Plus: Release 12.1.0.1.0 Production on Seg Fev 3 19:20:16 2014

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

Horário do último log-in bem-sucedido: Seg Fev 03 2014 19:19:16 -02:00

Conectado a:
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> create user scott identified by tiger;

Usuário criado.

SQL> grant create session to scott;

Concessão bem-sucedida. 
 
Acima, eu conectei no banco de dados PDB01 e criei o usuário local SCOTT. Ao consultar a view de dicionário de dados ALL_USERS, poderemos ver abaixo que tanto o usuário SCOTT quanto o usuário PDB_ADMIN (criado durante a criação do banco de dados PDB01), possuem o valor "NO" na coluna COMMON, o que significa que os mesmos são usuários locais do banco de dados PDB01.

SQL> select username,common from all_users where common='NO';

USERNAME                   COM
-------------------------- ---
PDB_ADMIN                   NO
SCOTT                       NO
 
Abaixo irei criar um usuário comum no banco de dados CDB. Podemos verificar abaixo que se tentarmos criar um usuário comum se usar o prefixo C## o erro ORA-65096 será emitido.

C:\>sqlplus system/manager@localhost/CDB01

SQL> create user global identified by global;
create user global identified by global
            *
ERRO na linha 1:
ORA-65096: nome de atribuição ou de usuário comum inválido

SQL> create user c##global identified by global;

Usuário criado.
 
Após a criação do usuário comum C##GLOBAL, irei conceder o privilégio CREATE SESSION de forma que o mesmo possa se conectar tanto no banco de dados CDB01 quanto nos bancos de dados PDBs através da cláusula CONTAINER=ALL do comando GRANT.

SQL> grant create session to c##global;

Concessão bem-sucedida.

SQL> grant create session to c##global container=ALL;

Concessão bem-sucedida.  

Após a concessão do privilégio CREATE SESSION em conjunto com a opção CONTAINER=ALL para o usuário comum C##GLOBAL, poderemos verificar abaixo que a conexão com o banco de dados PDB02, por exemplo, será realizada com sucesso.

C:\>sqlplus C##global/global@localhost/PDB02

SQL*Plus: Release 12.1.0.1.0 Production on Ter Fev 3 19:30:56 2014

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

Horário do último log-in bem-sucedido: Seg Fev 3 2014 19:25:24 -02:00

Conectado a:
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> show user;
USER é "C##GLOBAL"

SQL> show con_name;

CON_NAME
----------------------
PDB02


Resumo

Para ilustrar um pouco do que foi demonstrado nesse artigo, segue abaixo uma figura que resume bem o conceito por trás da arquitetura Multitenant do Oracle 12c.



Para finalizar, segue abaixo alguns exemplos das opções que temos para abrir (startup) e fechar (shutdown) um banco de dados plugável no Oracle 12c. Em alguns dos exemplos, entenda o caractere | (pipe) como ENTER.


-- startup
  • alter pluggable database PDB01 open;
  • alter pluggable database PDB01 open read only;
  • alter pluggable database PDB01, PDB02 open;
  • alter pluggable database all open;
  • startup pluggable database PDB01;
  • alter session set container=PDB01; | startup

-- shutdown

  • alter pluggable database PDB01 close immediate;
  • alter pluggable database all close immediate;
  • alter pluggable database all except PDB02 close immediate;
  • sqlplus sys@PDB01 as sysdba | shutdown immediate;



21 comentários:

João Lucas disse...

Grande Legatti, tudo bom?

Já trabalhei com Oracle e com PostgreSQL, atualmente não tenho contato com DB, mas há tempos tenho uma dúvida que deve ser bastante trivial, mas muito útil para developers: Qual a relação e diferença entre schemas e tenants ?

Oracle e PG possuem schemas e tenants, certo? Eles têm as mesmas reponsabilidades nos dois sistemas?

Eduardo Legatti disse...

Olá João,

Tudo bem? Se me lembro bem, no PostgreSQL os schemas são namespaces para tabelas. Não sei se seria correto dizer que um schema no PostgreSQL poderia ser considerado como um tenant. Esse é um termo bem complicado. Um schema poderia fazer um papel de um tenant, ou seja, um cliente ou empresa dentre vários clientes/empresas que acessam a mesma camada de banco de dados e vejam seus dados de forma segregada? Na minha opinião, sim. Separar em schemas? Pode ser. Me lembro que ao desenvolver o modelo de dados no PostgreSQL, eu divida as várias tabelas dos sistemas em seus respectivos shemas. Todos os sistemas eram integrados e tinham relacionamentos entre eles. Utilizávamos muito a variável "search_path" para não ter que qualificar as tabelas com os schemas. Em um modelo de dados multitenant, teríamos uma mesma tabela em vários schemas distintos sem qualquer conflito entre eles. Na época preferimos segregar os dados utilizando o código da empresa/cliente entre as várias tabelas existentes. Uma outra opção poderia ser criar bancos de dados separados onde cado banco poderia ser um tenant. Geralmente vejo um banco de dados e vários schemas distintos, ou seja, um banco de dados para todos os tenants, mas um schema por tenant.

No caso do Oracle 12c, o recurso do multitenant foi arquitetado via containers. Neste modelo vários tenants são executados na mesma instância. O ambiente de execução é compartilhado entre vários conteiners. Lembre-se que nas versões do Oracle anteriores ao 12c, não podíamos ter usuários/schemas duplicados em um mesmo banco de dados. No Oracle 12c isso é possível através dessa arquitetura multitenancy via conteiners. Acredito que nesse caso, o Oracle 12c se diferencia do PostgreSQL em relação a essa propriedade.

Abraços e até mais...

Legatti

Fábio Prado disse...

Eduardo, ótimo artigo, mais 1 p/ eu recomendar p/ alunos qdo me perguntarem sobre o assunto!

A arquitetura Multitenant representa um grande avanço na consolidação e administração de BDs Oracle, mas é um recurso que já existe (sem esse nome e toda a propaganda por trás do recurso), por exemplo, no SQL Server, há mais de 1 década, e a Microsoft não cobra nada a mais p/ podermos utilizá-lo.

Adoro Oracle, mas infelizmente vejo muita gente deixar de usar muitos recursos por causa dos altos custos das options!

Eduardo Legatti disse...

Olá Fábio,

Realmente não sei se faz muito sentido cobrar por uma coisa que já está aí a décadas em outras plataformas. A operação de "detach" and "attach" do SQL Server por exemplo, eu acho bem simples e prática. Tem muitas coisas legais em outras plataformas!!

Obrigado pela visita!

Abraços

Legatti

Wellington Prado disse...

Ótimo artigo Eduardo! Bem direto e fácil compreensão.
Parabéns...

Forte abraço...

Eduardo Legatti disse...

Olá Wellington,

Obrigado pela visita!

Abraços e até mais

Legatti

Unknown disse...

Otimo Post, muito didático! Parabens.

Abraço,

Marcelo Graçadio

Eduardo Legatti disse...

Olá Marcelo,

Obrigado pela visita e pelo comentário!

Abraços e até mais

Legatti

Rui Barros disse...

Excelente post, Legatti! Abraço

Eduardo Legatti disse...

Olá Rui,

Obrigado pela visita e pelo comentário ;-)

Abraços

Legatti

Unknown disse...

Boa noite, muito boa sua explicação parabéns, agora uma pergunta quantos cdb eu posso ter?
Ou somente 1?
Mais uma vez ti parabenizo!!!

Eduardo Legatti disse...

Olá Rodrigo,

Pode ter mais de um sem problemas. CDB1, CDB2, CDB3, etc.

Abraços,

Legatti

Unknown disse...

Boa noite, qual é o comando pra criar um cdb? Desde já agradeço

Eduardo Legatti disse...

Olá Rodrigo,

Criar um banco de dados, envolve a execução de vários scripts complementares, por isso utilizo o DBCA. No entanto, você pode gerar os scripts de criação pelo próprio DBCA na última tela do mesmo.

Enfim, segue um exemplo:

CREATE DATABASE "cdb1"
MAXINSTANCES 8
MAXLOGHISTORY 1
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 1024
DATAFILE '/u01/app/oracle/oradata/cdb1/system01.dbf' SIZE 700M REUSE
AUTOEXTEND ON NEXT 10240K MAXSIZE UNLIMITED
EXTENT MANAGEMENT LOCAL
SYSAUX DATAFILE '/u01/app/oracle/oradata/cdb1/sysaux01.dbf' SIZE 550M REUSE
AUTOEXTEND ON NEXT 10240K MAXSIZE UNLIMITED
SMALLFILE DEFAULT TEMPORARY TABLESPACE TEMP TEMPFILE '/u01/app/oracle/oradata/cdb1/temp01.dbf' SIZE 20M REUSE
AUTOEXTEND ON NEXT 640K MAXSIZE UNLIMITED
SMALLFILE UNDO TABLESPACE "UNDOTBS1" DATAFILE '/u01/app/oracle/oradata/cdb1/undotbs01.dbf' SIZE 200M REUSE
AUTOEXTEND ON NEXT 5120K MAXSIZE UNLIMITED
CHARACTER SET AL32UTF8
NATIONAL CHARACTER SET AL16UTF16
LOGFILE GROUP 1 ('/u01/app/oracle/oradata/cdb1/redo01.log') SIZE 50M,
GROUP 2 ('/u01/app/oracle/oradata/cdb1/redo02.log') SIZE 50M,
GROUP 3 ('/u01/app/oracle/oradata/cdb1/redo03.log') SIZE 50M
USER SYS IDENTIFIED BY "&&sysPassword" USER SYSTEM IDENTIFIED BY "&&systemPassword"
enable pluggable database
seed file_name_convert=('/u01/app/oracle/oradata/cdb1/system01.dbf','/u01/app/oracle/oradata/cdb1/pdbseed/system01.dbf',
'/u01/app/oracle/oradata/cdb1/sysaux01.dbf','/u01/app/oracle/oradata/cdb1/pdbseed/sysaux01.dbf',
'/u01/app/oracle/oradata/cdb1/temp01.dbf','/u01/app/oracle/oradata/cdb1/pdbseed/temp01.dbf',
'/u01/app/oracle/oradata/cdb1/undotbs01.dbf','/u01/app/oracle/oradata/cdb1/pdbseed/undotbs01.dbf');


Abraços,

Legatti

Lilian Barroso disse...

Mais um artigo excepcional.
Parabéns!

Eduardo Legatti disse...

Olá Lilian,

Obrigado pela visita!!

Abraços,

Legatti

Unknown disse...

Eduardo, parabéns pelo seu artigo. Inclusive estou indicando para outros profissionais da nossa área, por ser de fácil compreensão.

Onde presto serviços de consultoria em banco de dados atualmente, estamos migrando para o DB Oracle 12c e já iniciaremos com arquitetura Multitenant.

At.

Fabio Fonseca

Eduardo Legatti disse...

Olá Fábio,

Obrigado pela visita!!


Abraços,

Legatti

Unknown disse...

Seu artigo está bem didádico. Mas, a Oracle joga pesado com usuários que utilizam o Standard Edition, que é um banco "capado"; e apesar da arquitetura Multitenant ser um avanço no Oracle a partir da 12c, no Standard Edition que é um banco básico essa abordagem passa longe no que se refere a CDBs e PDBs. As diversas features disponibilizadas no Enterprise, não podem ser utilizadas no Standard, e a diferença de preço entre a versão SE e EE é absurda.

Sidney França disse...

Excelente artigo, Eduardo! Parabéns!

Uma dúvida: Qual seria a configuação do tnsnames.ora e do listener.ora num ambiente com vários pdbs como no exemplo que você usou?

Abraços!

Eduardo Legatti disse...

Olá Sidney,

Em relação à conexão com os bancos de dados, sejam eles CDBs ou PDBs, os mesmos podem ser acessados da mesma forma que nas versões anteriores, seja utilizando o arquivo TNSNAMES.ora, seja utilizando via o método Easy Connect (EZCONNECT) conforme demonstrado nos exemplos a seguir:

sqlplus system/manager@localhost:1521/CDB01
sqlplus system/manager@localhost:1521/PDB01
sqlplus system/manager@localhost:1521/PDB02

Abraços

Postagens populares