[PATCH] BUG#28683 - ndb_size.pl should support more than one database

Patch by: Monty Taylor <mtaylor@mysql.com>
Fixes by: Stewart Smith

  Added the ability to run ndb_size.pl on mulitple databases and also to exclude lists of databases and tables from analysis.
  ---
  Added schema name information to index table calculations as well.
  ---
  Made database an optional parameter, the exclusion of which causes all databases to be examined.
  If selecting from information_schema fails, attempt to fall back to show tables from
  ---
  Added support for setting an optional "real_table_name" for a table to deal with unique indexe size calcs.
  ---
  Fixed report title for the case where we are using operating on more than one database.
  ---
  Fixed some perl style concerns timothy had.
  Cull the list of databases in perl rather than passing both an in and a not in list to MySQL
  Get this full list of databases from show databases if needed.

  storage/ndb/tools/ndb_size.pl@stripped, 2007-05-25 13:45:44-07:00, mtaylor@qualinost.(none) +102 -28
    Added the ability to run ndb_size.pl on mulitple databases and also to exclude lists of databases and tables from analysis.
    ---
    Added schema name information to index table calculations as well.
    ---
    Made database an optional parameter, the exclusion of which causes all databases to be examined.
    If selecting from information_schema fails, attempt to fall back to show tables from
    ---
    Added support for setting an optional "real_table_name" for a table to deal with unique indexe size calcs.
    ---
    Fixed report title for the case where we are using operating on more than one database.
    ---
    Fixed some perl style concerns timothy had. 
    Cull the list of databases in perl rather than passing both an in and a not in list to MySQL
    Get this full list of databases from show databases if needed.

