免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 7993 | 回复: 25
打印 上一主题 下一主题

求助仙子:多进程操作oracle出错,如何处理? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-05-24 16:11 |只看该作者 |倒序浏览
本帖最后由 hnwcr 于 2010-05-25 10:43 编辑

问题:爹进程如果不sleep 则程序立即异常,sleep的话只有第一个子进程正常,sleep时间到后,整个程序异常。
请教这是为什么?????? 关键部份的代码贴如下:
$oracle_dbh->{InactiveDestroy}=1; ##参考DBI文档,设成常连
foreach (0..4) ###生成测试5个进程分别处理表中5组数据。表中记录非常之多
    { my $pid=fork();
      $oracle_dbh->{InactiveDestroy}=1;
      if ($pid==0)
        {   ##子进程
            $oracle_dbh->{InactiveDestroy}=1;
            my  $sql_child= qq { select * from hiuinv1o.acc_fund_book
                                 WHERE  MOD(account_id,5)=}.$_;  ###利用account字段按5取余把表中数据分为5个进程待处理的数据
            print $sql_child."\n";
            my    $sth_child=$oracle_dbh->prepare($sql_child);#SQL语句
            $sth_child->execute();
            my    @alt_cursor=(); ##初始化数组
            my    $seq_child=0;
            while(@alt_cursor=$sth_child->fetchrow_array)
            {
                    print $$."\n"; ###有数据就随便打出进程编号
            }
            exit(0);
        }
        elsif ($pid==-1) {print ("fork error\n");
            exit(-1);
        }
        else  ###爹进程
            {sleep 8; ##把这个地方去掉,程序立即结束。保留的话第一个子进程在8秒内运行正常,超过8秒后整个程序异常。
             $oracle_dbh->{InactiveDestroy}=1;}
    }

while(waitpid(-1, WNOHANG)!=-1) {
        my $es=`ps -ef|grep owe`;
        print $es."\n";
}
my  $es=`ps -ef|grep owe`;
print $es."\n";





错误 信息如下:


child 4895000 is running!
select * from hiuinv1o.acc_fund_book
                                 WHERE  MOD(account_id,5)=0

打印第一个子进程的编号无数行
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。
sleep 8后。。。。。。。。。。。。。。。。。。。

child 6267266 is running!
select * from hiuinv1o.acc_fund_book
                                 WHERE  MOD(account_id,5)=1
