[pgsql-jp: 28721] Re: current transaction is aborted について

SAITO Masaru daisaito @ lares.dti.ne.jp
2003年 1月 21日 (火) 03:23:32 JST


齋藤@横浜です。

On Thu, 16 Jan 2003 20:29:38 +0900
冨田 直人 <ntomita @ pana.net> wrote:

> はじめまして、冨田と申します。
(snip)

> 数万件のレコードが格納されているファイル(data.txt)から
> 一行ずつ読込、DBにinsertするプログラムを作成しています。
> 
> 言語はPerlを使用し、PostgreSQLとやりとりする部分は、
> DBIを使用しています。
> 
> COMMITのタイミングとしては、100件単位でcommitするように
> しているのですが、1万5000件を超えた所から、下記のようなエラーが出力されます。

件数はともかくとして、100件単位でcommitというのはどうなんでしょう。
**99件目でエラーになった場合その前の98件の処理は全部捨てるんですか?
また、失敗した行は捨てるというなら、autocommitでもよいのでは?
全てが成功しなければいけないなら、エラーが発生した行でエラーメッセージを
出して、処理を止める。(die or exit)
でもってそのレコードを直して、retry and stop and retry ...


# 1レコードのボリュームが大きくないので数万件でも、全件commitしても
# たいしてパフォーマンスには影響しないと思います。


> 
> NOTICE:  current transaction is aborted, queries ignored until end of transaction block

何かエラーが起きたんでしょう。

> 
> vmstat等を確認するとDisk I/Oの問題のようにも見えるのですが、
> 原因が掴めない為、こちらに投稿させていただきました。

関係ないかと。。


> プログラムが悪いような気もしますので、実際のプログラムを以下に示します。
> 
> 何か原因が分かりましたら、教えてください。
> 解り難い説明で申し訳ありませんが、宜しくお願い致します。
> 
> #-- <insert.pl> -----------------------------#
> 
>     use DBI;
> 
>     $cnt = 0;
> 
>     # DB接続
>     $dbh = DBI->connect("dbi:Pg:dbname=test_db", user, passwd, {
>            PrintError => 0,
>            AutoCommit => 0
>     });
> 
>     open(FILE, "<data.txt");
> 
>     $sth = $dbh->prepare(
>            q{ insert into t_test values(?,?,?,?,?) }
>     );
> 
>     # ファイル読込
>     while (<FILE>) {
>         @str = split / /;
>         $rv = $sth->execute($str[0],$str[1],$str[2],$str[3],$str[4]);
この行を
eval{
$rv = $sth->execute($str[0],$str[1],$str[2],$str[3],$str[4]) or die $dbh->errstr;
};
if($@){
    print "errstring is ==>$@";
    $dbh->roolback();
}else{
    $dbh->commit();
}
と変えて、

>         $cnt++;
> 
#         if(($cnt % 100)==0)
#             $dbh->commit;
#         }
このブロックをコメントアウト
こんな感じでどうでしょう。
私の予感では悪いのはデータだと思います。
#日付として解釈できない文字列とか、
#長すぎる文字列とか、半角カナとか。。


>     }
> 
>     close(FILE);
> 
>     $dbh->commit;       # COMMIT実行
>     $dbh->disconnect;   # DB切断
> 
>     exit;
> 
> #--------------------------------------------
> # t_testテーブルの構成
> #--------------------------------------------
> psql -d test_db -c "CREATE TABLE t_test(
>         date            timestamp,
>         msg_id          char(200),
>         from_add        char(200),
>         to_add          char(100),
>         etc             text
> );"
> # インデックス作成
> psql -d test_db -c "CREATE INDEX test_index ON t_test(msg_id);"
> 
> -- <ntomita @ pana.net> --

--
SAITO Masaru <daisaito @ lares.dti.ne.jp>




pgsql-jp メーリングリストの案内