viernes, 23 de febrero de 2018

Migración Cross Platform de Base de datos grandes con TRANSPORT TABLESPACE

(Antes de empezar quiero dedicar este artículo a mis alumnos de los cursos oficiales Oracle de diciembre 2017 y enero 2018 que me pidieron la información. ¡Gracias chicos por su tiempo!... Ahora si empezamos)

En algunas ocasiones los DBAs hemos tenido que realizar migraciones Cross Platform, es decir entre sistemas operativos diferentes, tales como Windows, Linux, Solaris, AIX o HP-UX.  Este tipo de migraciones requieren de mucho tiempo de planificación si las bases de datos son muy grandes, complejas y transaccionales.

Analizando un poco las opciones, vemos que utilizar Golden Gate u ODI requiere de un licenciamiento extra; el procedimiento de Oracle Datapump es una opción bastante conocida y es por eso que en este articulo quiero enfocarme en el procedimiento de TRANSPORT TABLESPACE.

Si uno navega por internet podrá encontrar el procedimiento de TRANSPORT TABLESPACE muy bien detallado y explicado, sin embargo, normalmente te explican el procedimiento de manera teórica y con una base de datos de ejemplo que resulta ser bastante pequeña.  Si se aplica el procedimiento teórico a una base de datos de más de 2 Terabytes y muy transaccional tomaría muchísimo tiempo realizar la migración.

Es por eso que en este articulo quiero compartir con Ustedes, de acuerdo a mi experiencia personal, cual es el procedimiento real en la práctica y que puntos debemos tener en cuenta para lograr hacer una migración con TRANSPORT TABLESPACE de manera eficiente y maximizando tiempos.

La migración que me toco realizar fue de Linux hacia AIX y la base de datos comprendida 3.5 Terabytes aproximadamente.

Antes de realizar la migración, tuve que tener en consideración algunos aspectos importantes

1.    Revisión del formato ENDIAN de sistema operativo

El formato ENDIAN es la forma como el Sistema operativo almacena su información; existen 2 tipos de formato Big-endian y Little-endian.  Big-endian almacena en memoria la información de números con el valor de mayor significancia primero, mientras que Little-endian almacena el valor de menor significancia primero. 
Por ejemplo, el número 1460 se almacena en Big-endian como 1460 y en Little-endian como 0641.

Es necesario revisar el formato ENDIAN del sistema operativo origen y destino que forman parte en la migración de base de datos.  Revisamos la vista V$TRANSPORTABLE_PLATFORM para los sistemas operativos LINUX y AIX que son los que intervinieron en la migración que realicé.
.

SQL> select PLATFORM_NAME,ENDIAN_FORMAT from V$TRANSPORTABLE_PLATFORM where PLATFORM_NAME in ('Linux x86 64-bit','AIX-Based Systems (64-bit)');

PLATFORM_NAME                     ENDIAN_FORMAT
--------------------------------- --------------
AIX-Based Systems (64-bit)        Big
Linux x86 64-bit                  Little


Debido a que ambos sistemas operativos tienen diferente formato ENDIAN, utilizamos TRANSPORT TABLESPACE y no Transport Database.


2.    Planificación del movimiento de Datafiles.

Uno de los pasos fundamentales de TRANSPORT TABLESPACE es como copiar la información de todos los Tablespaces de un servidor a otro.
Para la migración que tuve realizar se pensó en replicar los archivos de Linux hacia AIX mediante una base de datos Standby en un servidor intermedio.  Este servidor intermedio puede tener pocos recursos y su espacio es alimentado por espacio asignado en el servidor AIX.

Si la base de datos Standby utiliza Filesystem, se alimenta al servidor intermedio mediante NFS


Si la base de datos Standby utiliza ASM, se realiza la copia de las LUNs del servidor intermedio al servidor destino.


Con esta configuración es posible tener, en tiempo real, los Datafiles de todos los Tablespaces que vamos a migrar en el servidor final AIX.  Además, es posible realizar pruebas de migración sin necesidad de utilizar la base de datos de Producción ya que todo se realiza mediante la instancia Standby en el servidor Intermedio.  



Con la arquitectura lista para migrar, procedemos con los pasos para la migración.
  
Paso 1: Revisión de los Tablespaces
Antes de proceder con la migración es necesario revisar que toda la información que vamos a transportar se encuentre correctamente almacenada en los Tablespaces candidatos.
En la base de datos PROD, utilizamos el procedimiento TRANSPORT_SET_CHECK.  Se debe colocar la lista completa de Tablespaces que vamos a migrar.