DBD::Oracle::st execute failed: ORA-03106: fatal two-task communication protocol error (DBD ERROR: OCIStmtExecute) [for Statement " select * from hiuinv1o.acc_fund_book
                                 WHERE  MOD(account_id,5)=1"] at owe.pl line 171.
DBD::Oracle::st fetchrow_array failed: ORA-03115: unsupported network datatype or representation (DBD ERROR: OCIStmtFetch) [for Statement " select * from hiuinv1o.acc_fund_book
                                 WHERE  MOD(account_id,5)=0"] at owe.pl line 174.
DBD::Oracle::st fetchrow_array failed: ERROR no statement executing (perhaps you need to call execute first) [for Statement " select * from hiuinv1o.acc_fund_book
                                 WHERE  MOD(account_id,5)=1"] at owe.pl line 174.
###################################
###################################
child 3494328 is running!
select * from hiuinv1o.acc_fund_book
                                 WHERE  MOD(account_id,5)=2
DBD::Oracle::db prepare failed: ORA-03113: end-of-file on communication channel (DBD ERROR: error possibly near <*> indicator at char 15 in ' select * from <*>hiuinv1o.acc_fund_book
                                 WHERE  MOD(account_id,5)=2') [for Statement " select * from hiuinv1o.acc_fund_book
                                 WHERE  MOD(account_id,5)=2"] at owe.pl line 170.
Can't call method "execute" on an undefined value at owe.pl line 171.
###################################
child 6324638 is running!
select * from hiuinv1o.acc_fund_book
                                 WHERE  MOD(account_id,5)=3
DBD::Oracle::db prepare failed: ORA-03135: connection lost contact (DBD ERROR: error possibly near <*> indicator at char 15 in ' select * from <*>hiuinv1o.acc_fund_book
                                 WHERE  MOD(account_id,5)=3') [for Statement " select * from hiuinv1o.acc_fund_book
                                 WHERE  MOD(account_id,5)=3"] at owe.pl line 170.
Can't call method "execute" on an undefined value at owe.pl line 171.
###################################
child 6402494 is running!
select * from hiuinv1o.acc_fund_book
                                 WHERE  MOD(account_id,5)=4
DBD::Oracle::db prepare failed: ORA-03135: connection lost contact (DBD ERROR: error possibly near <*> indicator at char 15 in ' select * from <*>hiuinv1o.acc_fund_book
                                 WHERE  MOD(account_id,5)=4') [for Statement " select * from hiuinv1o.acc_fund_book
                                 WHERE  MOD(account_id,5)=4"] at owe.pl line 170.
Can't call method "execute" on an undefined value at owe.pl line 171.
###################################
###################################
     wcr  242108 2965682   2 16:13:59 pts/19  0:00 perl owe.pl
     wcr 6402496  242108   0 16:14:36 pts/19  0:00 grep owe

###################################
     wcr  242108 2965682   2 16:13:59 pts/19  0:00 perl owe.pl
     wcr 6324640  242108   0 16:14:36 pts/19  0:00 grep owe

###################################
     wcr  242108 2965682   2 16:13:59 pts/19  0:00 perl owe.pl
     wcr 3494330  242108   0 16:14:36 pts/19  0:00 grep owe

###################################
     wcr  242108 2965682   3 16:13:59 pts/19  0:00 perl owe.pl
     wcr 6267268  242108   0 16:14:37 pts/19  0:00 grep owe

###################################
     wcr  242108 2965682   3 16:13:59 pts/19  0:00 perl owe.pl
     wcr 4895002  242108   0 16:14:37 pts/19  0:00 grep owe

###################################
     wcr  242108 2965682   3 16:13:59 pts/19  0:00 perl owe.pl
     wcr 4895004  242108   0 16:14:37 pts/19  0:00 grep owe

论坛徽章:
0
2 [报告]
发表于 2010-05-24 18:16 |只看该作者
自顶一下。

论坛徽章:
0
3 [报告]
发表于 2010-05-25 10:42 |只看该作者
我把操作单独写为一个小程序,然后用system狂调来解决问题,但我真的很想知道原来的程序错在哪儿。因为用现在的方法写出来的代码很丑很别扭。点名兰花仙子来解决啦。:wink:

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2010-05-25 12:37 |只看该作者
fork出的进程pid你要保存起来,然后一个个的waitpid.
例如,你把产生的子进程id存在@children中
最后:

  1. foreach my $child (@children) {
  2.      print "waiting $child\n";
  3.      waitpid($child, 0);
  4. }
复制代码

论坛徽章:
0
5 [报告]
发表于 2010-05-25 14:53 |只看该作者
{:3_198:}同意PY的,应该是没有做进程互斥导致的。

论坛徽章:
78
双子座
日期:2013-10-15 08:50:09天秤座
日期:2013-10-16 18:02:08白羊座
日期:2013-10-18 13:35:33天蝎座
日期:2013-10-18 13:37:06狮子座
日期:2013-10-18 13:40:31双子座
日期:2013-10-22 13:58:42戌狗
日期:2013-10-22 18:50:04CU十二周年纪念徽章
日期:2013-10-24 15:41:34巨蟹座
日期:2013-10-24 17:14:56处女座
日期:2013-10-24 17:15:30双子座
日期:2013-10-25 13:49:39午马
日期:2013-10-28 15:02:15
6 [报告]
发表于 2010-05-25 16:21 |只看该作者
这个应该不是代码的问题,ORA-03106:ORA-03115:这些错误都是oracle客户端的版本问题

论坛徽章:
0
7 [报告]
发表于 2010-05-25 16:44 |只看该作者
回复 6# yybmsrs


    举个例子:当一个进程正在进行fetchrow_array,数据没取完的时候,另外一个进程用同样$dbh去执行prepare之类的时候,就会出错。

论坛徽章:
78
双子座
日期:2013-10-15 08:50:09天秤座
日期:2013-10-16 18:02:08白羊座
日期:2013-10-18 13:35:33天蝎座
日期:2013-10-18 13:37:06狮子座
日期:2013-10-18 13:40:31双子座
日期:2013-10-22 13:58:42戌狗
日期:2013-10-22 18:50:04CU十二周年纪念徽章
日期:2013-10-24 15:41:34巨蟹座
日期:2013-10-24 17:14:56处女座
日期:2013-10-24 17:15:30双子座
日期:2013-10-25 13:49:39午马
日期:2013-10-28 15:02:15
8 [报告]
发表于 2010-05-25 17:29 |只看该作者
回复 7# toniz


    oracle的没测,但是我在mysql下测试了10W条数据情况,这样写是没问题的。有时间测下oracle的

论坛徽章:
0
9 [报告]
发表于 2010-05-25 17:33 |只看该作者
仔细看了一下,还有一个原因,就是$dbh会受到exit的影响。任意一个子进程使用exit退出后,$dbh将会失效。

论坛徽章:
0
10 [报告]
发表于 2010-05-25 17:38 |只看该作者
回复 8# yybmsrs


    如果不互斥,让几个进程同时执行,有可能报:
DBD::Oracle::db prepare failed: ORA-01002: fetch out of sequence ( 游标错误)
   也可能报:
DBD::Oracle::db prepare failed: ORA-03124: two-task internal error

总之我这边上面两个错误是随机的。


   使用waitpid之后,就会报:DBD::Oracle::db prepare failed: ORA-03113: end-of-file (这个是受到子进程exit的影响)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP