Here is a shot in the dark.
DBI database handles are usually destroyed just like any other object - when nothing references them. However, things can prevent the handle from being destroyed naturally:
- Handle is a package global
- Handle forms part of a cyclic reference that Perl cannot automatically free
When this happens, the object is destroyed as part of 'global destruction' which basically just undefs everything and calls DESTROY
in, practically, a random order. This may be what is causing your spurious errors.
To begin with, you can try enumerating your DB handles at the start and end of your script and see if any are still in use by the end. See this code snippet:
sub show_child_handles {
my ($h, $level) = @_;
printf "%sh %s %s\n", $h->{Type}, "\t" x $level, $h;
show_child_handles($_, $level + 1)
for (grep { defined } @{$h->{ChildHandles}});
}
my %drivers = DBI->installed_drivers();
show_child_handles($_, 0) for (values %drivers);
If you're not sure why the object is still in use, you can use Devel::Cycle on some big data structures to find them.
You may also find DBI's tracing functionality useful. Export DBI_TRACE=2
before running your script and it'll log every time a handle is created or destroyed.