mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-10-19 08:56:34 +00:00
Fix SchemaIterator by replacing recursion with double nested while loops.
This commit is contained in:
@@ -334,64 +334,67 @@ sub _iterate_dbh {
|
|||||||
$self->{dbs} = \@dbs;
|
$self->{dbs} = \@dbs;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !$self->{db} ) {
|
DATABASE:
|
||||||
$self->{db} = shift @{$self->{dbs}};
|
while ( $self->{db} || defined(my $db = shift @{$self->{dbs}}) ) {
|
||||||
PTDEBUG && _d('Next database:', $self->{db});
|
if ( !$self->{db} ) {
|
||||||
return unless $self->{db};
|
PTDEBUG && _d('Next database:', $db);
|
||||||
}
|
$self->{db} = $db;
|
||||||
|
|
||||||
if ( !defined $self->{tbls} ) {
|
|
||||||
my $sql = 'SHOW /*!50002 FULL*/ TABLES FROM ' . $q->quote($self->{db});
|
|
||||||
PTDEBUG && _d($sql);
|
|
||||||
my @tbls = map {
|
|
||||||
$_->[0]; # (tbl, type)
|
|
||||||
}
|
}
|
||||||
grep {
|
|
||||||
my ($tbl, $type) = @$_;
|
|
||||||
(!$type || ($type ne 'VIEW'))
|
|
||||||
&& $self->_resume_from_table($tbl)
|
|
||||||
&& $self->table_is_allowed($self->{db}, $tbl);
|
|
||||||
}
|
|
||||||
@{$dbh->selectall_arrayref($sql)};
|
|
||||||
PTDEBUG && _d('Found', scalar @tbls, 'tables in database', $self->{db});
|
|
||||||
$self->{tbls} = \@tbls;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ( my $tbl = shift @{$self->{tbls}} ) {
|
if ( !$self->{tbls} ) {
|
||||||
my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
|
my $sql = 'SHOW /*!50002 FULL*/ TABLES FROM ' . $q->quote($self->{db});
|
||||||
if ( my $e = $EVAL_ERROR ) {
|
PTDEBUG && _d($sql);
|
||||||
my $table_name = "$self->{db}.$tbl";
|
my @tbls = map {
|
||||||
# SHOW CREATE TABLE failed. This is a bit puzzling;
|
$_->[0]; # (tbl, type)
|
||||||
# maybe the table got dropped, or crashed. Not much we can
|
|
||||||
# do about it; If the table is missing, just PTDEBUG it, but
|
|
||||||
# otherwise, warn with the error.
|
|
||||||
if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
|
|
||||||
PTDEBUG && _d("Skipping $table_name because it no longer exists");
|
|
||||||
}
|
}
|
||||||
else {
|
grep {
|
||||||
warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
|
my ($tbl, $type) = @$_;
|
||||||
|
(!$type || ($type ne 'VIEW'))
|
||||||
|
&& $self->_resume_from_table($tbl)
|
||||||
|
&& $self->table_is_allowed($self->{db}, $tbl);
|
||||||
}
|
}
|
||||||
next;
|
@{$dbh->selectall_arrayref($sql)};
|
||||||
|
PTDEBUG && _d('Found', scalar @tbls, 'tables in database',$self->{db});
|
||||||
|
$self->{tbls} = \@tbls;
|
||||||
}
|
}
|
||||||
my $tbl_struct = $tp->parse($ddl);
|
|
||||||
if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
|
TABLE:
|
||||||
return {
|
while ( my $tbl = shift @{$self->{tbls}} ) {
|
||||||
db => $self->{db},
|
my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
|
||||||
tbl => $tbl,
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
name => $q->quote($self->{db}, $tbl),
|
my $table_name = "$self->{db}.$tbl";
|
||||||
ddl => $ddl,
|
# SHOW CREATE TABLE failed. This is a bit puzzling;
|
||||||
tbl_struct => $tbl_struct,
|
# maybe the table got dropped, or crashed. Not much we can
|
||||||
};
|
# do about it; If the table is missing, just PTDEBUG it, but
|
||||||
|
# otherwise, warn with the error.
|
||||||
|
if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
|
||||||
|
PTDEBUG && _d("$table_name no longer exists");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
|
||||||
|
}
|
||||||
|
next TABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $tbl_struct = $tp->parse($ddl);
|
||||||
|
if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
|
||||||
|
return {
|
||||||
|
db => $self->{db},
|
||||||
|
tbl => $tbl,
|
||||||
|
name => $q->quote($self->{db}, $tbl),
|
||||||
|
ddl => $ddl,
|
||||||
|
tbl_struct => $tbl_struct,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
PTDEBUG && _d('No more tables in database', $self->{db});
|
PTDEBUG && _d('No more tables in database', $self->{db});
|
||||||
$self->{db} = undef;
|
$self->{db} = undef;
|
||||||
$self->{tbls} = undef;
|
$self->{tbls} = undef;
|
||||||
|
} # DATABASE
|
||||||
|
|
||||||
# Recurse to get the next database. If there's no next db, then the
|
PTDEBUG && _d('No more databases');
|
||||||
# call will return undef and we'll return undef, too.
|
return;
|
||||||
return $self->_iterate_dbh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub database_is_allowed {
|
sub database_is_allowed {
|
||||||
|
Reference in New Issue
Block a user