sqlldr标准输出未处理导致批处理挂起问题
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,1问题生产环境一个批量处理没有完成。2分析批量处理逻辑:java->shell->sqlldr检查数据库会话,发现对应会话等待事件为SQL*Net message from client,对应v$se
千家信息网最后更新 2026年11月01日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安全错误
数据库的锁怎样保障安全
新华互联网科技
互联网是第几次科技革命的成果
上海卓越科技互联网
金融科技还是互联网
金融科技创新监管互联网金融
易互联网科技有限公司
科技服务与互联网
唐信互联网科技
顺网科技2021年互联网排名
中国最先进互联网科技公司
广州慧亚互联网科技怎么样
移动互联网科技股
互联网软件和科技
知域互联网科技有限公司大骗子
互联网与医疗科技
科技互联网的核心竞争力
同城互联网络科技
数字互联网科技有限公司
现代互联网科技公司
互联网科技企业文化
中国互联网科技股
圆梦互联网科技
与互联网科技公司
互联网金融 科技金融
承德科技产业互联网发展
宁夏众和广鑫互联网科技有限公司
互联网科技大赛获奖感言
互联网安防科技感
互联网高科技行业有哪些企业
重庆科技产业互联网有哪些