ORA-31623: a job is not attached to this session via the specified handle

本文解决了一个在使用Oracle Datapump API时遇到的ORA-31623错误,通过分析发现错误原因是由于未正确处理作业(job)导致的遗留表问题。文章详细记录了解决过程,并给出了具体的解决方案。

在使用Oracel Datapump API时碰到ORA-31623(a job is not attached to this session via the specified handle)错误,从故障描述来
看提示 job并没有成功附加到当前session指定的handle。该package的导入导出一直正常运行究竟是什么原因导致的呢?我们拭目以待......

1、故障环境 SQL> select * from v$version where rownum<2; BANNER ---------------------------------------------------------------- Oracle Database 10g Release 10.2.0.4.0 - 64bit Production 2、异常方式与异常现象 当前package的使用情况是使用schema为goex_admin执行时正常,而使用goex_webuser执行时收到错误提示。 即使用不同的用户来执行时存储过程异常.而在此之前类似的问题并不存在,即无论用哪个schema来实现datapump都成功执行。 被调用的存储过程为:goex_admin.FNO_SYS_DATAPUMP_PKG.export_dump -->下面是调用时出现的异常现象 SQL> DECLARE 2 dump_name_in VARCHAR2(32767); 3 overwrite_existing_in CHAR(1); 4 handle_out NUMBER; 5 err_num NUMBER; 6 err_msg VARCHAR2(32767); 7 8 BEGIN 9 dump_name_in := 'TEST_EXP'; 10 overwrite_existing_in := 'N'; 11 handle_out := NULL; 12 err_num := NULL; 13 err_msg := NULL; 14 15 FNO_SYS_DATAPUMP_PKG.export_dump ( dump_name_in, overwrite_existing_in, handle_out, err_num, err_msg ); 16 DBMS_OUTPUT.Put_Line('HANDLE_OUT = ' || TO_CHAR(handle_out)); 17 DBMS_OUTPUT.Put_Line('ERR_NUM = ' || TO_CHAR(err_num)); 18 DBMS_OUTPUT.Put_Line('ERR_MSG = ' || err_msg); 19 20 DBMS_OUTPUT.Put_Line(''); 21 COMMIT; 22 END; 23 / DECLARE * ERROR at line 1: ORA-20001: FNO_SYS_DATAPUMP_PKG.export_dump debugpos=210 (dumpname = TEST_EXP, -->这段信息给出了代码中错误所在的位置为210 handle = null) ORA-06512: at "GOEX_ADMIN.FNO_SYS_DATAPUMP_PKG", line 738 ORA-06512: at line 15 3、分析异常 -->初步判断有可能是存在权限问题,但以前适用goex_webuser也一直正常,我们来看看代码中的210处位置 BEGIN -- Drop table 'Go_Data_Dumping_Job ' debugpos := 200; drop_db_table( tbl_in => c_db_dump_job_name ); -->此为同一package的过程用于删除已经存在的job debugpos := 210; -- Create Datapump Job hand := -->从210位置来判断,应该是job没有被open,然后就跳到exception的others部分 DBMS_DATAPUMP.open( operation => 'EXPORT' -->由于给出的error 信息不够详细很难以发现到底问题出在哪里 , job_mode => 'SCHEMA' , job_name => c_db_dump_job_name , version => 'LATEST' ); EXCEPTION WHEN DBMS_DATAPUMP.job_exists THEN debugpos := 220; EXECUTE IMMEDIATE 'drop table ' || c_db_dump_job_name; debugpos := 230; hand := DBMS_DATAPUMP.open( operation => 'EXPORT' , job_mode => 'SCHEMA' , job_name => c_db_dump_job_name , version => 'LATEST' ); WHEN OTHERS THEN raise_application_error( -20001, myspname || ' debugpos=' || TO_CHAR( debugpos ) || ' (dumpname = ' || dump_name_in || ', handle = ' || NVL( TO_CHAR( hand ), 'null' ) || ')' ); END; -->修改EXCEPTION的WHEN OTHERS THEN部分,以便能抛出未知异常.使用下面的代码来替换(v_err_code,v_err_msg声明部分略) v_err_code := SQLCODE; v_err_msg := SUBSTR( SQLERRM, 1, 200 ); DBMS_OUTPUT.put_line( 'Error code: '|| v_err_code ); DBMS_OUTPUT.put_line( 'Error message: '|| v_err_msg ); SQL> show user; USER is "GOEX_WEBUSER" SQL> alter package goex_admin.FNO_SYS_DATAPUMP_PKG compile; Package altered. SQL> alter package goex_admin.FNO_SYS_DATAPUMP_PKG compile body; Package body altered. -->再次执行则ORA-31623错误出现,为故障的解决提供了线索 SQL> DECLARE 2 dump_name_in VARCHAR2(32767); 3 overwrite_existing_in CHAR(1); 4 handle_out NUMBER; 5 err_num NUMBER; 6 err_msg VARCHAR2(32767); 7 8 BEGIN 9 dump_name_in := 'X'; 10 overwrite_existing_in := 'N'; 11 handle_out := NULL; 12 err_num := NULL; 13 err_msg := NULL; 14 15 goex_admin.FNO_SYS_DATAPUMP_PKG.export_dump ( dump_name_in, overwrite_existing_in, handle_out, err_num, err_msg ); 16 COMMIT; 17 END; 18 / DECLARE * ERROR at line 1: ORA-31623: a job is not attached to this session via the specified handle ORA-06512: at "GOEX_ADMIN.FNO_SYS_DATAPUMP_PKG", line 709 ORA-06512: at line 15 SQL> ho oerr ora 31623 31623, 00000, "a job is not attached to this session via the specified handle" // *Cause: An attempt to reference a job using a handle which is invalid or // no longer valid for the current session. // *Action: Select a handle corresponding to a valid active job or start a // new job. -->分析上面的ORA描述job不能附加到指定的handle.其Action是选择一个有效的handle或启动一个新的job. -->Google了一下该ORA,有个关于这个问题的描述是由于当前schema(goex_webuser)没有创建表的权限. -->于是按下面的方式授予goex_webuser建表权限,当时并没有检查该权限是否授予,而是直接为其授予. SQL> conn sys / as sysdba Enter password: Connected. SQL> grant create any table to goex_webuser; Grant succeeded. SQL> conn goex_webuser/goex_webuser; Error accessing PRODUCT_USER_PROFILE Warning: Product user profile information not loaded! You may need to run PUPBLD.SQL as SYSTEM Connected. SQL> DECLARE 2 dump_name_in VARCHAR2(32767); 3 overwrite_existing_in CHAR(1); 4 handle_out NUMBER; err_num NUMBER; 5 6 err_msg VARCHAR2(32767); 7 8 BEGIN 9 dump_name_in := 'X'; 10 overwrite_existing_in := 'N'; 11 handle_out := NULL; 12 err_num := NULL; 13 err_msg := NULL; 14 15 goex_admin.FNO_SYS_DATAPUMP_PKG.export_dump ( dump_name_in, overwrite_existing_in, handle_out, err_num, err_msg ); 16 COMMIT; 17 END; 18 / PL/SQL procedure successfully completed. -->授予create any table权限之后存储过程成功执行了 4、故障再现 -->后续再次使用GOEX_WEBUSER执行时故障依旧 SQL> show user; USER is "GOEX_WEBUSER" SQL> DECLARE 2 dump_name_in VARCHAR2(32767); 3 overwrite_existing_in CHAR(1); 4 handle_out NUMBER; 5 err_num NUMBER; 6 err_msg VARCHAR2(32767); 7 8 BEGIN 9 dump_name_in := 'N'; 10 overwrite_existing_in := 'N'; 11 handle_out := NULL; 12 err_num := NULL; 13 err_msg := NULL; 14 15 goex_admin.FNO_SYS_DATAPUMP_PKG.export_dump ( dump_name_in, overwrite_existing_in, handle_out, err_num, err_msg ); 16 COMMIT; 17 END; 18 / DECLARE * ERROR at line 1: ORA-31623: a job is not attached to this session via the specified handle ORA-06512: at "GOEX_ADMIN.FNO_SYS_DATAPUMP_PKG", line 709 ORA-06512: at line 15 SQL> / DECLARE * ERROR at line 1: ORA-31623: a job is not attached to this session via the specified handle ORA-06512: at "GOEX_ADMIN.FNO_SYS_DATAPUMP_PKG", line 709 ORA-06512: at line 15 SQL> / DECLARE * ERROR at line 1: ORA-31623: a job is not attached to this session via the specified handle ORA-06512: at "GOEX_ADMIN.FNO_SYS_DATAPUMP_PKG", line 709 ORA-06512: at line 15 5、进一步分析 -->检查alert log file发现下列提示信息,且不论是使用GOEX_WEBUSER还是使用GOEX_ADMIN都出现该提示 kupprdp: master process DM00 started with pid=28, OS id=6858 to execute - SYS.KUPM$MCP.MAIN('Go_Data_Dumping_Job', 'GOEX_WEBUSER', 'KUPC$C_1_20120321131105', 'KUPC$S_1_20120321131105', 0); kupprdp: worker process DW01 started with worker id=1, pid=29, OS id=6862 to execute - SYS.KUPW$WORKER.MAIN('Go_Data_Dumping_Job', 'GOEX_WEBUSER'); Wed Mar 21 13:13:00 2012 The value (30) of MAXTRANS parameter ignored. Wed Mar 21 13:13:10 2012 The value (30) of MAXTRANS parameter ignored. -->这个提示每执行一次就提示一次,对应上面执行语句时使用 “/”来再次执行PL/SQL The value (30) of MAXTRANS parameter ignored. The value (30) of MAXTRANS parameter ignored. Wed Mar 21 14:13:46 2012 The value (30) of MAXTRANS parameter ignored. kupprdp: master process DM00 started with pid=30, OS id=12040 to execute - SYS.KUPM$MCP.MAIN('Go_Data_Dumping_Job', 'GOEX_ADMIN', 'KUPC$C_1_20120321141346', 'KUPC$S_1_20120321141346', 0); kupprdp: worker process DW01 started with worker id=1, pid=31, OS id=12042 to execute - SYS.KUPW$WORKER.MAIN('Go_Data_Dumping_Job', 'GOEX_ADMIN'); -->关于从alert log file得到的错误信息,Metalink给出了BUG号为:6347775 -->此提示信息是由于在创建备份主表时使用了如下语句: -->CREATE TABLE <table_name> (<columns_list>) INITRANS 10 MAXTRANS 30 -->由于Maxtrans参数在10gR1时已经废弃,所以在告警日志中出现提示,不影响数据的导入导出,仅仅是增大告警日志文件的大小 -->由此可知告警日志获得的信息无助于当前故障的解决 -->Metalink上[ID 308388.1]描述ORA-31623为由于流池和Java池导致该故障发生,然使用GOEX_ADMIN导出正常,因此排除这个原因. 6、彻底解决 -->使用sys登陆到数据库,查看视图DBA_DATAPUMP_JOBS DBA_DATAPUMP_JOBS: Identifies all active Data Pump jobs in the database, regardless of their state, on an instance (or on all instances for Real Application Clusters). It also show all Data Pump master tables not currently associated with an active job. -->视图DBA_DATAPUMP_JOBS给出了当前活动JOB相关的一些信息 SQL> conn / as sysdba Connected. -->下面的查询发现有一个名为Go_Data_Dumping_Job的job_name且其owner为GOEX_WEBUSER -->实际上该job_name对应于一个以job_name命名的临时表名 SQL> select owner_name, job_name from dba_datapump_jobs; OWNER_NAME JOB_NAME ------------------------------ ------------------------------ GOEX_WEBUSER Go_Data_Dumping_Job SQL> drop table GOEX_WEBUSER.Go_Data_Dumping_Job purge; drop table GOEX_WEBUSER.Go_Data_Dumping_Job purge * ERROR at line 1: ORA-00942: table or view does not exist SQL> drop table GOEX_WEBUSER."Go_Data_Dumping_Job" purge; -->删除该临时表名 Table dropped. SQL> conn goex_webuser/goex_webuser; Error accessing PRODUCT_USER_PROFILE Warning: Product user profile information not loaded! You may need to run PUPBLD.SQL as SYSTEM Connected. SQL> DECLARE -->再次调用datapump存储过程被成功执行 2 dump_name_in VARCHAR2(32767); 3 overwrite_existing_in CHAR(1); handle_out NUMBER; 4 5 err_num NUMBER; 6 err_msg VARCHAR2(32767); 7 8 BEGIN 9 dump_name_in := NULL; 10 overwrite_existing_in := 'N'; 11 handle_out := NULL; 12 err_num := NULL; 13 err_msg := NULL; 14 15 goex_admin.FNO_SYS_DATAPUMP_PKG.export_dump ( dump_name_in, overwrite_existing_in, handle_out, err_num, err_msg ); 16 COMMIT; 17 END; 18 / PL/SQL procedure successfully completed. -->Author:Robinson Cheng -->Blog: http://blog.youkuaiyun.com/robinson_0612 6、修正代码段 -->为原来的procedure添加如下代码段以生成schema的名字,以避免在删除由于job产生的表名时错误(v_schema应先声明) SELECT SYS_CONTEXT( 'USERENV', 'CURRENT_USER' ) INTO v_schema FROM dual; -->原来的schema能够导出自身的所有对象,且能够删除导出故障时生成的临时表,因此没有报错 WHEN DBMS_DATAPUMP.job_exists THEN debugpos := 220; EXECUTE IMMEDIATE 'drop table ' || v_schema || '.' || c_db_dump_job_name; -->同理procedure drop_db_table也应当添加一个schema参数传入,此处不再演示 7、总结 a、在使用Oracle Datapump API时应注意如果定义了job_name则任意导致job失败或挂起的情形都将导致以job_name命名的table存在. b、对于当前失败的job,再次执行时会碰到job(ORA-31634)已经存在的提示,此时应删除对应表名再使用原来的job_name再次实现Datapump. c、对于出现的故障一般的建议是不要使用自定义的Job_name,由Oracle自动生成Job_name以自动销毁异常的job. d、本文的例子得到的是ORA-31623错误而不是ORA-31634,貌似与ORA-31634 毫不相干,但删除job_name后一切正常. e、在PL/SQL代码中,应尽可能的使用SQLCODE,SQLERRM来抛出不可预知的故障.

