I've added this as a note: Note that the ChildHandles array holds weak references and that 'from time to time' the old slots get freed up. This isn't a leak, it just appears to be if you're not familiar with the caching that DBI does internally. You can rest assured that if the DBI did have a real leak a) a great many people would be affected and b) it would get fixed very quickly.
I think 'from time to time' is every 120 or so newly created child handles. Tim. On Tue, May 26, 2015 at 07:57:53AM -0300, Steve Cookson - gmail wrote: > It seems to be further documented here, together with a solution: > > http://stackoverflow.com/questions/13338308/perl-dbi-memory-leak, > > But the solution does not seem to be reliable. Sometimes it works sometimes > not. > > I'll update you when I know more. > > Regards, > > Steve. > > On 26/05/15 07:07, Steve Cookson - gmail wrote: > >Hi Guys, > > > >You may have seen part of this post on PerlMonks. If so apologies for the > >duplication. This started off as a general search for leaks in my code, > >and resulted in a few hits, one of which was attached to every database > >access. > > > >A simple "select ATT_RECORD_NAME_TXT from TBL_TEST; " results in the leak > >of one scalar value. It seems to be attached to the ->prepare statement. > > > >At first I assumed it was down to my Firebird driver, which is relatively > >new, so I switched the driver to ODBC::Firebird, with the same result. > >Finally I changed to mysql and again got a memory leak. The only thing I > >can assume is that either my code is generically wrong (and I hope this is > >the case), or there is a leak in dbi, which I would be surprised by. > > > >I would appreciate some advice. > > > >Test code follows. Please install Devel::Leak to pick up leaked scalars > >and update the dsn to the dsn of your choice. > > > >Thanks for your help. > > > >Regards, > > > >Steve. > > > >#! /usr/bin/perl > > > >package main; > >use strict; > >use warnings; > >use DBI; > >#use DBD::Firebird; > >use DBD::ODBC; > >use Devel::Leak; > > my $handle; > > my $count_start; > > my $count_stop; > > my $gl_dbh; > > > > # Just do this 5 times to make sure there is no contribution to > >$handle count from Devel::Leak > > for (1..10){ > > print "Handle init: ", Devel::Leak::NoteSV($Launch::handle),"\n"; > > } > >#my $loc_dsn = <<DSN; > >#dbi:ODBC:Driver=Firebird;Dbname=/home/image/Documents/Endoscopia/DB/newEndo.fdb; > > > >#ib_dialect=3; > >#DSN > >my $loc_dsn = <<DSN; > >DBI:mysql:database=new_schema_test; > >host=localhost; > >port=3306"; > >DSN > > $Launch::gl_dbh=DBI->connect($loc_dsn,"root","password", { > > PrintError => 1, # Report errors via warn > > RaiseError => 1 # Report errors via Die > > } > > ) or die; > > > > my @loc_sql_string =(); > > $loc_sql_string[0]="CREATE TABLE TBL_TEST_LEAK ( ATTR_RECORD_ID_TXT > >VARCHAR(10) NOT NULL, ATT_RECORD_NAME_TXT VARCHAR(255), CONSTRAINT > >PK_TBL_TEST_LEAK PRIMARY KEY (ATTR_RECORD_ID_TXT) ); "; > > $loc_sql_string[1]="GRANT DELETE, INSERT, REFERENCES, SELECT, UPDATE > >ON TBL_TEST_LEAK TO SYSDBA WITH GRANT OPTION"; > > $loc_sql_string[2]="INSERT INTO TBL_TEST_LEAK (ATTR_RECORD_ID_TXT, > >ATT_RECORD_NAME_TXT) VALUES ('206', 'Delay Test 1' )"; > > $loc_sql_string[3]="select ATT_RECORD_NAME_TXT from TBL_TEST_LEAK; "; > > $loc_sql_string[4]= $loc_sql_string[3]; > > $loc_sql_string[5]= $loc_sql_string[3]; > > $loc_sql_string[6]= $loc_sql_string[3]; > > $loc_sql_string[7]= $loc_sql_string[3]; > > $loc_sql_string[8]= $loc_sql_string[3]; > > $loc_sql_string[9]="drop table TBL_TEST_LEAK; "; > > > > for (my $i=1;$i<=9;$i++){ > > $count_start=Devel::Leak::NoteSV($Launch::handle); > > print "DBD start: ", $count_start,"\n"; > > print $loc_sql_string[$i], "\n"; > > dbd_select($loc_sql_string[$i]); > > # You can use > > #$count_stop=Devel::Leak::CheckSV($Launch::handle); > > $count_stop=Devel::Leak::NoteSV($Launch::handle); > > print "Handle stop: ", $count_stop,"\n"; > > print "Count difference: ", $count_stop-$count_start,"\n"; > > } > > $Launch::gl_dbh->disconnect; > > > >sub dbd_select{ > > my $loc_sql_string=shift; > > my $loc_sth=$Launch::gl_dbh->prepare($loc_sql_string) or die; > > #$loc_sth->execute() or die; > > #$loc_sth->finish(); > > return; > >} > > > >1; > > > > >