首页 » Cloud, ORACLE 9i-23ai » Troubleshooting ORA-39002: invalid operation during datapump TZ version Difference

Troubleshooting ORA-39002: invalid operation during datapump TZ version Difference

最近有个datapump跨数据库迁移数据时,提示”ORA-39002: invalid operation”错误, 排除过目录文件权限和语法兼容问题,后来发现是目标库的Timezone Version低于源库的TZ version. 需要升级目标库的TZ VERSION,这里简单记录该问题.

$ impdp xxx@xxx directory=xxx  dumpfile=xxx.dmp logfile=xxx.log table_exists_action=replace 
Import: Release 18.0.0.0.0 - Production on Tue Mar 22 17:40:58 2022
Version 18.3.0.0.0

Copyright (c) 1982, 2018, Oracle and/or its affiliates.  All rights reserved.

Connected to: Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
ORA-39002: invalid operation

官方文档Oracle Database Globalization Support Guide 对应的版本, 4.7 Upgrading the Time Zone File and Timestamp with Time Zone Data 章节有记录如何升级,可以使用utltz_* ScriptsDBMS_DST Package 完成升级。

# cdb$root
SQL> SELECT * FROM v$timezone_file;

FILENAME		VERSION     CON_ID
-------------------- ---------- ----------
timezlrg_31.dat 	     31 	 0

SQL> alter session set container=pdbanbob;
Session altered.

SQL> SELECT * FROM v$timezone_file;
FILENAME		VERSION     CON_ID
-------------------- ---------- ----------
timezlrg_18.dat 	     18 	 0


SQL> col PROPERTY_VALUE for a30
SQL> col PROPERTY_NAME for a50
SQL> r
  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				   18
DST_SECONDARY_TT_VERSION			   0
DST_UPGRADE_STATE				   NONE

SQL> SELECT * FROM v$timezone_file;

FILENAME		VERSION     CON_ID
-------------------- ---------- ----------
timezlrg_31.dat 	     31 	 0


SQL> alter session set container=pdbanbob;

Session altered.

SQL> SELECT * FROM v$timezone_file;

FILENAME		VERSION     CON_ID
-------------------- ---------- ----------
timezlrg_18.dat 	     18 	 0


SQL> col PROPERTY_VALUE for a30
SQL> col PROPERTY_NAME for a50
SQL> r
  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				   18
DST_SECONDARY_TT_VERSION			   0
DST_UPGRADE_STATE				   NONE


SQL> SELECT DBMS_DST.get_latest_timezone_version FROM dual;

GET_LATEST_TIMEZONE_VERSION
---------------------------
			 31

  1  Select con_id,name,value$ from containers(props$) where name='DST_PRIMARY_TT_VERSION'
  2* order by 1

    CON_ID NAME 			  VALUE$
---------- ------------------------------ ----------
	 1 DST_PRIMARY_TT_VERSION	  31
	 5 DST_PRIMARY_TT_VERSION	  18
	 6 DST_PRIMARY_TT_VERSION	  18
	 8 DST_PRIMARY_TT_VERSION	  18
	 9 DST_PRIMARY_TT_VERSION	  18
	10 DST_PRIMARY_TT_VERSION	  18
...


Note:
注意CDB是31,但是PDB 还是18,之前的升级并不完整。

解决方法
升级低版本的Timezone version

SQL> shutdown immediate
SQL> startup upgrade
SQL> exec dbms_dst.begin_upgrade(31)
SQL> shutdown immediate
SQL> startup

— for pdb

Updating the RDBMS DST version of the CDB will not change the RDBMS_DST version of the PDB’s in this CDB.
Updating the RDBMS DST version of a PDB will not change the RDBMS_DST version of the other PDB’s or the CDB.
When creating a new PDB the RDBMS DST version of new PDB is the RDBMS DST version of PDB$SEED.
The RDBMS DST version of PDB$SEED is the RDBMS_DST version at the CDB creation time (default is DSTv18 for 12.1.0.2 and 12.1.0.1).
The RDBMS DST version of PDB$SEED can currently not be updated.

From 12cR2 onwards, timezone upgrade scripts are included in the target ORACLE_HOME under rdbms/admin directory.

Then set the below to login to PDB.

alter session set container = <pdb_name>;

If pdb name is pdb1, then check below.

alter session set container = pdb1;

Perform the Prepare Window and Upgrade Window in PDB.

Prepare Window

$ cd $ORACLE_HOME/rdbms/admin

SQL> Show con_name

SQL> show con_id

SQL>
SQL> @utltz_countstats.sql
SQL> @utltz_countstar.sql
exec dbms_scheduler.purge_log;
select count(*) from SYS.WRI$_OPTSTAT_HISTGRM_HISTORY;
select count(*) from SYS.WRI$_OPTSTAT_HISTHEAD_HISTORY;

-- check the data retention period of the stats
-- the default value is 31
select systimestamp - dbms_stats.get_stats_history_availability from dual;

-- disable stats retention
exec dbms_stats.alter_stats_history_retention(0);

-- remove all the stats
exec DBMS_STATS.PURGE_STATS(systimestamp);

-- check the result of the purge operation
select count(*) from SYS.WRI$_OPTSTAT_HISTGRM_HISTORY;
select count(*) from SYS.WRI$_OPTSTAT_HISTHEAD_HISTORY;

exec dbms_stats.alter_stats_history_retention(31);

Upgrade Window

Run the utltz_upg_check.sql script from the $ORACLE_HOME directory:
spool utltz_upg_check.log 
@utltz_upg_check.sql 
spool off

Run the utltz_upg_apply.sql script from the $ORACLE_HOME directory after the utltz_upg_check.sql script is executed successfully: This script utltz_upg_apply.sql will shutdown and bring up the database two times.

spool utltz_upg_apply.log
 @utltz_upg_apply.sql 
spool off

 

打赏

对不起,这篇文章暂时关闭评论。