Migrando um Oracle Autonomous Database (ADW) para outro banco

Geralmente quando falamos em Autonomous Database, estamos falando de levar um banco local para a núvem Oracle, mas nesse caso o procedimento vai ser o inverso, vamos retirar um banco do ADW e coloca-lo em um banco local, o banco de origem (ADW) estava na versão 18c e iremos migrar para a versão 19.9.0 local.

De acordo com a documentação da Oracle, existem algumas formas de se realizar a extração dos dados, e todas envolvem de alguma forma o Object Storage:

To export data from your Autonomous Data Warehouse database to other Oracle databases, use one of the following methods:

Use Oracle Data Pump to export the data from your Autonomous Data Warehouse database to a directory on your database, and then move the data from the directory to your cloud object store.

Use Oracle Data Pump to export the data to your cloud object store directly. This method is only supported with Oracle Cloud Infrastructure Object Storage and Oracle Cloud Infrastructure Object Storage Classic.

Use the procedure DBMS_CLOUD.EXPORT_DATA This method is only supported with Oracle Cloud Infrastructure Object Storage and Oracle Cloud Infrastructure Object Storage Classic.

Como eu não queria “perder” tempo tendo que gerar o arquivo no Object Storage, depois baixa-lo para a minha máquina e só então restaurar o dump, eu usei um parâmetro interessante que é o uso do database link no expdp para gerar o arquivo em minha máquina, os passos executados foram os seguintes:

Configurar a conexão:

Após o banco local instalado, baixe a wallet do seu ADW e coloque ele no servidor, além disso precisamos ajustar o arquivo sqlnet.ora apontando para onde ele deve buscar a wallet, no meu caso ficou assim:

[oracle@srv-db admin]$ cat sqlnet.ora
WALLET_LOCATION = (SOURCE = (METHOD = file) (METHOD_DATA = (DIRECTORY="/home/oracle/wallet_ADW")))
SSL_SERVER_DN_MATCH=yes
[oracle@srv-db admin]$

E no nosso tnsnames podemos usar o de exemplo que já vem no arquivo baixado do ADW:

db01_high =
(description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522) (host=xxxxxxx.oraclecloud.com))
(connect_data=
(service_name=xxxxxxx.adwc.oraclecloud.com))(security=(ssl_server_cert_dn="CN=xxxxxxx.oraclecloud.com")))

A dica aqui é usar a conexão no serviço HIGH pois iremos utilizar parallel para o nosso export.

Teste a sua conexão com um tnsping:

[oracle@srv-db admin]$ tnsping db01_high
TNS Ping Utility for Linux: Version 19.0.0.0.0 - Production on 31-OCT-2020 16:35:04<br>Copyright (c) 1997, 2020, Oracle. All rights reserved
Used parameter files:
/oracle/app/oracle/product/19.0.0/dbhome_1/network/admin/sqlnet.ora
Used TNSNAMES adapter to resolve the alias
Attempting to contact (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522) (host=xxxxxxx.oraclecloud.com)) (connect_data= (service_name=xxxxxxxxxx.adwc.oraclecloud.com)) (security=(ssl_server_cert_dn=CN=xxxxxxxx.oraclecloud.com)))
OK (520 msec)
[oracle@srv-db admin]$

Criando o database link

No seu banco local, crie um database link usando a string de conexão que acabamos de criar:

create database link
adw_origem
connect to
admin
identified by
"SENHA_ADW"
using 'db01_high';

Realizando o export

No nosso export usamos o parâmetro network_link que vai se conectar no database link que criamos e realizar o export para um diretório na máquina de destino, dessa forma já vamos gerando e baixando o dump(o que pode nos economizar um tempo), vale lembrar que para usar o parallel você precisa estar usando uma edição Enterprise.

expdp system/senha network_link=adw_origem directory=expdp_adw dumpfile=expdp_adw_30102020_%u.dmp logfile=EXPDP_ADW.log full=y parallel=6

Realizando o import

Após o export ter terminado(no meu caso levou aproximadamente 2h e gerou 104G de dump), podemos realizar o import mas sem antes precisarmos fazer algumas validações:

Criar tablespaces:

Com esse select você pode ver quais tablespaces são necessárias no seu ambiente, no meu caso apesar de existirem diversas outras, eu só precisava da DATA:

SELECT 
OWNER,
TABLESPACE_NAME
FROM DBA_SEGMENTS
GROUP BY OWNER,TABLESPACE_NAME;
Conferir timezone

No primeiro import que tentei fazer, havia apenas instalado a versão 19c local sem aplicar nenhum patch e peguei o seguinte problema:

Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
ORA-39002: invalid operation
ORA-39405: Oracle Data Pump does not support importing from a source database with TSTZ version 33 into a target database with TSTZ version 32.

Conforme documentado aqui pelo mestre Tim Hall, além de termos versões de banco compatíveis, também precisamos que o Timezone da origem e destino sejam compatíveis, aproveitei para atualizar meu banco e grid para a versão 19.9 (lançada a alguns dias) e quando fui aplicar o patch ele não estava disponível para essa versão, dessa forma copiei os arquivos .dat da versão 19.8 de forma manual para seus respectivos diretórios e segui o post do Tim Hall.

Compress

No ADW uma de suas principais vantagens é estar rodando em cima de um Exadata e utilizar de suas funcionalidades para entregar a parte inteligente, um outro erro que peguei durante meu import foi o seguinte:

ORA-39083: Object type TABLE:"XXXX"."XXXX" failed to create with error:
ORA-64307: Exadata Hybrid Columnar Compression is not supported for tablespaces on this storage type

Que pode ser resolvido na origem retirando a compressão do objeto ou durante o import, criando a tabela manualmente sem a compressão e depois importando os dados ou então como estamos em uma versão mais nova(superior a 12.1) podemos usar o parâmetro transform=table_compression_clause:none que fala para o impdp respeitar a compressão que está definida na nossa tablespace (que no meu caso não possui nenhuma compressão ativa).

Tamanho do campo varchar2

Outro problema que encontrei foi que no ADW ele já vem com o parâmetro MAX_STRING_EXTENDED configurado EXTENDED

ORA-39083: Object type TABLE:"xxxx"."xxxx" failed to create with error:
ORA-00910: specified length too long for its datatype

Para isso basta fazer o seguinte, por sua conta e risco, leia a documentação da Oracle para entender melhor o que essa alteração acarreta.

SHUTDOWN IMMEDIATE;
STARTUP UPGRADE;
alter system set MAX_STRING_SIZE=EXTENDED;
@?/rdbms/admin/utl32k.sql
SHUTDOWN IMMEDIATE;
STARTUP; 
Impdp

Após esse ajuste, o seu import já pode ser realizado com os parâmetros que você precisar:

impdp system directory=expdp_adw dumpfile=expdp_adw_30102020_%u.dmp logfile=impdp_adw.log transform=table_compression_clause:none PARALLEL=6 full=y
chevron_left
chevron_right