雑多なノート

プログラミング初心者がメモとかを書きます。基礎的なこともメモとして。偏食系のアニオタ。

強制終了の理由とMySQLのキャッシュ

MySQLからデータを持ってきてNeo4jに流し込むPerlスクリプトを走らせてたら強制終了されてた

processing 19 of 215...finish
processing 19 of 215...強制終了
[vayacico@rabbit script]$

何とも不親切なエラーメッセージ……
不親切感的にスクリプト内部でエラーが発生した訳ではなさそう

調べてみたらLinuxから強制終了させられてる可能性があるらしい
メッセージが「強制終了」だけなので調べても見つからないことも覚悟してたけど見つかって良かった……

とりあえず調べた通りにログを確認

[vayacico@rabbit ~]$ sudo tail /var/log/messages   
...
Dec  5 19:55:07 rabbit kernel: Out of memory: Kill process 6287 (mysql_to_neo4j.) score 738 or sacrifice child                                     
Dec  5 19:55:07 rabbit kernel: Killed process 628
7, UID 500, (mysql_to_neo4j.) total-vm:2790640kB, anon-rss:359168kB, file-rss:4kB

Out of memoryとかいうお馴染み感のあるメッセージを確認
メモリ使いすぎで消されたのね
OOM killerとかいう格好良い名前のLinuxカーネルの仕組みによって消されたらしい
このメッセージを標準エラー出力に出してくれればいいのになー


強制終了の理由が分かったところで原因を考えてみる
メモリの使いすぎっていうのは決まっているのだがメモリを大量に使うようなコードは書いた覚えがない
MySQLから持ってくるデータは多いけどカーソル使ってアクセスしている(多分)のでメモリを大量に消費するとは思えないし
変数に結果を全部格納するようなプログラムだと実行した瞬間に落ちそうだし途中で落ちるっていうのも変だ

色々調べてみると「うっかり行をキャッシュしすぎてるんじゃね?」というのが出てきた

Identify a memory problem in Perl/DBI code - Stack Overflow

キャッシュする行が多すぎてメモリを使い果たしてるのではないか,とのこと

my $dbh = DBI->connect($dsn, $user, $pass, { RowCacheSize => 20 }) or die "Cannot connect to $dsn: $DBI::errstr\n";

接続時にオプションを付けることでキャッシュサイズを制限できるらしいのでやってみる
効果あるか分からないけど
ちなみに上のコードはキャッシュする行を20行に制限するものらしい
多分だけど



12/6夜追記
これ実行しても同じところで強制終了
他のところに原因があるのか……?

何となく全データを持ってきてる気がする


ここら辺が役立つかな?
明日やってみよう
YappoLogs: mysql_use_result on DBD::mysql
巨大なテーブルから SELECT する際のメモ | singular point