ORA-39405: Oracle Data Pump does not support importing from a source database with TSTZ version 42 into a target database with TSTZ version 32.


Hoy vamos a abordar cómo podemos modificar el TSTZ en un entorno Multitenant y en un Single Instance si hemos encontrado el siguiente error al intentar realizar una importación con Datapump:
ORA-39405:
Oracle Data Pump does not support importing from a source database
with TSTZ version 42 into a target database with TSTZ version 32.
Este error es debido a que el timezone de ambos entornos no coincide. Pero, ¿Podemos realizar el cambio? SI. Eso si, este cambio no se puede realizar sin una verificación previa, vamos a ello.
Single Instance
Para este tipo de entornos, debemos verificar con DBMS_DST cual es la versión más actual de nuestro timezone. Este package fue implementado por Oracle en la versión 11gR2 con el fin de facilitar los procedimientos de actualización de la zona horaria en nuestras bases de datos.
SELECT DBMS_DST.get_latest_timezone_version From Dual;
GET_LATEST_TIMEZONE_VERSION
---------------------------
43
En nuestro caso hemos tenido suerte, ya que la versión coincide con la del entorno de exportación. Sin embargo, ¿qué pasaría si la versión más reciente no coincide? Tendríamos que recurrir al export clásico. Tendríamos que recurrir al export clásico. Este tipo de exportación es un tema diferente que mi compañero de batallas Cele Cueve explica muy bien en su blog. Aquí les dejo el enlace por si desean aprender cómo resolverlo en caso de que no se pueda actualizar:
Si no conocían este blog, les sugiero que lo visiten, ya que publica artículos muy top.
Ahora, vamos a actualizar la zona horaria en el entorno.
Lo primero que vamos hacer es cerrar y abrirla en modo upgrade nuestra base de datos. Una vez abierta, lanzamos el siguiente bloque anónimo para que nuestro entorno este atento de lo que vamos hacer.
SQL> shu immediate
SQL> startup upgrade
SQL>
DECLARE
l_tz_version PLS_INTEGER;
BEGIN
l_tz_version := DBMS_DST.get_latest_timezone_version;
DBMS_OUTPUT.put_line('l_tz_version=' || l_tz_version);
DBMS_DST.begin_prepare(l_tz_version);
END;
/
Comprobamos que la ejecución del bloque anónimo ha ido bien verificando el parámetro DST_SECONDARY_TT_VERSION. Ahí deberíamos ver la versión a la que vamos a subir.
SELECT property_name, property_value
FROM database_properties
WHERE property_name LIKE 'DST_%'
ORDER BY property_name;
PROPERTY_NAME PROPERTY_VALUE
------------------------------ --------------------
DST_PRIMARY_TT_VERSION 32
DST_SECONDARY_TT_VERSION 43
DST_UPGRADE_STATE PREPARE
Antes de confirmar el cambio, vamos a verificar si podríamos tener algún problema con los objetos de nuestra base de datos que se verán afectados. Importante, antes de verificar limpiar las siguientes tablas: SYS.DST$AFFECTED_TABLES y SYS.DST$ERROR_TABLE.
SQL> TRUNCATE TABLE sys.dst$affected_tables;
SQL> TRUNCATE TABLE sys.dst$error_table;
SQL> EXEC DBMS_DST.find_affected_tables;
SQL> Select Decode(count(*),0,'SIN_PELIGRO','CUIDADO') from sys.dst$affected_tables;
DECODE(COUN
-----------
SIN_PELIGRO
SQL> select * from sys.dst$error_table;
no rows selected
Finalizamos la fase de preparación (DBMS_DST.END_PREPARE), cerramos y abrimos de nuevo en modo upgrade para confirmar el cambio de timezone.
SQL> EXEC DBMS_DST.end_prepare;
SQL> shu immediate
SQL> startup upgrade
SQL> SET SERVEROUTPUT ON
DECLARE
l_tz_version PLS_INTEGER;
BEGIN
SELECT DBMS_DST.get_latest_timezone_version
INTO l_tz_version
FROM dual;
DBMS_OUTPUT.put_line('l_tz_version=' || l_tz_version);
DBMS_DST.begin_upgrade(l_tz_version);
END;
/
l_tz_version=43
An upgrade window has been successfully started.
Al terminar nos devolverá la versión instalada
l_tz_version=43
An upgrade window has been successfully started.
Multitenant
El proceso para actualizar la zona horaria será completamente diferente, ya que debemos llevar a cabo la operación en todos los contenedores. Mike Dietrich lo explica de manera clara en su sitio web.
https://mikedietrichde.com/2018/12/18/how-to-patch-all-pdbs-with-the-a-new-time-zone-file/
Así que vamos a ello.
El primer paso que tenemos que verificar es la versión del timezone:
alter system set "_exclude_seed_cdb_view"=false scope=both;
column value$ format a20
select value$, con_id from containers(SYS.PROPS$) where NAME='DST_PRIMARY_TT_VERSION' order by 2
VALUE$ CON_ID
-------------------- ----------
32 1
32 2
32 4
Antes de ejecutar la consulta, lo primero que hicimos fue setear el parámetro _exclude_seed_cdb_view a false antes de lanzar la sql.
Un par de apuntes sobre este parámetro:
Se recomienda configurarlo en false cuando trabajamos con entornos multitenant.
Es un parámetro reservado (empieza por “_”)
Si lo configuramos en true, oculta todo lo relacionado con PDB$SEED en las consultas SQL habituales. Veamos un ejemplo, conectándonos a nuestra CDB$Root y consultando el valor del parámetro cuando conectamos por primera vez (también consultaremos las PDBS que tiene nuestro contendor):
SYS> show parameter _exclude_seed_cdb_view
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
_exclude_seed_cdb_view boolean FALSE
SYS> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 PDB READ WRITE NO
Vamos a ver que nos muestra la consulta anterior con el parámetro a TRUE:
SYS@OSIGBP> alter system set "_exclude_seed_cdb_view"=true scope=both;
System altered.
SYS@OSIGBP> select value$, con_id from containers(SYS.PROPS$) where NAME='DST_PRIMARY_TT_VERSION' order by 2;
VALUE$ CON_ID
-------------------- ----------
32 1
32 3
Muy interesante, podemos observar que la información de PDB$SEED se oculta al setear el valor a true.
Continuamos asegurándonos que tenemos las PDB abiertas
[oracle~]
$ORACLE_HOME/perl/bin/perl $ORACLE_HOME/rdbms/admin/catcon.pl -b tzcheck -d $ORACLE_HOME/rdbms/admin -n 1 -l /tmp utltz_upg_check.sql
...
[oracle~]
$ORACLE_HOME/perl/bin/perl $ORACLE_HOME/rdbms/admin/catcon.pl -b tzapply -d $ORACLE_HOME/rdbms/admin -n 1 -l /tmp utltz_upg_apply.sql
...
La primera sentencia sería como un pequeño test pero sin aplicar “tzcheck“, y la segunda sentencia realiza el cambio “tzapply“.
Verificamos:
column value$ format a20
select value$, con_id from containers(SYS.PROPS$) where NAME='DST_PRIMARY_TT_VERSION' order by 2
VALUE$ CON_ID
-------------------- ----------
43 1
43 2
43 4
Listo. Espero que os sirva.
Subscribe to my newsletter
Read articles from David Sanz directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

David Sanz
David Sanz
Soy desarrollador, Analista, DBA Oracle y Arquitecto OCI, certificado en OCI Migration and Integration Certified Professional y Certified Architect Associate con más de 15 años de experiencia en plataformas Oracle además de especialista en temas de rendimiento.