更多参考:

数据泵 EXPDP 导出工具的使用

数据泵 IMPDP 导入工具的使用

expdp impdp中 exclude/include 的使用

使用 Oracle Datapump API 实现数据导出

dbms_xplan之display_cursor函数的使用

dbms_xplan之display函数的使用

执行计划中各字段各模块描述

使用 EXPLAIN PLAN 获取SQL语句执行计划

启用 AUTOTRACE 功能

函数使得索引列失效

Oracle 绑定变量窥探

PL/SQL 联合数组与嵌套表

<think>我们正在解决Oracle数据泵导出时出现的UDE-31623ORA-31623错误。根据用户提供的引用(特别是文档ID1907256.1),这个错误的具体描述是:“a jobis notattached tothis sessionvia thespecified handle”(作业没有通过指定的句柄附加到当前会话)。这通常发生在尝试控制(如停止、重启或监控)一个数据泵作业时,但当前会话并没有附加到这个作业。错误原因分析:1.会话未附加作业:可能因为之前的会话已经断开,而作业在后台继续运行,此时在新的会话中尝试重新附加该作业就会失败。2.作业句柄无效:在数据泵操作中,作业句柄(handle)是唯一标识作业的。如果句柄不正确或已失效,就会导致此错误。3.作业已完成或失败:如果作业已经完成(成功或失败)而用户仍尝试附加,也会出现此错误。 解决方案: 根据Oracle官方文档(文档ID1907256.1)[^1][^2],我们可以采取以下步骤:步骤1:检查数据泵作业的状态使用以下SQL查询当前数据库中的数据泵作业状态:```sqlSELECTowner_name, job_name,operation,job_mode, stateFROM dba_datapump_jobs; ```或者(如果没有DBA权限): ```sqlSELECT *FROM user_datapump_jobs; ```步骤2:根据作业状态采取相应措施-如果作业状态(STATE)为`NOTRUNNING`、`FAILED`或`COMPLETED`,则说明作业已经结束,无法重新附加。此时,如果需要重新运行,应该使用新的作业名重新启动导出。-如果作业状态为`EXECUTING`,说明作业正在运行,但当前会话无法附加。这时,我们可以尝试重新附加到作业(见步骤3)。 步骤3:重新附加到运行中的作业(如果作业仍在运行) 在数据泵导出命令中,使用`attach`参数附加到现有作业:```bashexpdp username/passwordATTACH=<job_name> ```其中`<job_name>`是步骤1中查询到的作业名。 步骤4:如果附加成功,则可以在交互模式下控制作业(如停止、重启等)。如果附加失败(例如作业名错误或作业已不存在),则考虑终止该作业并重新启动。 步骤5:终止无法附加的作业(如果作业已挂起且无法附加) 如果作业确实存在但无法附加,且需要停止它,可以使用以下PL/SQL命令(以SYS或拥有权限的用户执行):```sqlDECLAREhdlNUMBER;BEGINhdl :=DBMS_DATAPUMP.ATTACH('<job_name>', '<owner_name>'); --作业名和所有者(从步骤1中获取)DBMS_DATAPUMP.STOP_JOB(hdl,1,0); --立即停止作业END; /``` 注意:如果作业所有者不是当前用户,需要指定所有者。步骤6:重新启动导出作业在清理了无效作业后,使用新的作业名重新启动导出: ```bashexpdpusername/password DIRECTORY=dpump_dirDUMPFILE=export.dmp LOGFILE=export.logJOB_NAME=new_job_name ...``` 预防措施:1.在脚本中使用数据泵时,确保作业名唯一(例如包含时间戳)。 2.在会话中断(如网络断开)后,先检查作业状态再尝试重新附加。3.定期清理已完成的数据泵作业。注意事项: -如果作业已经完成(成功或失败),则不需要终止,直接重新运行即可。-如果作业状态为`DEFINING`,表示作业正在创建,可以稍等片刻再尝试附加。如果上述步骤无法解决问题,可能需要检查数据泵的日志文件(通常位于DIRECTORY参数指定的目录中)以获取更多信息。 相关问题: 1.如何查看Oracle数据泵作业的详细日志?2.如何永久删除Oracle数据泵作业? 3.在Oracle数据泵中,如何从网络故障中恢复导出作业?</think>### 解决 Oracle 数据泵导出错误 UDE-31623 ORA-31623 "job not attached to session handle" 根据您提供的引用文档 ID 1907256.1[^1][^2],这个错误的核心是数据泵作业未能正确附加到当前会话句柄。以下是针对此错误的完整解决方案: #### 错误原因分析 ```mermaid graph TD A[UDE-31623/ORA-31623] --> B[会话句柄丢失] B --> C1[网络中断] B --> C2[会话超时] B --> C3[客户端异常退出] B --> C4[并行操作冲突] B --> C5[作业名重复] A --> D[作业状态不一致] D --> E1[作业仍在运行] D --> E2[作业已停止但未清除] ``` 主要触发场景: 1. **会话中断**:导出过程中网络断开或客户端异常关闭 2. **作业状态残留**:作业仍在数据库后台运行,但会话句柄丢失[^1] 3. **句柄冲突**:多个会话尝试附加同名作业(常见于脚本重复执行) 4. **权限问题**:用户权限变更导致会话无法重新附加作业 #### 解决方案步骤 ##### 1. 检查作业状态(关键步骤) ```sql -- 查询所有数据泵作业状态 SELECT owner_name, job_name, operation, job_mode, state, attached_sessions FROM dba_datapump_jobs WHERE job_name = '<your_job_name>'; -- 替换为实际作业名 -- 若无作业名,查询所有运行中作业 SELECT * FROM dba_datapump_jobs WHERE state = 'EXECUTING'; ``` - ✅ **正常状态**:`STATE = 'EXECUTING'` 且 `ATTACHED_SESSIONS > 0` - ❌ **错误状态**:`STATE = 'NOT RUNNING'` 但作业实际在运行(需强制清理) ##### 2. 重新附加作业(首选方案) ```bash expdp username/password@db \ ATTACH=<job_name> # 从步骤1获取的作业名 ``` - 成功附加后进入交互模式,可选择: - `CONTINUE_CLIENT` 恢复作业 - `STOP_JOB` 安全停止 - 若附加失败,继续下一步 ##### 3. 强制清理残留作业 ```sql DECLARE hdl NUMBER; BEGIN -- 尝试附加作业 hdl := DBMS_DATAPUMP.ATTACH('<job_name>', '<owner_name>'); -- 立即停止并删除作业 DBMS_DATAPUMP.STOP_JOB(hdl, 1, 0); EXCEPTION WHEN OTHERS THEN -- 当附加失败时直接删除作业 DBMS_DATAPUMP.DETACH('<job_name>'); END; / ``` ##### 4. 重启导出作业(预防措施) ```bash expdp username/password@db \ DIRECTORY=dpump_dir \ DUMPFILE=export_%U.dmp \ LOGFILE=export.log \ JOB_NAME=exp_$(date +%s) \ # 使用时间戳确保唯一性 PARALLEL=4 \ CLUSTER=N # 禁用集群选项(规避常见Bug) ``` 关键参数优化: - `JOB_NAME`:添加时间戳保证唯一性(避免 ORA-31623- `CLUSTER=N`:禁用集群模式(解决引用[2]提到的并发Bug) - `PARALLEL`:根据 CPU 核心数设置(公式:$ \text{parallel} \leq \text{CPU\_cores}/2 $) ##### 5. 网络中断处理 若错误由网络中断引起: ```bash # 使用mosh替代ssh(防止会话超时) mosh user@dbserver # 在tmux/screen中启动导出 tmux new-session -s expdp expdp ... # 按Ctrl+B D脱离会话 ``` #### 预防措施 1. **会话管理**: - 使用 `nohup expdp ... &` 或 `tmux` 启动作业 - 设置 SQLNET.EXPIRE_TIME=10(分钟级心跳检测) 2. **作业监控脚本**: ```bash #!/bin/bash # 自动检测并重新附加作业 if ! expdp attach=<job_name>; then echo "Reattaching failed, restarting job..." expdp ... JOB_NAME=exp_$(date +%s) fi ``` 3. **参数优化**(`expdp` 命令行): ```bash COMPRESSION=ALL # 减少网络传输量 NETWORK_LINK=db_link # 远程导出避免客户端中断 ENCRYPTION_PASSWORD=pass # 防止凭据失效 ``` > **重要提示**:如果问题反复出现,请检查 Oracle 集群配置。引用[2]指出该错误常与 Bug 5663241/4173696 相关(集群环境下的句柄同步问题),需应用补丁或设置 `CLUSTER=N`[^2]。 #### 故障排除流程图 ```mermaid graph LR A[出现 ORA-31623] --> B{作业是否存在?} B -->|Yes| C[尝试ATTACH] B -->|No| D[重启新作业] C -->|成功| E[交互控制] C -->|失败| F[强制清理] F --> G[重启新作业] G --> H[添加唯一JOB_NAME] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值