SQL> EXEC SYS.DBMS_TTS.TRANSPORT_SET_CHECK (ts_list => 'EFINAN_MDT, TS_CUOTASTOTAL_H_2014, TS_CUOTASTOTAL_H_2015, TS_CUOTASTOTAL_H_2016, TS_CUOTASTOTAL_H_2017…');

PL/SQL procedure successfully completed.
     

Si la lista de Tablespaces es muy grande se puede utilizar el siguiente procedimiento para hacer la revisión.


declare
tbsname clob;
cnt number := 0;
CURSOR tbs is
select tablespace_name from dba_tablespaces where tablespace_name not in ('SYSTEM','UNDOTBS1','SYSAUX','TEMP');
begin
 for cur in tbs loop
     cnt:= cnt + 1;
     if cnt =1 then
         tbsname := cur.tablespace_name||',';
     elsif (cnt = tbs%ROWCOUNT) then
         tbsname := tbsname||cur.tablespace_name;
     else   
         tbsname := tbsname||cur.tablespace_name||',';
     end if; 
  end loop;
  dbms_output.put_line('Count:'||cnt||'  --  Tbsname: '||tbsname);
  dbms_tts.TRANSPORT_SET_CHECK(tbsname,true);
end;


Verificamos si el procedimiento encontró algún problema en los Tablespaces. Revisamos la vista TRANSPORT_SET_VIOLATIONS.
En mi caso no encontró ningún error, pero si se encuentran, es importante solucionarlos antes de empezar con toda la migración.


SQL> SQL> SELECT * FROM transport_set_violations;

no rows selected



Paso 2: Deneter PROD y levantar PROD_STBY en READ WRITE
Ya en ventana de migración, procedemos a detener la base de datos PROD y levantar la base de datos PROD_STBY en READ WRITE.
Para el procedimiento de levantar PROD_STBY podríamos realizar un FAILOVER (10g) o utilizar un SNAPSHOT STANDBY (11g y 12c)

PROD

SQL> alter system switch logfile;
System altered.

SQL> shut immediate
Database closed.
Database dismounted.
ORACLE instance shut down.


PROD_STBY a Snaptshot Standby

SQL> alter database recover managed standby database cancel;
Database altered.

SQL> ALTER DATABASE CONVERT TO SNAPSHOT STANDBY;
Database altered.

SQL> shut immediate;
ORA-01109: database not open
Database dismounted.
ORACLE instance shut down.

SQL> Startup
ORACLE instance started.



Paso 3: Colocar los Tablespaces en Read Only
En la base de datos PROD_STBY, colocamos todos los Tablespaces que vamos a transportar en READ ONLY.  Para este paso yo preparé un archivo con el comando para cada Tablespaces y luego ejecuté de una sola vez.


[oracle@serv_stby]$ cat read_only.sql
alter tablespace EFINAN_MDT read only;
alter tablespace TS_CUOTASTOTAL_H_2014 read only;
alter tablespace TS_CUOTASTOTAL_H_2015 read only;
alter tablespace TS_CUOTASTOTAL_H_2016 read only;
alter tablespace TS_CUOTASTOTAL_H_2017 read only;
...

[oracle@servidor]$ sqlplus / as sysdba

SQL> @read_only.sql



Paso 4: Exportar la Metadata general de la base de datos.
En la base de datos PROD_STBY, generamos los comandos SQL para los Roles, Directorios y Perfiles.


SQL> set long 4000
SQL> set pagesize 8000
SQL> set linesize 400

