Vivendo e Aprendendo

Experiência prática na administração de Banco de Dados

Transportado schema de um banco para outro [exp e imp]

by Gilberto C. Andrade on 08 abril 2010

Tagged as: Database, Linux, oracle,

Fazer exportação e importação de schemas de usuários de um banco para outro com os utilitários exp e imp não coisa fácil, principalmente se você nunca fez essa tarefa! Mas há sempre uma primeira vez para quase tudo, não é mesmo?

O nosso banco está iniciando e não tem muitos dados, aproximadamente 6GB de tamanho físico. Só a exportação demorou aproximadamente seis horas.
Bom, o passo inicial foi criar um novo banco - isso porque estamos passando da versão 10gR1 intel para 10gR2 ppc - com opções mínimas. O segundo foi realizar o exp no banco original somente dos usuários (schemas) necessários:


    exp userid=system@desenv file=producao.dmp log=export_producao.log buffer=65535000 consistent=y recordlength=65535 grants=y compress=n statistics=none owner=(login,hades,c_hades,ergon,c_ergon,gilberto,kira, epj,rafael,sic)

O terceiro parecia simples, fazer a importação no novo banco.


    #Importando os dados sem as constraints
    imp '/ AS SYSDBA' file=producao.dmp full=y grants=n constraints=n
    #Importando sem os dados com as constraints
    imp '/ AS SYSDBA' file=producao.dmp full=y grants=n constraints=y rows=n

Doce ilusão! Isso não funcionou porque não tínhamos criado os usuários nesse novo banco. Incrível, se é um export e import, por que não tem essa característica por padrão? Já existe a definição de todos os objetos, inclusive dos usuários no dump do exp.

Bom, a solução inicial foi extrair do dump gerado pelo exp, a definição dos schemas dos usuários. Para isso utilizamos o utilitário de sistema strings:


    strings producao.dmp | grep -i "CREATE USER" > create_user.sql  strings producao.dmp | grep -i "GRANT " > grants.sql
    

Que dureza! Veja que isso não ajudou muito porque o arquivo gerado - grants.sql - não faz distinção através do schema. Não entendeu? Vou mostrar:


    oracle@oracleserver:~/backup/scripts> head grants.sql
    GRANT ALTER ON "ACIDENTES_SEQ" TO "HADES" WITH GRANT OPTION
    GRANT SELECT ON "ACIDENTES_SEQ" TO "HADES" WITH GRANT OPTION
    GRANT ALTER ON "ACIDENTES_SEQ" TO "C_HADES" WITH GRANT OPTION
    GRANT SELECT ON "ACIDENTES_SEQ" TO "C_HADES" WITH GRANT OPTION
    GRANT ALTER ON "ACIDENTES_SEQ" TO "C_ERGON" WITH GRANT OPTION
    GRANT SELECT ON "ACIDENTES_SEQ" TO "C_ERGON" WITH GRANT OPTION
    GRANT ALTER ON "AVERB_SEQ" TO "HADES" WITH GRANT OPTION
    GRANT SELECT ON "AVERB_SEQ" TO "HADES" WITH GRANT OPTION
    GRANT ALTER ON "AVERB_SEQ" TO "C_HADES" WITH GRANT OPTION
    GRANT SELECT ON "AVERB_SEQ" TO "C_HADES" WITH GRANT OPTION
    oracle@oracleserver:~/backup/scripts>

Veja que não há definição a qual usuário o objeto pertence. A solução foi realizar o exp para cada usuário separadamente e extrair os grants:


    exp '/ AS SYSDBA' file=login_grants.dmp log=export_archon.log buffer=65535000 consistent=y recordlength=65535 grants=y compress=n statistics=none owner=(login) 
    exp '/ AS SYSDBA' file=ergon_grants.dmp log=export_archon.log buffer=65535000 consistent=y recordlength=65535 grants=y compress=n statistics=none owner=(ergon) 
    exp '/ AS SYSDBA' file=c_ergon_grants.dmp log=export_archon.log buffer=65535000 consistent=y recordlength=65535 grants=y compress=n statistics=none owner=(c_ergon) 
    exp '/ AS SYSDBA' file=hades_grants.dmp log=export_archon.log buffer=65535000 consistent=y recordlength=65535 grants=y compress=n statistics=none owner=(hades) 
    exp '/ AS SYSDBA' file=c_hades_grants.dmp log=export_archon.log buffer=65535000 consistent=y recordlength=65535 grants=y compress=n statistics=none owner=(c_hades) 
    exp '/ AS SYSDBA' file=sys_grants.dmp log=export_archon.log buffer=65535000 consistent=y recordlength=65535 grants=y compress=n statistics=none owner=(sys)     
    strings ergon_grants.dmp | grep "GRANT " > ergon_grants.sql strings c_ergon_grants.dmp | grep "GRANT " > c_ergon_grants.sql strings login_grants.dmp | grep "GRANT " > login_grants.sql
    . . . 

Tem um ditado que acho verdadeiro no nosso mundo TI:

Se eu posso complicar porque vou simplificar!

Você ri não é? Mas você precisava ver a cara do meu chefe depois de 3 dias nessa tarefa.
Depois de tudo isso, tem a caçada dos objetos inválidos que nem o script utlrp.sql resolve.

Ai você diz: “Mas que cara burro! Existe outra maneira de resolver isso muito mais simples.”.
Pois é! Não é burrice não, é inesperiência mesmo! Sem contar na pressão que vc mesmo exerce sobre si para realizar a tarefa. Vc precisa demonstrar que é capaz.

Bom o resultado final é que depois de toda essa luta, encontrei outra maneira fácil de resolver esse problema - extrair a definição de determinados usuários e seus grants -. Muito fácil mesmo. :)

definição

SET pages 9999 SET LINES 180 SET hea off spool create_users_to_move.SQL SELECT 'create user '||username||' identified by '||password|| ' default tablespace '||default_tablespace|| ' temporary tablespace '||temporary_tablespace||';' FROM dba_users WHERE username NOT IN ('DBSNMP','OUTLN','SYS','SYSTEM') ORDER BY username; spool off

grants

SET pages 9999 SET LINES 180 SET hea off spool grants_for_users_to_move.SQL SELECT 'grant '||granted_role||' to '||grantee||';' FROM dba_role_privs WHERE grantee NOT IN ('DBSNMP','OUTLN','SYS','SYSTEM') ORDER BY grantee; /* select 'grant '||privilege||' on '||owner||'.'||table_name|| ' to '||grantee||';' from dba_tab_privs where grantee not in ('DBSNMP','OUTLN','SYS','SYSTEM') and owner not in ('SYS','SYSTEM','DBSNMP','OUTLN') order by grantee; */ spool off
Lembre-se que este script é útil quando há a possibilidade de acessar o banco de origem. Caso contrário, você terá que usar outro método para criar os usuários no banco de destino.
comments powered by Disqus