--- /usr/local/mysql-cluster-gpl-7.0.9-linux-i686-glibc23/bin/ndb_size.pl 2009-11-17 18:40:24.000000000 +0000 +++ ndb_size.pl 2010-01-26 13:52:03.000000000 +0000 @@ -42,7 +42,20 @@ # - some float stores come out weird (when there's a comma e.g. 'float(4,1)') # - no disk data values # - computes the storage requirements of views (and probably MERGE) -# - ignores character sets? +# - ignores character sets (use utf8 flag as work around) +# Test cases that succeed or fail on NDB Cluster +# create table tsuccess (c1 varchar(255),c2 varchar(255),c3 varchar(255),c4 varchar(255),c5 varchar(255), +# c6 varchar(255),c7 varchar(255),c8 varchar(255),c9 varchar(255),c10 varchar(255),c11 varchar(120)) character set utf8; +# Succeeds +# create table tfail1005 (c1 varchar(255),c2 varchar(255),c3 varchar(255),c4 varchar(255),c5 varchar(255), +# c6 varchar(255),c7 varchar(255),c8 varchar(255),c9 varchar(255),c10 varchar(255),c11 varchar(121)) character set utf8; +# Returns ERROR 1005 (HY000): Can't create table 'test.tfail1005' (errno: 140) +# create table tfail1118 (c1 varchar(255),c2 varchar(255),c3 varchar(255),c4 varchar(255),c5 varchar(255), +# c6 varchar(255),c7 varchar(255),c8 varchar(255),c9 varchar(255),c10 varchar(255),c11 varchar(127)) character set utf8; +# Returns ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8052. +# You have to change some columns to TEXT or BLOBs +# - ignores part keys fail on NDB Cluster e.g. CREATE TABLE $table (a int, b varchar(20), c int, primary key (a,b(10)), key (c)); + package MySQL::NDB::Size::Parameter; @@ -80,6 +93,7 @@ type is_varsize size + charlen Key) ], hash => 'dm_overhead', scalar => [{ -default => 4 },'align'], @@ -417,7 +431,8 @@ $debug, $format, $excludetables, - $excludedbs); + $excludedbs, + $utf8); GetOptions('database|d=s'=>\$database, 'hostname=s'=>\$hostname, @@ -428,6 +443,7 @@ 'loadqueries|l=s'=>\$loadqueries, 'excludetables=s'=>\$excludetables, 'excludedbs=s'=>\$excludedbs, + 'utf8'=>\$utf8, 'help|usage|h!'=>\$help, 'debug'=>\$debug, 'format|f=s'=>\$format, @@ -449,6 +465,7 @@ print STDERR "\t--user and --password default to empty string\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--utf8 Assume all CHAR/VARCHAR columns in tables will be storing UTF8 data\n"; print STDERR "\t--excludedbs Comma separated list of database names to skip\n"; print STDERR "\t--savequeries= saves all queries to the DB into \n"; print STDERR "\t--loadqueries= loads query results from . Doesn't connect to DB.\n"; @@ -525,7 +542,7 @@ } else { - my $sql= "select t.TABLE_NAME,t.TABLE_SCHEMA " . + my $sql= "select t.TABLE_NAME,t.TABLE_SCHEMA,t.TABLE_COLLATION " . " from information_schema.TABLES t " . " where t.TABLE_SCHEMA in ( $dblist ) "; @@ -560,7 +577,7 @@ foreach my $colname (keys %$info) { my $col= new MySQL::NDB::Size::Column(name => $colname); - my ($type, $size); + my ($type, $size, $charlen); $col->Key($$info{$colname}{Key}) if(defined($$info{$colname}{Key}) &&$$info{$colname}{Key} ne ''); @@ -584,8 +601,16 @@ { $type= $$info{$colname}{Type}; } + + # Work out byte length + $charlen=1; # default + if ($utf8) { + $charlen=3; # Force UTF8 + } + $col->type($type); $col->size($size); + $col->charlen($charlen); if($type =~ /tinyint/) {$col->dm(1)} @@ -629,8 +654,13 @@ } elsif($type =~ /varchar/ || $type =~ /varbinary/) { - my $fixed=$size+ceil($size/256); - $col->dm_overhead_set('length' => ceil($size/256)); + my $colsize=$size; + if ($type =~ /varchar/) { + $colsize=$size*$charlen; + } + + my $fixed=$colsize+ceil($colsize/256); + $col->dm_overhead_set('length' => ceil($colsize/256)); $col->dm($fixed); if(!$col->Key()) # currently keys must be non varsized { @@ -649,13 +679,19 @@ $queries{$sql}= \@dynamic; } $dynamic[0]=0 if ! defined($dynamic[0]) || !@dynamic; - $dynamic[0]+=ceil($size/256); # size bit + $dynamic[0]+=ceil($colsize/256); # size bit $col->is_varsize(1); $col->ver_dm('5.1',ceil($dynamic[0])); } } - elsif($type =~ /binary/ || $type =~ /char/) - {$col->dm($size)} + elsif($type =~ /binary/) + { + $col->dm($size); + } + elsif($type =~ /char/) + { + $col->dm($size*$charlen); + } elsif($type =~ /text/ || $type =~ /blob/) { $col->dm_overhead_set('length' => 8); @@ -1173,6 +1209,13 @@ printf $f.'%20s %9s %5s','Varsize Columns DM/Row','','',''; printf $v, $vdm_totals{$_} || 0 foreach @{$r->versions}; print "\n"; + + # Warn of Table Creation Issues + # Max value for row length is 8052 + # + if ($dm_totals{'5.0'}>8052) { + print "ERROR: $tname tables maximum row length $dm_totals{'5.0'} too large to create in NDB Cluster Engine and will need refactoring\n"; + } # DM for Indexes @@ -1554,6 +1597,13 @@ print "\n"; + # Warn of Table Creation Issues + # Max value for row length is 8052 + # + if ($dm_totals{'5.0'}>8052) { + print $self->h4("ERROR: $tname tables maximum row length $dm_totals{'5.0'} too large to create in NDB Cluster Engine and will need refactoring"); + } + # DM for Indexes print $self->h3('DataMemory for Indexes'); print "\n";