sqlldr标准输出未处理导致批处理挂起问题
发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,1问题生产环境一个批量处理没有完成。2分析批量处理逻辑:java->shell->sqlldr检查数据库会话,发现对应会话等待事件为SQL*Net message from client,对应v$se
千家信息网最后更新 2025年11月07日sqlldr标准输出未处理导致批处理挂起问题1问题
生产环境一个批量处理没有完成。
2分析
批量处理逻辑:
java->shell->sqlldr
检查数据库会话,发现对应会话等待事件为SQL*Net message from client,对应v$session.program为sqlldr@xxx,v$session.seq#保持不变,持续超过5个小时(6:45-12:20)。
查询数据库加载的表,发现已加载部分数据,但对应sqlldr日志为空。
对应sqlldr命令如下:
sqlldr user/pwd data=a.txt control=a.ctl log=a.log bad=a.bad discard=a.dis errors=9999999 rows=1000
在测试环境验证,sqlldr直接运行时,可以顺利加载所有数据;通过java->shell->sqlldr方式运行时,在加载特定行数后停止,问题可以重现。
在进行以上测试时,sqlldr直接运行时,当前窗口会输出已加载了xx行。其实,问题正出在这里。通过java->shell->sqlldr方式运行时,标准输出没有程序读取,在要加载的数据量达到一定程度时(超过缺省缓冲区大小),就会导致加载过程停止。
验证过程参考附录。
3解决方案
处理sqlldr的标准输出与错误输出,可选方法:
方法一: sqlldr ... silent=(ALL)
方法二: sqlldr .... 1>std.log 2>err.log
附,测试脚本
--RunShell.java
import java.util.Date;
import java.text.SimpleDateFormat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class RunShell {
public static void main(String[] args){
try {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String shpath="/home/oracle/java/test.sh";
System.out.println("---1--" + df.format(new Date()));
Process ps = Runtime.getRuntime().exec(shpath);
System.out.println("---2--" + df.format(new Date()));
//ps.waitFor();
BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));
String loop = args[0];
System.out.println(loop);
String line;
while ("0".equals(loop) && (line = br.readLine()) != null) {
System.out.println(line);
}
System.out.println("---3--" + df.format(new Date()));
ps.waitFor();
System.out.println("---4--" + df.format(new Date()));
}
catch (Exception e) {
e.printStackTrace();
}
}
}
--test.sh
seq -w 1 100000|awk '{print $0"xxxxxxxxxxxxxx"}'
测试1--传入参数0,主线程主动读取shell的标准输出
java RunShell 0
---1--2018-04-20 13:23:25
---2--2018-04-20 13:23:25
0
...
...
---3--2018-04-20 13:23:34
---4--2018-04-20 13:23:34
==〉可以顺利完成
测试2--传入参数1,主线程不读取shell的标准输出
java RunShell 1
---1--2018-04-20 13:28:30
---2--2018-04-20 13:28:30
1
---3--2018-04-20 13:28:30
==〉长时间挂起
Ctrl-C
^C---4--2018-04-20 16:37:08
生产环境一个批量处理没有完成。
2分析
批量处理逻辑:
java->shell->sqlldr
检查数据库会话,发现对应会话等待事件为SQL*Net message from client,对应v$session.program为sqlldr@xxx,v$session.seq#保持不变,持续超过5个小时(6:45-12:20)。
查询数据库加载的表,发现已加载部分数据,但对应sqlldr日志为空。
对应sqlldr命令如下:
sqlldr user/pwd data=a.txt control=a.ctl log=a.log bad=a.bad discard=a.dis errors=9999999 rows=1000
在测试环境验证,sqlldr直接运行时,可以顺利加载所有数据;通过java->shell->sqlldr方式运行时,在加载特定行数后停止,问题可以重现。
在进行以上测试时,sqlldr直接运行时,当前窗口会输出已加载了xx行。其实,问题正出在这里。通过java->shell->sqlldr方式运行时,标准输出没有程序读取,在要加载的数据量达到一定程度时(超过缺省缓冲区大小),就会导致加载过程停止。
验证过程参考附录。
3解决方案
处理sqlldr的标准输出与错误输出,可选方法:
方法一: sqlldr ... silent=(ALL)
方法二: sqlldr .... 1>std.log 2>err.log
附,测试脚本
--RunShell.java
import java.util.Date;
import java.text.SimpleDateFormat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class RunShell {
public static void main(String[] args){
try {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String shpath="/home/oracle/java/test.sh";
System.out.println("---1--" + df.format(new Date()));
Process ps = Runtime.getRuntime().exec(shpath);
System.out.println("---2--" + df.format(new Date()));
//ps.waitFor();
BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));
String loop = args[0];
System.out.println(loop);
String line;
while ("0".equals(loop) && (line = br.readLine()) != null) {
System.out.println(line);
}
System.out.println("---3--" + df.format(new Date()));
ps.waitFor();
System.out.println("---4--" + df.format(new Date()));
}
catch (Exception e) {
e.printStackTrace();
}
}
}
--test.sh
seq -w 1 100000|awk '{print $0"xxxxxxxxxxxxxx"}'
测试1--传入参数0,主线程主动读取shell的标准输出
java RunShell 0
---1--2018-04-20 13:23:25
---2--2018-04-20 13:23:25
0
...
...
---3--2018-04-20 13:23:34
---4--2018-04-20 13:23:34
==〉可以顺利完成
测试2--传入参数1,主线程不读取shell的标准输出
java RunShell 1
---1--2018-04-20 13:28:30
---2--2018-04-20 13:28:30
1
---3--2018-04-20 13:28:30
==〉长时间挂起
Ctrl-C
^C---4--2018-04-20 16:37:08
输出
数据
测试
标准
问题
处理
方法
参数
数据库
方式
环境
线程
过程
运行
验证
主动
事件
命令
大小
小时
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
服务器安全检查报告模版
九阴真经 服务器
延边创业软件开发有限公司地址
湖北pdu服务器专用电源直销
数据库语言中and
北京做软件开发工资
助力网络安全工程师考证
申通软件开发商
江苏一朵云互联网科技
验证失败服务器时出错
服务器网络有哪些问题
服务器安全策略端口打开
oracle数据库高可用
哪些服务器有单颗核心
a 数据库系统安全
邢台java微服务架构数据库
英雄联盟香港服务器
软件开发的税
http 2.0 服务器
sap hana数据库的历史
光纤传播与网络技术电子书
香港美国服务云服务器
互联网科技股细分龙头
数据库是一个不断回溯
计算机网络技术专业百度知道
缘启斗罗服务器价格
数据库的常用资源
网络安全的知名公司
河北省检察院网络安全竞赛
青浦区口碑好软件开发诚信服务