SQL> spool roles.sql
SQL> select dbms_metadata.get_ddl ('ROLE’, ROLE) from dba_roles;
SQL> spool off;

SQL> spool perfiles.sql
SQL> select dbms_metadata.get_ddl ('PROFILE’, PROFILE) from dba_profiles;
SQL> spool off;

SQL> spool directorios.sql
SQL> select dbms_metadata.get_ddl ('DIRECTORY’, DIRECTORY_NAME) from dba_directories;
SQL> spool off;


Exportamos los DB Links y los sinónimos públicos.


[oracle@serv_stby]$ expdp system@PROD_STBY dumpfile=dblink_pubsyno.dmp directory=DATA_PUMP_DIR include=DB_LINK,PUBLIC_SYNONYM full=Y



Paso 5: Exportar la información de los usuarios.
En la base de datos PROD_STBY, revisamos primero cual es el Default Tablespace de cada usuario.  Esta información puede ser exportada a un archivo SQL.


SQL> set linesize 400
SQL> set pagesize 8000

SQL> spool default_tablespace.sql
SQL> select 'alter user '||username||' default tablespace '||DEFAULT_TABLESPACE||';' from dba_users;
SQL> spool off;


Con esta información guardada, se procede a colocar el Default Tablespace de todos los usuarios al Tablespace SYSTEM.  Esto se realiza porque los usuarios son importados antes que los Tablespaces en la base de datos destino.


[oracle@serv_stby]$ cat tbs_SYSTEM.sql
alter user SPMCP default tablespace SYSTEM;
alter user SREPLICA default tablespace SYSTEM;
alter user SSAC default tablespace SYSTEM;
alter user SSCF default tablespace SYSTEM;
alter user SSOLI default tablespace SYSTEM;
...

[oracle@servidor]$ sqlplus / as sysdba

SQL> @tbs_SYSTEM.sql


Finalmente creamos un archivo PARFILE con la lista de todos los usuarios a migrar y lanzamos el siguiente EXPDP excluyendo Tablas, Índices y Vistas Materializadas.


[oracle@serv_stby]$ cat users_list.par
SCHEMAS='SPMCP','SPUC','SREPLICA','SSAC','SSCF','SSOLI'…

[oracle@serv_stby]$ expdp system@PROD_STBY DUMPFILE=users_meta.dmp DIRECTORY=DATA_PUMP_DIR logfile=users_meta.log CONTENT=METADATA_ONLY EXCLUDE=TABLE,INDEX, MATERIALIZED_VIEW PARFILE=users_list.par



Paso 6: Exportar la Metadata de las tablas temporales y externas.
Las tablas temporales y externas no son transportadas por el procedimiento TRANSPORT TABLESPACE, por lo que hay que tener mucho cuidado al momento de realizar la migración.
En la base de datos PROD_STBY, se crea un script de Backup para ambos tipos de tablas.


SQL> set linesize 400
SQL> set pagesize 8000
SQL> set long 4000

SQL> spool tablas_Externas.sql
SQL> select trim(dbms_metadata.get_ddl('TABLE',TABLE_NAME,owner)||';') from dba_external_tables where owner!='SYS';
SQL> spool off;

SQL> spool tablas_Temporales.sql
SQL> select trim(dbms_metadata.get_ddl('TABLE',TABLE_NAME,owner)||';')  from dba_tables where TEMPORARY='Y' and owner in ('SPMCP','SPUC','SREPLICA','SSAC','SSCF','SSOLI');
SQL> spool off;



Paso 7: Exportar la Metadata de los Tablespaces.
En la base de datos PROD_STBY, exportamos la Metadata de los Tablespaces a transportar.
Creamos un PARFILE con la lista de todos los Tablespaces antes de ejecutar el EXPDP.


[oracle@serv_stby]$ cat transport_tbs.par
transport_tablespaces=EFINAN_MDT, TS_CUOTASTOTAL_H_2014, TS_CUOTASTOTAL_H_2015, TS_CUOTASTOTAL_H_2016, TS_CUOTASTOTAL_H_2017, …

[oracle@serv_stby]$ expdp system@PROD_STBY directory=DATA_PUMP_DIR dumpfile=tbs_metadata.dmp logfile=tbs_metadata.log PARFILE=transport_tbs.par



Paso 8: Copiamos archivos Dumps.
Todos los archivos DUMP y SQL que hemos generado deben de copiarse al servidor DESTINO para poder proceder con la importación de toda la METADATA.


scp *.dmp oracle@serv_new:/u01/migracion/tts
scp *.sql oracle@serv_new:/u01/migracion/tts



Como se tiene la replicación por NFS o LUNs de los Datafiles de PROD_STBY, los archivos ya se encuentran en el servidor destino listos para realizar la conversión.


Paso 9: Convertir los Datafiles al nuevo formato ENDIAN.
El secreto para acelerar el procedimiento de conversión de Datafiles es utilizar PARALELISMO.  Esto sirve de mucho si tu base de datos tiene una gran cantidad de Datafiles.

En el servidor DESTINO, se crearon dos archivos de tipo RMAN con paralelismo 6 y una larga lista de Datafiles en cada uno.
En cada archivo se realiza la conversión de los Datafiles de LINUX hacia AIX y se copian en el Diskgroup +DGDATA01


[oracle@serv_new]$ cat convert1.rman
run{
allocate channel d1 device type disk;
allocate channel d2 device type disk;
allocate channel d3 device type disk;
allocate channel d4 device type disk;
allocate channel d5 device type disk;
allocate channel d6 device type disk;
CONVERT DATAFILE
'/u02/oradata/FULXT01/datafile/o1_mf_efinan_m_lhqk5dpv_.dbf',
'/u02/oradata/FULXT01/datafile/o1_mf_efinan_m_mcqk5qko_.dbf',
'/u02/oradata/FULXT01/datafile/o1_mf_efinan_m_mfqk5rkp_.dbf',
'/u02/oradata/FULXT01/datafile/o1_mf_efinan_m_mjqk5stg_.dbf',
'/u02/oradata/FULXT01/datafile/o1_mf_efinan_m_mnqk5un6_.dbf',
'/u02/oradata/FULXT01/datafile/o1_mf_efinan_m_mrqk6034_.dbf',
'/u02/oradata/FULXT01/datafile/o1_mf_efinan_m_mvqk61db_.dbf',
'/u02/oradata/FULXT01/datafile/o1_mf_efinan_m_mlqk5tm6_.dbf',
'/u02/oradata/FULXT01/datafile/o1_mf_efinan_m_mpqk5vek_.dbf',
FROM PLATFORM='Linux x86 64-bit' TO PLATFORM='AIX-Based Systems (64-bit)' FORMAT '+DGDATA01' PARALLELISM=6;
release channel d1;
release channel d2;
release channel d3;
release channel d4;
release channel d5;
release channel d6;
}



[oracle@serv_new]$ cat convert2.rman
run{
allocate channel d1 device type disk;
allocate channel d2 device type disk;
allocate channel d3 device type disk;
allocate channel d4 device type disk;
allocate channel d5 device type disk;
allocate channel d6 device type disk;
CONVERT DATAFILE
'/u03/oradata/FULXT01/datafile/o1_mf_efinan_m_ndqk6d53_.dbf',
'/u03/oradata/FULXT01/datafile/o1_mf_efinan_m_m4qk5ngl_.dbf',
'/u03/oradata/FULXT01/datafile/o1_mf_efinan_m_mbqk5q32_.dbf',
'/u03/oradata/FULXT01/datafile/o1_mf_efinan_m_nbqk69p3_.dbf',
'/u03/oradata/FULXT01/datafile/o1_mf_efinan_m_lvqk5lth_.dbf',
'/u03/oradata/FULXT01/datafile/o1_mf_efinan_m_ncqk6d53_.dbf',
'/u03/oradata/FULXT01/datafile/o1_mf_efinan_m_liqk5e6u_.dbf',
'/u03/oradata/FULXT01/datafile/o1_mf_efinan_m_lqqk5jqo_.dbf',
'/u03/oradata/FULXT01/datafile/o1_mf_efinan_m_n2qk62mj_.dbf',
'/u03/oradata/FULXT01/datafile/o1_mf_efinan_m_neqk6gub_.dbf',
FROM PLATFORM='Linux x86 64-bit' TO PLATFORM='AIX-Based Systems (64-bit)' FORMAT '+DGDATA01' PARALLELISM=6;
release channel d1;
release channel d2;
release channel d3;
release channel d4;
release channel d5;
release channel d6;
}


En la base de datos NEW_PROD, se ejecuta la conversión utilizando los dos archivos RMAN creados anteriormente. Es importante revisar los logs para monitorear el procedimiento de conversión.


[oracle@serv_new]$ rman target=/ @ convert1.rman log='convert1.log' &
[oracle@serv_new]$ rman target=/ @ convert2.rman log='convert2.log' &



Paso 10: Importación de Metadata a la base de datos NEW_PROD.
Con todos los Datafiles ya convertidos a formato AIX, es momento de proceder con la importación de toda la información a la nueva base de datos.
En la base de datos NEW_PROD, se realiza la importación de los siguientes objetos en este orden:

·         Roles, Directorios y Perfiles.  Revisar que los archivos SQL tengan los comandos correctos.


[oracle@serv_new]$ sqlplus / as sysdba

SQL>@roles.sql

SQL>@perfiles.sql

SQL>@directorios.sql


·         Los Usuarios. Se excluye las vistas y la cuota de Tablespaces ya que aun no se han transportados a la base de datos NEW_PROD


[oracle@serv_new]$ impdp system@NEW_PROD DUMPFILE=users_meta.dmp DIRECTORY=DATA_PUMP_DIR CONTENT=METADATA_ONLY logfile=users_imp.log EXCLUDE=VIEW,TABLESPACE_QUOTA


·         Los Tablespaces. Se crea un archivo PARFILE con la lista de los nuevos DATAFILES creados en el servidor Destino.


[oracle@serv_new]$ cat datafiles.par
transport_datafiles=
'+DGDATA01/fulxt01/datafile/efinan_mix.292.815072977',
'+DGDATA01/fulxt01/datafile/efinan_mdt.283.815071541',
'+DGDATA01/fulxt01/datafile/efinan_mdt.284.815071727',
'+DGDATA01/fulxt01/datafile/efinan_mdt.285.815071871',
'+DGDATA01/fulxt01/datafile/efinan_mix.293.815073143',
'+DGDATA01/fulxt01/datafile/efinan_mdt.286.815071987',
'+DGDATA01/fulxt01/datafile/efinan_mdt.287.815072171',
'+DGDATA01/fulxt01/datafile/efinan_mix.295.815073443',
'+DGDATA01/fulxt01/datafile/efinan_mdt.288.815072357',
'+DGDATA01/fulxt01/datafile/efinan_mdt.337.816892735’


[oracle@serv_new]$ impdp system@NEW_PROD directory= DATA_PUMP_DIR dumpfile=tbs_metadata.dmp logfile=tbs_meta_imp.log parfile=datafiles.par


·         Las Vistas y Cuotas de Usuario. Una vez que los Tablespaces ya se encuentran agregados a la base de datos NEW_PROD se procede a importar las Vistas y Cuotas de Tablespaces.


[oracle@serv_new]$ impdp system@NEW_PROD DUMPFILE=users_meta.dmp DIRECTORY=DATA_PUMP_DIR CONTENT=METADATA_ONLY logfile=users_view_imp.log INCLUDE=VIEW,TABLESPACE_QUOTA


·         Los DBlinks y Sinónimos Públicos. Con los esquemas y tablas ya importados, se crean los sinónimos públicos y los DBlinks.


[oracle@serv_new]$ impdp system@NEW_PROD DUMPFILE=dblink_pubsyno.dmp DIRECTORY=DATA_PUMP_DIR CONTENT=METADATA_ONLY logfile=dblink_pubsyno_imp.log INCLUDE =DB_LINK,PUBLIC_SYNONYM FULL=Y


Paso 10: Configuración de Tablespaces y Usuarios.
En la base de datos NEW_PROD, configuramos los Tablespaces en modo READ WRITE y definimos el default Tablespace original a cada usuario.


[oracle@serv_new]$ sqlplus / as sysdba

SQL>@tbs_read_write.sql

SQL>@default_tablespace.sql


Recrear las Tablas Externas y Temporales. Revisar que los archivos SQL tengan los comandos correctos.


[oracle@serv_new]$ sqlplus / as sysdba

SQL>@tablas_Externas.sql

SQL>@tablas_Temporales.sql


Paso 11: Compilación de objetos.
En la base de datos NEW_PROD, una vez que todo haya sido importado de manera correcta, se procede a compilar todos los objetos de la base de datos y finalizar la migracion.

[oracle@serv_new]$ sqlplus / as sysdba

SQL> @?/rdbms/admin/utlrp.sql



Conclusión

Como podemos observar, el verdadero procedimiento de TRASNPORT TABLESPACE tiene muchos puntos a tomar en cuenta antes y después del transporte de archivos.  Mientras mas compleja es la base de datos, más cuidado debemos tener durante la migración.
Sin embargo, este articulo les puede servir de guía para lograr una migración de manera exitosa y con menos tiempo del planificado.

3 comentarios:

  1. Muy buena Guia me ayudo bastante..

    ResponderBorrar
  2. Muchas Gracias por compartir, solo un comentario corregir el Titulo dice "TRASNPORT TABLESPACE", lo correcto "TRANSPORT TABLESPACE"

    Luis M.

    ResponderBorrar