# Copyright (c) 2001, 2006 MySQL AB # Use is subject to license terms # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
# # This is a test with uses many processes to test a MySQL server. # # Tested a lot with: --threads=30
my $opt_loop_count=500000; # Change this to make test harder/easier
##################### Standard benchmark inits ##############################
use DBI;
use Getopt::Long;
use Benchmark;
package main;
our ($opt_skip_create,$opt_skip_in,$opt_verbose,$opt_fast_insert);
our ($opt_lock_tables,$opt_debug,$opt_skip_delete,$opt_fast,$opt_force);
our ($opt_threads);
our ($opt_host,$opt_user,$opt_password,$opt_db);
my (@testtables, $abort_table, $numtables, $start_time, $end_time);
my ($dbh);
GetOptions("host=s","db=s","user=s","password=s","loop-count=i","skip-create","skip-in","skip-delete","verbose","fast-insert","lock-tables","debug","fast","force","threads=i") || die "Aborted";
$opt_verbose=$opt_debug=$opt_lock_tables=$opt_fast_insert=$opt_fast=$opt_skip_in=$opt_force=undef; # Ignore warnings from these
print "Test of multiple connections that test the following things:\n";
print "insert, select, delete, update, alter, check, repair and flush\n";
$numtables = $#testtables+1;
srand 100; # Make random numbers repeatable
#### #### Start timeing and start test ####
$start_time=new Benchmark;
$dbh = DBI->connect("DBI:MariaDB:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr; if (!$opt_skip_create)
{
my $table_def; foreach $table_def (@testtables)
{
my ($table,$extra)= ($table_def->[0], $table_def->[1]);
print "Creating table $table in database $opt_db\n";
$dbh->do("drop table if exists $table");
$dbh->do("create table $table". " (id int(6) not null auto_increment,". " info varchar(32)," . " marker timestamp," . " flag int not null," . " primary key(id)) $extra")
or die $DBI::errstr; # One row in the table will make future tests easier
$dbh->do("insert into $table (id) values (null)")
or die $DBI::errstr;
} # Create the table we use to signal that we should end the test
$dbh->do("drop table if exists $abort_table");
$dbh->do("create table $abort_table (id int(6) not null) ENGINE=heap") ||
die $DBI::errstr;
}
$dbh->do("delete from $abort_table");
$dbh->disconnect; $dbh=0; # Close handler
$|= 1; # Autoflush
#### #### Start the tests ####
my ($i, $pid, %work);
for ($i=0 ; $i < $opt_threads ; $i ++)
{
test_insert() if (($pid=fork()) == 0); $work{$pid}="insert";
} for ($i=0 ; $i < $numtables ; $i ++)
{
test_insert($i,$i) if (($pid=fork()) == 0); $work{$pid}="insert_one";
} for ($i=0 ; $i < $opt_threads ; $i ++)
{
test_select() if (($pid=fork()) == 0); $work{$pid}="select_key";
}
test_join() if (($pid=fork()) == 0); $work{$pid}="test_join";
test_select_count() if (($pid=fork()) == 0); $work{$pid}="select_count";
test_delete() if (($pid=fork()) == 0); $work{$pid}="delete";
test_update() if (($pid=fork()) == 0); $work{$pid}="update";
test_flush() if (($pid=fork()) == 0); $work{$pid}= "flush";
test_check() if (($pid=fork()) == 0); $work{$pid}="check";
test_repair() if (($pid=fork()) == 0); $work{$pid}="repair";
test_alter() if (($pid=fork()) == 0); $work{$pid}="alter"; #test_database("test2") if (($pid=fork()) == 0); $work{$pid}="check_database";
$errors=0;
$running_insert_threads=$opt_threads+$numtables; while (($pid=wait()) != -1)
{
my ($ret);
$ret=$?/256;
print "thread '" . $work{$pid} . "' finished with exit code $ret\n"; if ($work{$pid} =~ /^insert/)
{ if (!--$running_insert_threads)
{ # Time to stop other threads
signal_abort();
}
}
$errors++ if ($ret != 0);
}
# # Cleanup #
if (!$opt_skip_delete && !$errors)
{
my $table_def;
$dbh = DBI->connect("DBI:MariaDB:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
sleep(5); # Give time to insert some rows
$i=0; while (($i++ % 10) || !test_if_abort($dbh))
{
sleep(1);
$row_counts=simple_query($dbh, $count_query);
for ($j=0 ; $j < $table_count ; $j++)
{
my ($id)= int rand $row_counts->[$j];
my ($table)= $testtables[$j]->[0];
$dbh->do("delete from $table where id >= $id-2 and id <= $id +2") || die "Got error on delete from $table: $DBI::errstr\n";
$count++;
}
}
$dbh->disconnect; $dbh=0;
print "Test_delete: Executed $count deletes\n";
exit(0);
}
# # Update the flag for table 2 and 3 # Will abort after a while when table1 doesn't change max value #
sub test_update
{
my ($dbh, $i, $j, $row_counts, $count_query, $count, $loop);
$dbh = DBI->connect("DBI:MariaDB:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
sleep(5); # Give time to insert some rows
$i=0; while (($i++ % 100) || !test_if_abort($dbh))
{ if ($loop++ >= 100)
{
$loop=0;
$row_counts=simple_query($dbh, $count_query);
}
for ($j=1 ; $j <= 2 ; $j++)
{
my ($id)= int rand $row_counts->[$j];
my ($table)= $testtables[$j]->[0]; # Fix to not change the same rows as the above delete
$id= ($id + $count) % $row_counts->[$j];
$dbh->do("update $table set flag=flag+1 where id >= $id-2 and id <= $id +2") || die "Got error on update of $table: $DBI::errstr\n";
$count++;
}
}
$dbh->disconnect; $dbh=0;
print "Test_update: Executed $count updates\n";
exit(0);
}
# # Run a check on all tables except the last one # (The last one is not checked to put pressure on the key cache) #
sub test_check
{
my ($dbh, $sth, $row, $i, $j, $type, $table);
$dbh = DBI->connect("DBI:MariaDB:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
$type= "check"; for ($i=$j=0 ; !test_if_abort($dbh) ; $i++)
{
sleep(200);
$table=$testtables[$j]->[0];
$sth=$dbh->prepare("$type table $table") || die "Got error on prepare: $DBI::errstr\n";
$sth->execute || die $DBI::errstr;
while (($row=$sth->fetchrow_arrayref))
{ if ($row->[3] ne "OK")
{
print "Got error " . $row->[3] . " when doing $type on $table\n";
exit(1);
}
} if (++$j == $numtables-1)
{
$j=0;
}
}
$dbh->disconnect; $dbh=0;
print "test_check: Executed $i checks\n";
exit(0);
}
# # Do a repair on the first table once in a while #
sub test_repair
{
my ($dbh, $sth, $row, $i, $type, $table);
$dbh = DBI->connect("DBI:MariaDB:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
$type= "repair"; for ($i=0 ; !test_if_abort($dbh) ; $i++)
{
sleep(100);
$table=$testtables[0]->[0];
$sth=$dbh->prepare("$type table $table") || die "Got error on prepare: $DBI::errstr\n";
$sth->execute || die $DBI::errstr;
while (($row=$sth->fetchrow_arrayref))
{ if ($row->[3] ne "OK")
{
print "Got error " . $row->[3] . " when doing $type on $table\n";
exit(1);
}
}
}
$dbh->disconnect; $dbh=0;
print "test_repair: Executed $i repairs\n";
exit(0);
}
# # Do a flush tables on table 3 and 4 once in a while #
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.