sqlldr标准输出未处理导致批处理挂起问题
发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,1问题生产环境一个批量处理没有完成。2分析批量处理逻辑:java->shell->sqlldr检查数据库会话,发现对应会话等待事件为SQL*Net message from client,对应v$se
千家信息网最后更新 2025年02月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安全错误
数据库的锁怎样保障安全
书小说软件开发
网络安全体系规划ppt
战地1看不到服务器ping
小软件开发公司采用项目奖金
ntp服务器搭建win10
筹课网络技术有限公司
部队网络安全稿件
软件开发转软件售前
慈溪一站式软件开发设计
电脑改网络存储服务器
湖北叮咚网络技术
软件开发做全栈的多不多
成都网络技术与新媒体
服务器稳定性标准
网络安全信息第一龙头
湛江智能软件开发
在数据库怎样模拟5g数据
数据库大
java里怎么用数据库
深圳皇家网络技术
体现互联网科技的配色方案
衢州云软件开发教程
维护网络安全人人有责主题班会
工业网络技术的就业方向
nc网络安全防护系统
手机app软件开发说明书
河南省的大数据库在哪
网络安全手抄报模板设计图片
网络安全宣传周毕节
计算机三级网络技术考点