Durante o upgrade do Oracle Database da versão 11gR2 para 19c, caso o banco de dados possua a option Oracle Label Security (OLS) habilitada, então precisamos executar o script “olspreupgrade.sql” antes de iniciar o upgrade do banco de dados. Este post foca apenas nos detalhes da execução do script olspreupgrade.sql, não abordando o procedimento de desativação do Database Vault que também um requisito para executar o upgrade.
Abaixo a descrição resumida deste requisito, no relatório gerado com o Pre Upgrade Tool (preupgrade.jar):
==============
BEFORE UPGRADE
==============
REQUIRED ACTIONS
================
1. Logged in AS SYSDBA, run $ORACLE_HOME/rdbms/admin/olspreupgrade.sql from
the new Oracle Database 19 home.
olspreupgrade.sql has not been run on this database. To view the number
of records that olspreupgrade.sql moves, use the following command:
SELECT count(*) FROM system.aud$;
As part of the upgrade to 19, records in the 11.2.0.4.0 audit table
SYSTEM.AUD$ are moved to SYS.AUD$. This step can be manually performed
before the upgrade to reduce downtime. Refer to the 19 Oracle Label
Security Administrator's Guide, or to Oracle Database Upgrade Guide for
further details.
Nessa descrição, há um pouco de contradição quanto ela diz que o procedimento é executado como parte de o upgrade e esta etapa “pode” ser executada manulamente antes do upgrade, afim de diminuir o downtime. Na verdade, pelo menos para versão 11gR2, você DEVE executar esse script manualmente antes de iniciar o upgrade, conforme documentação:

Fonte: About Oracle Label Security Upgrades and Downgrades
Tentativa de rodar o upgrade sem executar esta etapa manualmente ainda no Oracle 11gR2, pode fazer procedimento abortar após o erro “ORA-03113: end-of-file on communication channel” (associado com erros ORA-7445 no alert.log) durante a execução do script olspreupgrade.sql com o DB Home 19c, os scripts subsequentes do processo de upgrade apresentam erro porque a sessão foi interrompida na instância:

