簡體   English   中英

使用帶有Oracle 8的DBI模塊的Perl腳本停止處理

[英]Perl script using DBI module with Oracle 8 stops processing

我在使用連接到Oracle 8的DBI模塊(版本1.601)的Perl腳本時遇到問題。操作系統是FreeBSD 7.0。

該腳本只是打開一個連接,循環通過CSV文件一次一行/一行插入數據,然后關閉連接並退出。 cron作業每30分鍾執行一次處理任何傳入CSV文件的腳本。 有時,腳本會在中途停止處理(沒有插入新數據,不會消耗更多的CPU時間),有必要將其終止。

CSV文件似乎有一個大小閾值。 任何低於35000行的腳本,腳本都會執行並退出。 否則它會停止並且過程處於(看似)休眠/等待狀態。

我只能通過SQL * Plus遠程訪問Oracle8。 檢查了Oracle v $會話表並查看這些停滯進程的連接是否未關閉,因此可能達到某些資源限制? 在FreeBSD上運行'limits'會產生以下結果:

cputime          infinity secs
filesize         infinity kB
datasize           524288 kB
stacksize           65536 kB
coredumpsize     infinity kB
memoryuse        infinity kB
memorylocked     infinity kB
maxprocesses         5547
openfiles           11095
sbsize           infinity bytes
vmemoryuse       infinity kB

我不確定如何繼續。 我如何或在哪里可以縮小問題的范圍?

任何幫助表示贊賞。


這是腳本,對某些var名稱進行了更改,省略了輸入檢查代碼:

#!/usr/bin/perl -w
use DBI;
use strict;

my $exitstatus = 0;
my $infile = shift;
open (INFILE, "$infile");

my $dbh = DBI->connect(
  'dbi:Oracle:sid=mysid;host=myhostname',
  'myusername',
  'mypassword',
  {
    RaiseError => 1,
    AutoCommit => 1
  }
) or die $DBI::errstr;

while (<INFILE>) {
  chomp;
  next if (/^#.*$/ || /^$/);
  my @columns = split /\t/;
  my ($var1, $var2, $var3) = @columns;
  eval {
    my $oProce = qq{
      BEGIN
        InsertStoredProc(
        field1 => $var1,
        field2 => $var2,
        field3 => $var3
        );
      END;
    };
    $dbh->do( $oProce );
  };
  if ( $@ ) {
    $exitstatus=1;
    warn "LINE: @columns\n";
    warn "Execution of stored procedure failed: $DBI::errstr\n";
    warn "################################################################################\n";
  }
}
$dbh->disconnect;
close INFILE;
exit $exitstatus;

不是我認為它相關,但代碼效率很低。 您正在為插入的每一行解析SQL。 為什么不這樣做:

my $sth = $dbh->prepare('BEGIN InsertStoredProc(?,?,?); END;');
while (<INFILE>) {
  chomp;
  next if (/^#.*$/ || /^$/);
  my @columns = split /\t/;
  #my ($var1, $var2, $var3) = @columns;
  eval {
       $sth->execute(@columns);
    #my $oProce = qq{
    #  BEGIN
    #    InsertStoredProc(
    #    field1 => $var1,
    #    field2 => $var2,
    #    field3 => $var3
    #    );
    #  END;
    #};
    #$dbh->do( $oProce );
  };
  if ( $@ ) {
    $exitstatus=1;
    warn "LINE: @columns\n";
    warn "Execution of stored procedure failed: $DBI::errstr\n";
    warn "################################################################################\n";
  }
}

關閉AutoCommit的另一個建議也將加速你的代碼,因為你只會提交每N行而不是每一行。 為什么使用AutoCommit會導致掛起對我沒有意義。

至於如果你可以隨意重現它似乎掛起的點,嘗試使用DBI_TRACE = 15 = x.log運行它並在連接中設置ora_verbose => 6。 掛起時日志文件末尾的內容是什么。

你沒有使用AutoCommit試過嗎? 也許您創建了許多事務,Oracle停止處理更多請求。

嘗試每100行提交一次,當沒有更多數據時。

您可以使用strace -p your_program_pid來查看正在進行的操作,腳本停止的位置。

我希望這會對你有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM