Oracle 11g执行样本数据生成存储过程报socket write错误如何解决
问题排查与解决方案
No more data to read from socket属于Oracle 11g XE的典型前台报错,本质是Oracle后台进程异常终止导致数据库连接被强制断开,可按以下步骤排查解决:
第一步:优先排查what_is_my_personality存储过程问题
该存储过程是触发崩溃的高风险点,大概率是其内部逻辑异常触发了Oracle内核错误:
- 排查是否存在无效递归调用,比如存储过程内部反复调用自身触发栈溢出
- 排查是否用到了11g XE不支持的功能特性,或是存在对系统表的非法访问逻辑
- 排查是否对空值、非法入参未做兼容处理,触发了Oracle未捕获的内核异常
验证方法:手动插入一条student_dim和results测试数据,拿到对应学生id后单独执行exec what_is_my_personality(测试id);,如果单独调用也报错,即可确定是该存储过程的问题,逐行调试其内部逻辑即可。
第二步:排查样本生成存储过程的隐含问题
如果单独调用计算存储过程无异常,再调整样本生成逻辑:
11g XE中INSERT ALL语法和序列、dbms_random组合使用时,偶发会触发内核bug,你可以将INSERT ALL拆分为两个独立的INSERT语句,共用同一个nextId变量即可,修改后参考代码如下:
create or replace procedure generate_sample_data as nextId NUMBER := 0; begin FOR i IN 1 .. 5 LOOP SELECT seq1.nextval INTO nextId FROM dual; -- 插入学生表 INSERT INTO student_dim (id,stu_id,dep_code,fac_code,password,stu_fname,stu_lname,gender,loc_code,age,gp_avg,personality) VALUES (nextId,dbms_random.string('U', 6),default,default,default,default,default,round(dbms_random.value(1,2)),default,round(dbms_random.value(10,80)),round(dbms_random.value(0,5)),NULL); -- 插入结果表 INSERT INTO results (student_id,OPN1,OPN2,OPN3,OPN4,AGG1,AGG2,AGG3,AGG4,NEU1,NEU2,NEU3,NEU4,EXT1,EXT2,EXT3,EXT4,CSN1,CSN2,CSN3,CSN4) VALUES (nextId,round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5)),round(dbms_random.value(0,5))); what_is_my_personality(nextId); END LOOP; COMMIT; end;
同时检查序列seq1的配置,执行select * from user_sequences where sequence_name='SEQ1';确认是否存在缓存为0、开启循环导致生成重复id的问题。
第三步:排查11g XE本身的限制与bug
Oracle 11g Express Edition有固定的资源限制,也存在较多已知版本bug:
- 查看数据库alert日志(默认路径
$ORACLE_BASE/diag/rdbms/xe/XE/trace/alert_XE.log),报错前后的日志会明确记录后台进程崩溃的具体原因,比如是否是ORA-00600内部错误、或是资源不足导致进程被终止 - 11g XE默认最大内存只有1G,如果
what_is_my_personality有大量计算逻辑,可能触发内存不足导致进程崩溃,可尝试调大SGA/PGA配置后再测试 - 如果确认是11.2版本的已知内核bug,可安装对应版本的补丁集,或是将逻辑拆分成分次执行,避免单次调用涉及过多计算量。
内容的提问来源于stack exchange,提问作者Phaki
相关产品推荐
相关产品推荐

