Neste artigo, vamos simular a aplicação de Patch em um ambiente Multitenant, especificamente em um Application Container e seus Application PDBs.
Na consulta abaixo, vemos que a versão de nossa aplicação atual é 2.0:
[oracle@quiasma ~]$ sqlplus sys/oracle@HR_AC as sysdba
SQL*Plus: Release 18.0.0.0.0 - Production on Mon Jul 12 19:24:14 2021
Version 18.13.0.0.0
Copyright (c) 1982, 2018, Oracle. All rights reserved.
Connected to:
Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
Version 18.13.0.0.0
SQL> column app_name format a15
SQL> column app_version format a10
SQL> column app_status format a15
SQL> SELECT APP_NAME, APP_VERSION, APP_STATUS FROM DBA_APPLICATIONS WHERE APP_IMPLICIT='N';
APP_NAME APP_VERSIO APP_STATUS
--------------- ---------- ---------------
HR_APP 2.0 NORMAL
Para iniciar o processo de Patch, vamos executar o script abaixo:
SQL> ALTER PLUGGABLE DATABASE APPLICATION HR_APP BEGIN PATCH 201 MINIMUM VERSION '2.0';
Pluggable database altered.
Vamos alterar uma tabela já existente, adicionando nela uma coluna:
SQL> ALTER TABLE HR.JOB_HISTORY ADD ( NOTES VARCHAR2(20));
Table altered.
Finalizando o processo de patch:
SQL> ALTER PLUGGABLE DATABASE APPLICATION HR_APP END PATCH 201;
Pluggable database altered.
Percebemos que, diferente do processo de UPGRADE, não é criamos um clone do Application Container (o Container “F3315411449_3_1” foi criado no último artigo):
SQL> conn / as sysdba
Connected.
SQL> col name format a20
SQL> SELECT CON_ID, NAME, APPLICATION_ROOT, OPEN_MODE, APPLICATION_ROOT_CON_ID FROM V$PDBS ORDER BY 3,1;
CON_ID NAME APP OPEN_MODE APPLICATION_ROOT_CON_ID
---------- -------------------- --- ---------- -----------------------
2 PDB$SEED NO READ ONLY
3 HIPOFISE2 NO READ WRITE
4 HIPOFISE1 NO READ WRITE
6 HR_PDB1 NO READ WRITE 5
7 HR_PDB2 NO READ WRITE 5
5 HR_AC YES READ WRITE
9 F3315411449_3_1 YES READ WRITE 5
7 rows selected.
Com a consulta abaixo, podemos ver que o Patch foi aplicado com sucesso:
SQL> conn sys/oracle@HR_AC as sysdba
Connected.
SQL> SELECT APP_NAME, PATCH_NUMBER, PATCH_MIN_VERSION, PATCH_STATUS FROM DBA_APP_PATCHES WHERE APP_NAME='HR_APP';
APP_NAME PATCH_NUMBER PATCH_MIN_VERSION PATCH_STAT
--------------- ------------ ------------------------------ ----------
HR_APP 201 2.0 INSTALLED
Porém o mesmo ainda não foi refletido para os Application PDBs, e por conta disso, vamos realizar este sincronismo:
SQL> ALTER SESSION SET CONTAINER=HR_PDB1;
Session altered.
SQL> ALTER PLUGGABLE DATABASE APPLICATION HR_APP SYNC;
Pluggable database altered.
SQL> ALTER SESSION SET CONTAINER=HR_PDB2;
Session altered.
SQL> ALTER PLUGGABLE DATABASE APPLICATION HR_APP SYNC;
Pluggable database altered.
Apesar de não conseguir validar qual PDB está com o patch aplicado (caso alguém saiba como se faz, me mande mensagem por favor!), podemos ver que o patch foi replicado para os Application PDBs com as evidências que virão mais adiante:
SQL> ALTER SESSION SET CONTAINER=HR_AC;
Session altered.
SQL> SELECT APP_NAME, PATCH_NUMBER, PATCH_MIN_VERSION, PATCH_STATUS FROM DBA_APP_PATCHES WHERE APP_NAME='HR_APP';
APP_NAME PATCH_NUMBER PATCH_MIN_VERSION PATCH_STAT
--------------- ------------ ------------------------------ ----------
HR_APP 201 2.0 INSTALLED
SQL> column name format a15
SQL> column app_name format a15
SQL> column app_version format a10
SQL> SELECT C.NAME, APS.APP_NAME, APS.APP_VERSION, APS.APP_STATUS FROM DBA_APP_PDB_STATUS APS JOIN V$CONTAINERS C ON C.CON_UID = APS.CON_UID WHERE APS.APP_NAME = 'HR_APP';
NAME APP_NAME APP_VERSIO APP_STATUS
--------------- --------------- ---------- ---------------
HR_PDB2 HR_APP 2.0 NORMAL
HR_PDB1 HR_APP 2.0 NORMAL
Constatando que a nova coluna (NOTES) se encontra nos Application PDBs:
SQL> ALTER SESSION SET CONTAINER=HR_PDB1;
Session altered.
SQL> DESC HR.JOB_HISTORY
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPLOYEE_ID NOT NULL NUMBER(6)
START_DATE NOT NULL DATE
END_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
DEPARTMENT_ID NUMBER(4)
NOTES VARCHAR2(20)
SQL> ALTER SESSION SET CONTAINER=HR_PDB2;
Session altered.
SQL> DESC HR.JOB_HISTORY;
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPLOYEE_ID NOT NULL NUMBER(6)
START_DATE NOT NULL DATE
END_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
DEPARTMENT_ID NUMBER(4)
NOTES VARCHAR2(20)
Obs: Este procedimento foi criado pelo senhor Ahmed Baraka (www.ahmedbaraka.com) e foi apenas reproduzido por mim em um laboratório pessoal para fins de aprendizado.