Index: ndb-work/storage/ndb/tools/ndb_size.pl
===================================================================
parent 67510ed2
...@@ -169,7 +169,9 @@ use Class::MethodMaker [ ...@@ -169,7 +169,9 @@ use Class::MethodMaker [
vdm_versions vdm_versions
ddm_versions ) ], ddm_versions ) ],
scalar => [ qw( name scalar => [ qw( name
rows ) ], rows
schema
real_table_name) ],
hash => [ qw( columns hash => [ qw( columns
indexes indexes
indexed_columns indexed_columns
...@@ -198,6 +200,16 @@ use Class::MethodMaker [ ...@@ -198,6 +200,16 @@ use Class::MethodMaker [
scalar => [ { -default=> 4 },'align'], scalar => [ { -default=> 4 },'align'],
]; ];
sub table_name
{
my ($self) = @_;
if ($self->real_table_name) {
return $self->real_table_name;
}else {
return $self->name;
}
}
sub compute_row_size sub compute_row_size
{ {
my ($self, $releases) = @_; my ($self, $releases) = @_;
...@@ -391,7 +403,7 @@ sub compute_estimate ...@@ -391,7 +403,7 @@ sub compute_estimate
package main; package main;
my ($dbh,$database,$hostname,$user,$password,$help,$savequeries,$loadqueries,$debug,$format); my ($dbh,$database,$hostname,$user,$password,$help,$savequeries,$loadqueries,$debug,$format,$excludetables,$excludedbs);
GetOptions('database|d=s'=>\$database, GetOptions('database|d=s'=>\$database,
'hostname=s'=>\$hostname, 'hostname=s'=>\$hostname,
...@@ -399,6 +411,8 @@ GetOptions('database|d=s'=>\$database, ...@@ -399,6 +411,8 @@ GetOptions('database|d=s'=>\$database,
'password|p=s'=>\$password, 'password|p=s'=>\$password,
'savequeries|s=s'=>\$savequeries, 'savequeries|s=s'=>\$savequeries,
'loadqueries|l=s'=>\$loadqueries, 'loadqueries|l=s'=>\$loadqueries,
'excludetables=s'=>\$excludetables,
'excludedbs=s'=>\$excludedbs,
'help|usage|h!'=>\$help, 'help|usage|h!'=>\$help,
'debug'=>\$debug, 'debug'=>\$debug,
'format|f=s'=>\$format, 'format|f=s'=>\$format,
...@@ -406,32 +420,73 @@ GetOptions('database|d=s'=>\$database, ...@@ -406,32 +420,73 @@ GetOptions('database|d=s'=>\$database,
my $report= new MySQL::NDB::Size::Report; my $report= new MySQL::NDB::Size::Report;
if($help || !$database) if($help)
{ {
print STDERR "Usage:\n"; print STDERR "Usage:\n";
print STDERR "\tndb_size.pl --database=<db name> [--hostname=<host>]" print STDERR "\tndb_size.pl --database=<db name>|ALL [--hostname=<host>]"
."[--user=<user>] [--password=<password>] [--help|-h] [--format=(html|text)] [--loadqueries=<file>] [--savequeries=<file>]\n\n"; ."[--user=<user>] [--password=<password>] [--help|-h] [--format=(html|text)] [--loadqueries=<file>] [--savequeries=<file>]\n\n";
print STDERR "\t--database=<db name> ALL may be specified to examine all "
."databases\n";
print STDERR "\t--hostname=<host>:<port> can be used to designate a " print STDERR "\t--hostname=<host>:<port> can be used to designate a "
."specific port\n"; ."specific port\n";
print STDERR "\t--hostname defaults to localhost\n"; print STDERR "\t--hostname defaults to localhost\n";
print STDERR "\t--user and --password default to empty string\n"; print STDERR "\t--user and --password default to empty string\n";
print STDERR "\t--format=(html|text) Output format\n"; print STDERR "\t--format=(html|text) Output format\n";
print STDERR "\t--excludetables Comma separated list of table names to skip\n";
print STDERR "\t--excludedbs Comma separated list of database names to skip\n";
print STDERR "\t--savequeries=<file> saves all queries to the DB into <file>\n"; print STDERR "\t--savequeries=<file> saves all queries to the DB into <file>\n";
print STDERR "\t--loadqueries=<file> loads query results from <file>. Doesn't connect to DB.\n"; print STDERR "\t--loadqueries=<file> loads query results from <file>. Doesn't connect to DB.\n";
exit(1); exit(1);
} }
$hostname= 'localhost' unless $hostname; $hostname= 'localhost' unless $hostname;
my %queries; # used for loadqueries/savequeries my %queries; # used for loadqueries/savequeries
if(!$loadqueries) if(!$loadqueries)
{ {
my $dsn = "DBI:mysql:database=$database;host=$hostname"; my $dsn = "DBI:mysql:host=$hostname";
$dbh= DBI->connect($dsn, $user, $password) or exit(1); $dbh= DBI->connect($dsn, $user, $password) or exit(1);
$report->database($database);
$report->dsn($dsn); $report->dsn($dsn);
} }
my @dbs;
if ($database && !($database =~ /^ALL$/i))
{
@dbs = split(',', $database);
}
else
{
# Do all databases
@dbs = map { $_->[0] } @{ $dbh->selectall_arrayref("show databases") };
}
my %withdb = map {$_ => 1} @dbs;
foreach (split ",", $excludedbs || '')
{
delete $withdb{$_};
}
delete $withdb{'mysql'};
delete $withdb{'INFORMATION_SCHEMA'};
delete $withdb{'information_schema'};
my $dblist = join (',', map { $dbh->quote($_) } keys %withdb );
$excludetables = join (',', map { $dbh->quote($_) } split ',', $excludetables )
if $excludetables;
if(!$loadqueries)
{
if (scalar(keys %withdb)>1)
{
$report->database("databases: $dblist");
}
else
{
$report->database("database: $dblist");
}
}
else else
{ {
open Q,"< $loadqueries"; open Q,"< $loadqueries";
...@@ -441,7 +496,6 @@ else ...@@ -441,7 +496,6 @@ else
%queries= %$e; %queries= %$e;
close Q; close Q;
$report->database("file:$loadqueries"); $report->database("file:$loadqueries");
$report->dsn("file:$loadqueries");
} }
$report->versions('4.1','5.0','5.1'); $report->versions('4.1','5.0','5.1');
...@@ -454,7 +508,25 @@ if($loadqueries) ...@@ -454,7 +508,25 @@ if($loadqueries)
} }
else else
{ {
$tables= $dbh->selectall_arrayref("show tables"); my $sql= "select t.TABLE_NAME,t.TABLE_SCHEMA " .
" from information_schema.TABLES t " .
" where t.TABLE_SCHEMA in ( $dblist ) ";
$sql.=" and t.TABLE_NAME not in " .
" ( $excludetables )"
if ($excludetables);
$tables= $dbh->selectall_arrayref($sql);
if (!$tables) {
print "WARNING: problem selecing from INFORMATION SCHEMA ($sql)\n";
if ($#dbs>0) {
print "\t attempting to fallback to show tables from $database";
$tables= $dbh->selectall_arrayref("show tables from $database\n");
} else {
print "All Databases not supported in 4.1. Please specify --database=\n";
}
}
$queries{"show tables"}= $tables; $queries{"show tables"}= $tables;
} }
...@@ -543,9 +615,10 @@ sub do_table { ...@@ -543,9 +615,10 @@ sub do_table {
$col->dm($fixed); $col->dm($fixed);
if(!$col->Key()) # currently keys must be non varsized if(!$col->Key()) # currently keys must be non varsized
{ {
my $sql= "select avg(length(`" my $sql= sprintf("select avg(length(`%s`)) " .
.$colname " from `%s`.`%s` " ,
."`)) from `".$t->name().'`'; $colname, $t->schema(), $t->table_name());
my @dynamic; my @dynamic;
if($loadqueries) if($loadqueries)
{ {
...@@ -573,9 +646,11 @@ sub do_table { ...@@ -573,9 +646,11 @@ sub do_table {
$blobhunk= 8000 if $type=~ /longblob/; $blobhunk= 8000 if $type=~ /longblob/;
$blobhunk= 4000 if $type=~ /mediumblob/; $blobhunk= 4000 if $type=~ /mediumblob/;
my $sql= "select SUM(CEILING(". my $sql= sprintf("select SUM(CEILING(length(`%s`)/%s)) " .
"length(`$colname`)/$blobhunk))" " from `%s`.`%s`" ,
."from `".$t->name."`"; $colname, $blobhunk,
$t->schema(), $t->table_name() );
my @blobsize; my @blobsize;
if($loadqueries) if($loadqueries)
{ {
...@@ -589,11 +664,12 @@ sub do_table { ...@@ -589,11 +664,12 @@ sub do_table {
$blobsize[0]=0 if !defined($blobsize[0]); $blobsize[0]=0 if !defined($blobsize[0]);
# Is a supporting table, add it to the lists: # Is a supporting table, add it to the lists:
$report->supporting_tables_set($t->name()."\$BLOB_$colname" => 1); $report->supporting_tables_set($t->schema().".".$t->name()."\$BLOB_$colname" => 1);
$t->supporting_tables_push($t->name()."\$BLOB_$colname"); $t->supporting_tables_push($t->schema().".".$t->name()."\$BLOB_$colname");
my $st= new MySQL::NDB::Size::Table(name => my $st= new MySQL::NDB::Size::Table(name =>
$t->name()."\$BLOB_$colname", $t->name()."\$BLOB_$colname",
schema => $t->schema(),
rows => $blobsize[0], rows => $blobsize[0],
row_dm_overhead => row_dm_overhead =>
{ '4.1' => 12, { '4.1' => 12,
...@@ -632,7 +708,9 @@ sub do_table { ...@@ -632,7 +708,9 @@ sub do_table {
$col->size($size); $col->size($size);
$t->columns_set( $colname => $col ); $t->columns_set( $colname => $col );
} }
$report->tables_set( $t->name => $t ); #print "setting tables: ",$t->schema(), $t->table_name(), $t->name, $t->real_table_name || "" , "\n";
# Use $t->name here instead of $t->table_name() to avoid namespace conflicts
$report->tables_set( $t->schema().".".$t->name() => $t );
# And now... the IndexMemory usage. # And now... the IndexMemory usage.
# #
...@@ -727,14 +805,16 @@ sub do_table { ...@@ -727,14 +805,16 @@ sub do_table {
# Is a supporting table, add it to the lists: # Is a supporting table, add it to the lists:
my $idxname= $t->name().'_'.join('_',@{$indexes{$index}{columns}}). my $idxname= $t->name().'_'.join('_',@{$indexes{$index}{columns}}).
"\$unique"; "\$unique";
$report->supporting_tables_set($idxname => 1); $report->supporting_tables_set($t->schema().".".$idxname => 1);
$t->supporting_tables_push($idxname); $t->supporting_tables_push($t->schema().".".$idxname);
$t->indexed_columns_set($_ => 1) $t->indexed_columns_set($_ => 1)
foreach @{$indexes{$index}{columns}}; foreach @{$indexes{$index}{columns}};
my $st= new MySQL::NDB::Size::Table(name => $idxname, my $st= new MySQL::NDB::Size::Table(name => $idxname,
real_table_name => $t->table_name(),
rows => $count[0], rows => $count[0],
schema => $t->schema(),
row_dm_overhead => row_dm_overhead =>
{ '4.1' => 12, { '4.1' => 12,
'5.0' => 12, '5.0' => 12,
...@@ -745,7 +825,6 @@ sub do_table { ...@@ -745,7 +825,6 @@ sub do_table {
row_ddm_overhead => row_ddm_overhead =>
{ '5.1' => 8 }, { '5.1' => 8 },
); );
do_table($st, do_table($st,
\%idxcols, \%idxcols,
{ {
...@@ -766,9 +845,10 @@ sub do_table { ...@@ -766,9 +845,10 @@ sub do_table {
foreach(@{$tables}) foreach(@{$tables})
{ {
my $table= @{$_}[0]; my $table= @{$_}[0];
my $schema = @{$_}[1] || $database;
my $info; my $info;
{ {
my $sql= 'describe `'.$table.'`'; my $sql= 'describe `'.$schema.'`.`'.$table.'`';
if($loadqueries) if($loadqueries)
{ {
$info= $queries{$sql}; $info= $queries{$sql};
...@@ -781,7 +861,7 @@ foreach(@{$tables}) ...@@ -781,7 +861,7 @@ foreach(@{$tables})
} }
my @count; my @count;
{ {
my $sql= 'select count(*) from `'.$table.'`'; my $sql= 'select count(*) from `'.$schema.'`.`'.$table.'`';
if($loadqueries) if($loadqueries)
{ {
@count= @{$queries{$sql}}; @count= @{$queries{$sql}};
...@@ -797,7 +877,7 @@ foreach(@{$tables}) ...@@ -797,7 +877,7 @@ foreach(@{$tables})
{ {
my @show_indexes; my @show_indexes;
{ {
my $sql= "show index from `".$table.'`'; my $sql= "show index from `".$schema.'`.`'.$table.'`';
if($loadqueries) if($loadqueries)
{ {
@show_indexes= @{$queries{$sql}}; @show_indexes= @{$queries{$sql}};
...@@ -826,6 +906,7 @@ foreach(@{$tables}) ...@@ -826,6 +906,7 @@ foreach(@{$tables})
} }
} }
my $t= new MySQL::NDB::Size::Table(name => $table, my $t= new MySQL::NDB::Size::Table(name => $table,
schema => $schema,
rows => $count[0], rows => $count[0],
row_dm_overhead => row_dm_overhead =>
{ '4.1' => 12, { '4.1' => 12,
...@@ -1008,7 +1089,7 @@ sub output ...@@ -1008,7 +1089,7 @@ sub output
my $self= shift; my $self= shift;
my $r= $self->{report}; my $r= $self->{report};
print $self->ul("ndb_size.pl report for database ". $r->database(). print $self->ul("ndb_size.pl report for ". $r->database().
" (".(($r->tables_count()||0)-($r->supporting_tables_count()||0)). " (".(($r->tables_count()||0)-($r->supporting_tables_count()||0)).
" tables)"); " tables)");
...@@ -1188,8 +1269,8 @@ sub output ...@@ -1188,8 +1269,8 @@ sub output
my $st= $r->tables->{$_}; my $st= $r->tables->{$_};
foreach(@{$st->indexes_keys()}) foreach(@{$st->indexes_keys()})
{ {
printf $f, $st->name() if $_ eq 'PRIMARY'; printf $f, $st->schema().".".$st->name() if $_ eq 'PRIMARY';
printf $f, $st->name().$_ if $_ ne 'PRIMARY'; printf $f, $st->schema().".".$st->name().$_ if $_ ne 'PRIMARY';
my $sti= $st->indexes->{$_}; my $sti= $st->indexes->{$_};
printf $v, ($sti->ver_im_exists($_)) printf $v, ($sti->ver_im_exists($_))
?$sti->ver_im->{$_} ?$sti->ver_im->{$_}
...@@ -1367,7 +1448,7 @@ print <<ENDHTML; ...@@ -1367,7 +1448,7 @@ print <<ENDHTML;
<body> <body>
ENDHTML ENDHTML
print $self->h1("ndb_size.pl report for database ". $r->database(). print $self->h1("ndb_size.pl report for ". $r->database().
" (".(($r->tables_count()||0)-($r->supporting_tables_count()||0)). " (".(($r->tables_count()||0)-($r->supporting_tables_count()||0)).
" tables)"); " tables)");
...@@ -1579,8 +1660,8 @@ ENDHTML ...@@ -1579,8 +1660,8 @@ ENDHTML
foreach(@{$st->indexes_keys()}) foreach(@{$st->indexes_keys()})
{ {
my @r; my @r;
push @r, $st->name() if $_ eq 'PRIMARY'; push @r, $st->schema().".".$st->name() if $_ eq 'PRIMARY';
push @r, $st->name().$_ if $_ ne 'PRIMARY'; push @r, $st->schema().".".$st->name().$_ if $_ ne 'PRIMARY';
my $sti= $st->indexes->{$_}; my $sti= $st->indexes->{$_};
push @r, ($sti->ver_im_exists($_)) push @r, ($sti->ver_im_exists($_))
?$sti->ver_im->{$_} ?$sti->ver_im->{$_}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment