大家好,这里是公众号 DBA学习之路,分享一些学习国产数据库路上的知识和经验。
前言
最近遇到好几次数据泵导入报错 ORA-39405 的问题,需要升级时区,本文正好记录一下解决过程。
问题分析
两套 19C 数据库,补丁版本不一致,源端补丁版本高于目标端,需要将源端的用户数据导入到目标端数据库库,在导入的时候报错如下:
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.
查看报错:
[oracle@orcl19c:/home/oracle]$ oerr ora 39405
39405, 00000, "Oracle Data Pump does not support importing from a source database with TSTZ version %s into a target database with TSTZ version %s."
// *Cause: The source database was at a different time zone version than the
// target database and there were tables that contained TIMESTAMP
// WITH TIME ZONE (TSTZ) data.
// *Action: Convert the target database to the same time zone version or
// later as the source database or use Oracle Data Pump with
// conventional data movement to export then import this data.
大致意思就是:
在使用 Oracle Data Pump 进行数据导入时,如果源数据库的时区版本(TSTZ版本)与目标数据库的时区版本不同,就会出现该错误,需要将目标数据库的时区版本更新为与源数据库相同或更高版本。
根据提示,我们需要将目标端数据库时区升级到 42,参考 MOS 文档:
需要安装补丁 Patch 35220732: RDBMS - DSTV42 UPDATE - TZDATA2023C:
- Request (if needed) and download the 18.0/19.0 DSTv42 Patch 35220732
- Unzip the RDBMS DSTv42 Patch 35220732
- Apply the RDBMS DSTv42 Patch 35220732 using Opatch.
下载补丁后,根据 README 提示进行升级时区即可。
解决方案
安装时区补丁
安装补丁需要先关闭数据库:
SQL> shu immediate
安装补丁:
## 进入补丁目录
[oracle@orcl19c:/home/oracle]$ cd /home/oracle/35220732
## 安装前检查
[oracle@orcl19c:/home/oracle]$ $ORACLE_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -ph ./
Oracle Interim Patch Installer version 12.2.0.1.17
Copyright (c) 2025, Oracle Corporation. All rights reserved.
PREREQ session
Oracle Home : /u01/app/oracle/product/19.0.0/db
Central Inventory : /u01/app/oraInventory
from : /u01/app/oracle/product/19.0.0/db/oraInst.loc
OPatch version : 12.2.0.1.17
OUI version : 12.2.0.7.0
Log file location : /u01/app/oracle/product/19.0.0/db/cfgtoollogs/opatch/opatch2025-02-20_17-23-05PM_1.log
Invoking prereq "checkconflictagainstohwithdetail"
Prereq "checkConflictAgainstOHWithDetail" passed.
OPatch succeeded.
## 安装补丁
[oracle@orcl19c 35220732]$ $ORACLE_HOME/OPatch/opatch apply
Oracle Interim Patch Installer version 12.2.0.1.17
Copyright (c) 2025, Oracle Corporation. All rights reserved.
Oracle Home : /u01/app/oracle/product/19.0.0/db
Central Inventory : /u01/app/oraInventory
from : /u01/app/oracle/product/19.0.0/db/oraInst.loc
OPatch version : 12.2.0.1.17
OUI version : 12.2.0.7.0
Log file location : /u01/app/oracle/product/19.0.0/db/cfgtoollogs/opatch/opatch2025-02-20_17-23-11PM_1.log
Verifying environment and performing prerequisite checks...
OPatch continues with these patches: 35220732
Do you want to proceed? [y|n]
y
User Responded with: Y
All checks passed.
Backing up files...
Applying interim patch '35220732' to OH '/u01/app/oracle/product/19.0.0/db'
Patching component oracle.oracore.rsf, 19.0.0.0.0...
Patch 35220732 successfully applied.
Log file location: /u01/app/oracle/product/19.0.0/db/cfgtoollogs/opatch/opatch2025-02-20_17-23-11PM_1.log
OPatch succeeded.
## 检查补丁是否安装完成
[oracle@orcl19c 35220732]$ $ORACLE_HOME/OPatch/opatch lspatches
35220732;RDBMS - DSTV42 UPDATE - TZDATA2023C
29585399;OCW RELEASE UPDATE 19.3.0.0.0 (29585399)
29517242;Database Release Update : 19.3.0.0.190416 (29517242)
OPatch succeeded.
安装完成后开启数据库:
SQL> startup
到这补丁安装就算完成了,接下来还需要执行时区升级。
升级时区
在 MOS 文档中看到升级时区有两种方式:
- using
DBMS_DST package
: 4.7.2 Upgrading the Time Zone Data Using the DBMS_DST Package - using the
utltz_* Scripts
in the$ORACLE_HOME/rdbms/admin
directory:4.7.1 Upgrading the Time Zone Data Using the utltz_* Scripts
这里官方建议使用第二种方式进行升级:
-- 运行 utltz_countstats.sql 显示所有包含 "TIMESTAMP WITH TIME ZONE" 类型的表的优化器统计信息,包括 num_rows(行数)。
SQL> @?/rdbms/admin/utltz_countstats.sql
-- 运行 utltz_countstar.sql 显示了所有包含 "TIMESTAMP WITH TIME ZONE" (TSTZ) 数据类型的表的 count(*) 操作结果。
SQL> @?/rdbms/admin/utltz_countstar.sql
-- 以上两个脚本只需要执行其中一个就行,具体根据统计信息的准确性来选择,第二种需要执行的时间可能较长。
-- dbms_scheduler 表通常包含大量的时区数据,如果不需要该表中的数据,可以在执行升级步骤之前使用以下命令删除它。在运行此命令之前,请停止主要作业,因为如果某些主作业仍在执行,则可能无法删除 dbms_scheduler 表中的所有数据。
SQL> exec dbms_scheduler.purge_log;
-- 其他可能包含大量时区数据的表包括 SYS.WRI$_OPTSTAT_HISTGRM_HISTORY 和 SYS.WRI$_OPTSTAT_HISTHEAD_HISTORY 表。如果您不需要这些数据,可以使用以下命令删除它们:
SQL> select count(*) from SYS.WRI$_OPTSTAT_HISTGRM_HISTORY;
SQL> select count(*) from SYS.WRI$_OPTSTAT_HISTHEAD_HISTORY;
SQL> select systimestamp - dbms_stats.get_stats_history_availability from dual;
SQL> exec dbms_stats.alter_stats_history_retention(0);
SQL> exec DBMS_STATS.PURGE_STATS(systimestamp);
SQL> select count(*) from SYS.WRI$_OPTSTAT_HISTGRM_HISTORY;
SQL> select count(*) from SYS.WRI$_OPTSTAT_HISTHEAD_HISTORY;
-- 等时区数据升级完成,可以使用以下命令将数据保留期限设置回其原始值:
SQL> exec dbms_stats.alter_stats_history_retention(31);
以上为升级时区前的一些准备工作,下面开始正式升级时区:
-- 升级时区
SQL> @?/rdbms/admin/utltz_upg_check.sql
SQL> @?/rdbms/admin/utltz_upg_check.sql
SQL> @?/rdbms/admin/utltz_upg_apply.sql
升级完成后,检查时区版本是否正确:
SQL> col property_name for a30
col value for a30
select property_name, substr(property_value, 1, 30) value
from database_properties
where property_name like 'DST_%'
order by property_name;
PROPERTY_NAME VALUE
------------------------------ ------------------------------
DST_PRIMARY_TT_VERSION 42
DST_SECONDARY_TT_VERSION 0
DST_UPGRADE_STATE NONE
可以看到时区已经升级到 42,再次使用数据泵导入数据成功。
写在最后
这里在延伸一下,从 RU 19.18 开始,时区补丁会跟随 RU 一起安装,但是不会自动更新数据库时区,需要人为执行升级,可参考 MOS:
- Steps to update the timezone after applying 19.18 DBRU & higher (Doc ID 2940808.1)
- Running IMPDP Results In ORA-39405 Despite Not Upgrading DST Version After Installation (Doc ID 3074563.1)
所以,大家建议大家在安装 RU 19.18 之后的补丁,需要手工升级时区:
## 注意:rac 数据库需要先切换成单机模式进行升级
SQL> @?/rdbms/admin/utltz_upg_apply.sql
具体步骤可以参考 MOS 文档内容。