Como Executar o Script
Quando a recomendação do Pre Upgrade Tool diz “run $ORACLE_HOME/rdbms/admin/olspreupgrade.sql from the new Oracle Database 19 home“, é sobre executar o script olspreupgrade.sql localizado no DB Home 19c, mas conectado na instância ainda no DB Home original (neste caso, 11gR2).
Conforme sugerido pelo manual de upgrade do 19c, optei por copiar o script do DB home 19c para o DB Home original, mas não é necessário, desde que informe o caminho correto no SQLPLUS:
$ export DBHOMENEW=/u02/app/oracle/product/19.0.0.0/dbhome_3 $ cp $DBHOMENEW/rdbms/admin/olspreupgrade.sql $ORACLE_HOME/rdbms/admin
OBS: A variável ORACLE_HOME está apontando para o DB Home 11gR2.
Como a execução pode demorar, coloquei a chamada do SQLPLUS dentro de um script shell e executei com nohup:
$ cat olspreupgrade.sh sqlplus / as sysdba <<EOF set timing on alter session set resumable_timeout=86500; @?/rdbms/admin/olspreupgrade.sql quit; EOF
$ nohup sh olspreupgrade.sh > olspreupgrade.log 2>&1 &
DICA: Neste exemplo estou usufruindo da feature Oracle Resumable Space Allocation, colocando um timeout de 24h (86500 segundos). Dessa forma, se ocorrer qualquer problema relacionado a tablespace, a sessão ficará aguardando uma resolução e poderá continuar de onde parou.
Estimativa de Espaço em Tablespace
O script faz uma estimativa do espaço necessário para realizar o processamento, caso a tablespace da tabela SYSTEM.AUD$ não tenha espaço suficiente para criar uma cópia da tabela no schema SYS, o script irá abortar.
******* BEGINNING OLS PRE UPGRADE SCRIPT ******** The amount of FREE space required = 263778533376 Bytes Free space available on SYSTEM tablespace= 386308800512 Bytes ******** PROCEEDING WITH OLS PRE UPGRADE *******
Neste caso, o script avaliou que a tabela original possuia aproximadamente 246 GB e o espaço livre na tablespace era de aproximadamente 360 GB, então o procedimento poderia prosseguir.
Porém, no meio do processo, a sessão entrou em modo de espera por falta de espaço na tablespace:
SET LINESIZE 300
SET PAGESIZE 500
COL SID FORMAT 99999
COL INST_ID FORMAT 99
COL STATUS FORMAT A10
COL MINUTES FORMAT 9,999
COL START_TIME FORMAT A20
COL SUSPEND_TIME FORMAT A20
COL MSG FORMAT A30
COL SQL_TEXT FORMAT A50
SELECT
SESSION_ID SID,
INSTANCE_ID INST_ID,
STATUS,
ROUND(TIMEOUT/60) MINUTES,
START_TIME,
SUSPEND_TIME,
ERROR_NUMBER || '-'|| ERROR_MSG AS MSG,
SQL_TEXT
FROM DBA_RESUMABLE
WHERE SUSPEND_TIME IS NOT NULL
ORDER BY 2,1;
SID INST_ID STATUS MINUTES START_TIME SUSPEND_TIME MSG SQL_TEXT
------ ------- ---------- ------- -------------------- -------------------- ------------------------------ --------------------------------------------------
17459 1 SUSPENDED 1,442 11/01/21 21:33:09 11/02/21 03:28:12 1652-ORA-01652: unable to exte CREATE TABLE SYS.PREUPG_AUD$ PARALLEL TABLESPACE S
nd temp segment by 8192 in tab YSTEM AS SELECT t.* FROM SYSTEM.AUD$ t
lespace SYSTEM
Viva ao Oracle Resumable Space Allocation, pelo menos o processo não abortou e eu só olhei no dia seguinte.
O erro na estimativa do script é que ele só avalia o tamanho da tabela SYSTEM.AUD$, sem considerar os LOBs vinculados com a tabela. Depois de notar isso, usei a query abaixo para ter uma esimativa mais real de qual seria o tamanho da nova tabela SYS.PREUPG_AUD$:
BREAK ON OWNER SKIP 1
COMPUTE SUM LABEL 'MBYTES' OF MBYTES ON OWNER
SET LINESIZE 300
SET PAGESIZE 100
COL OWNER FORMAT A20
COL SEGMENT_NAME FORMAT A30
COL MBYTES FORMAT 999,999,999
SELECT OWNER, SEGMENT_NAME, SEGMENT_TYPE, SUM(BYTES)/1024/1024 AS MBYTES
FROM DBA_SEGMENTS
WHERE SEGMENT_NAME IN (
select 'AUD$' from dual
union all
select index_name from dba_indexes where table_name='AUD$'
union all
select segment_name from dba_lobs where table_name='AUD$')
GROUP BY OWNER, SEGMENT_NAME, SEGMENT_TYPE
ORDER BY MBYTES DESC;
OWNER SEGMENT_NAME SEGMENT_TYPE MBYTES
-------------------- ------------------------------ ------------------ ------------
SYSTEM SYS_LOB0001460613C00041$$ LOBSEGMENT 414,162
AUD$ TABLE 251,599
SYS_IL0001460613C00040$$ LOBINDEX 0
SYS_LOB0001460613C00040$$ LOBSEGMENT 0
SYS_IL0001460613C00041$$ LOBINDEX 0
******************** ------------
MBYTES 665,761
Então na verdade, adicionando o tamanho do LOB “SYS_LOB0001460613C00041$$”, a tablespace precisaria ter um pouco mais de 650 GB livre.
Após adicionar mais alguns datafiles na tablespace, o procedimento resumiu e concluiu com sucesso.
Após criar a nova tabela, o script faz a limpeza da tabela original executando DELETE em lotes de 100 mil registros, então a tablespace ficará com um bom espaço livre após a execução do script.
Resumo
- Sempre consulte a documentação oficial referente a versão para qual está realizando upgrade (Ex: Requirements for Upgrading Databases That Use Oracle Label Security and Oracle Database Vault)
- Use o script “olspreupgrade.sql” que é disponibilizadopela Oracle no DB Home da nova versão para qual será realizado upgrade
- Execute o script com a instância ainda no DB Home original
- Revise os requisitos de espaço em tablespace e adicione datafiles antecipacamente, quando necessário
- Considere usar a feature Resumable Space Allocation para não perder o progresso em caso de falta de espaço na tablespace