Commit 1776fbac authored by unknown's avatar unknown

Fixed bug in ALTER TABLE

Removed _mi_rkey() function
New fork_big.pl multi-thread test


BitKeeper/deleted/.del-fork3_test.pl~c4a7bffb4f8e813c:
  Delete: tests/fork3_test.pl
BitKeeper/deleted/.del-fork_test.pl~3d3535329ed8cd5e:
  Delete: tests/fork_test.pl
Docs/manual.texi:
  Changelog.
  Updated support information
client/mysqladmin.c:
  Removed not used --timeout option
configure.in:
  Update version
myisam/mi_extra.c:
  Fixed bug in ALTER TABLE
myisam/mi_rkey.c:
  Removed _mi_rkey() function
myisam/myisamdef.h:
  Removed _mi_rkey() function
myisammrg/myrg_rkey.c:
  Removed _mi_rkey() function
myisammrg/myrg_rnext.c:
  Removed _mi_rkey() function
mysql-test/t/alter_table.test:
  Added test case for ALTER TABLE bug
sql/derror.cc:
  Moved shutdown message to clean_up
sql/mysql_priv.h:
  Moved shutdown message to clean_up
sql/sql_class.cc:
  Fixed bug in MySQL compiled with transactions but using --skip-"table-handler"
sql/sql_show.cc:
  Use time_after_lock for time of query when debugging
sql/sql_test.cc:
  Check memory overruns when using 'mysqladmin debug'
strings/ctype-tis620.c:
  F
parent 05f08c18
This diff is collapsed.
......@@ -28,7 +28,7 @@
#include <my_pthread.h> /* because of signal() */
#endif
#define ADMIN_VERSION "8.18"
#define ADMIN_VERSION "8.19"
#define MAX_MYSQL_VAR 64
#define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */
#define MAX_TRUNC_LENGTH 3
......@@ -817,8 +817,6 @@ static void usage(void)
-s, --silent Silently exit if one can't connect to server\n\
-S, --socket=... Socket file to use for connection\n");
#include "sslopt-usage.h"
printf("\
-t, --timeout=... Timeout for connection to the mysqld server\n");
#ifndef DONT_ALLOW_USER_CHANGE
printf("\
-u, --user=# User for login if not current user\n");
......
......@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
AM_INIT_AUTOMAKE(mysql, 3.23.36)
AM_INIT_AUTOMAKE(mysql, 3.23.37)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
......@@ -660,6 +660,7 @@ int main()
#
MAX_C_OPTIMIZE="-O6"
case $SYSTEM_TYPE in
*solaris2.7*)
# Solaris 2.7 has a broken /usr/include/widec.h
......
......@@ -319,6 +319,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
{
my_free(info->rec_alloc,MYF(MY_ALLOW_ZERO_PTR));
info->rec_alloc=info->rec_buff=0;
mi_fix_rec_buff_for_blob(info,info->s->base.pack_reclength);
}
break;
case HA_EXTRA_NORMAL: /* Theese isn't in use */
......
......@@ -22,8 +22,8 @@
/* Read a record using key */
/* Ordinary search_flag is 0 ; Give error if no record with key */
int _mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
enum ha_rkey_function search_flag, bool raw_key)
int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
enum ha_rkey_function search_flag)
{
uchar *key_buff;
MYISAM_SHARE *share=info->s;
......@@ -37,7 +37,7 @@ int _mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
if (raw_key)
if (!info->use_packed_key)
{
if (key_len == 0)
key_len=USE_WHOLE_KEY;
......@@ -101,11 +101,3 @@ int _mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
err:
DBUG_RETURN(my_errno);
} /* _mi_rkey */
/* shouldn't forget to do it inline sometime */
int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
enum ha_rkey_function search_flag)
{
return _mi_rkey(info,buf,inx,key,key_len,search_flag,TRUE);
}
......@@ -258,6 +258,7 @@ struct st_myisam_info {
my_bool quick_mode;
my_bool page_changed; /* If info->buff can't be used for rnext */
my_bool buff_used; /* If info->buff has to be reread for rnext */
my_bool use_packed_key; /* For MYISAMMRG */
myf lock_wait; /* is 0 or MY_DONT_WAIT */
int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
LIST open_list;
......@@ -630,8 +631,6 @@ void mi_update_status(void* param);
void mi_copy_status(void* to,void *from);
my_bool mi_check_status(void* param);
void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows);
int _mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
enum ha_rkey_function search_flag, bool raw_key);
my_bool check_table_is_closed(const char *name, const char *where);
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share);
......
......@@ -63,7 +63,9 @@ int myrg_rkey(MYRG_INFO *info,byte *record,int inx, const byte *key,
}
else
{
err=_mi_rkey(mi,buf,inx,key_buff,pack_key_length,search_flag,FALSE);
mi->use_packed_key=1;
err=mi_rkey(mi,buf,inx,key_buff,pack_key_length,search_flag);
mi->use_packed_key=0;
}
info->last_used_table=table+1;
......
......@@ -68,8 +68,10 @@ int _myrg_finish_scan(MYRG_INFO *info, int inx, enum ha_rkey_function type)
for (; table < info->end_table ; table++)
{
mi=table->table;
if ((err=_mi_rkey(mi,NULL,inx,key_buff,pack_key_length,
type,FALSE)))
mi->use_packed_key=1;
err=mi_rkey(mi,NULL,inx,key_buff,pack_key_length,type);
mi->use_packed_key=0;
if (err)
{
if (err == HA_ERR_KEY_NOT_FOUND) /* If end of file */
continue;
......
......@@ -57,13 +57,17 @@ CREATE TABLE t1 (
PRIMARY KEY (id)
) TYPE=MyISAM;
ALTER TABLE
t1
ORDER BY
t1.id,
t1.status,
t1.type_id,
t1.user_id,
t1.body;
ALTER TABLE t1 ORDER BY t1.id, t1.status, t1.type_id, t1.user_id, t1.body;
DROP TABLE t1;
drop table t1;
#
# The following combination found a hang-bug in MyISAM
#
CREATE TABLE t1 (AnamneseId int(10) unsigned NOT NULL auto_increment,B BLOB,PRIMARY KEY (AnamneseId)) type=myisam;
insert into t1 values (null,"hello");
LOCK TABLES t1 WRITE;
ALTER TABLE t1 ADD Column new_col int not null;
UNLOCK TABLES;
OPTIMIZE TABLE t1;
DROP TABLE t1;
......@@ -72,7 +72,7 @@ static void read_texts(const char *file_name,const char ***point,
Check that the above file is the right version for this program!\n\n",
my_progname,name,ant,error_messages);
VOID(my_close(file,MYF(MY_WME)));
clean_up(); /* Clean_up frees everything */
clean_up(0); /* Clean_up frees everything */
exit(1); /* We can't continue */
}
......@@ -115,7 +115,7 @@ err:
if (file != FERR)
VOID(my_close(file,MYF(MY_WME)));
fprintf(stderr,buff,my_progname,name);
clean_up(); /* Clean_up frees everything */
clean_up(0); /* Clean_up frees everything */
exit(1); /* We can't continue */
} /* read_texts */
......
......@@ -611,7 +611,7 @@ uint calc_week(TIME *ltime, bool with_year, bool sunday_first_day_of_week,
void find_date(char *pos,uint *vek,uint flag);
TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end);
TYPELIB *typelib(List<String> &strings);
void clean_up(void);
void clean_up(bool print_message=1);
ulong get_form_pos(File file, uchar *head, TYPELIB *save_names);
ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames,
const char *newname);
......
......@@ -136,9 +136,9 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
(hash_get_key) get_var_key,
(void (*)(void*)) free_var,0);
#ifdef USING_TRANSACTIONS
bzero((char*) &transaction,sizeof(transaction));
if (opt_using_transactions)
{
bzero((char*) &transaction,sizeof(transaction));
if (open_cached_file(&transaction.trans_log,
mysql_tmpdir, LOG_PREFIX, binlog_cache_size,
MYF(MY_WME)))
......
......@@ -1006,7 +1006,11 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
if (pthread_kill(tmp->real_id,0))
tmp->proc_info="*** DEAD ***"; // This shouldn't happen
#endif
#ifdef EXTRA_DEBUG
thd_info->start_time= tmp->time_after_lock;
#else
thd_info->start_time= tmp->start_time;
#endif
thd_info->query=0;
if (tmp->query)
{
......
......@@ -240,6 +240,7 @@ Open streams: %10lu\n",
fflush(stdout);
if (thd)
thd->proc_info="malloc";
my_checkmalloc();
TERMINATE(stdout); // Write malloc information
if (thd)
thd->proc_info=0;
......
/*
Copyright (C) 2001 by Korakot Chaovavanich <korakot@iname.com> and
Apisilp Trunganont <apisilp@pantip.inet.co.th>
Copyright (C) 1998, 1999 by Pruet Boonma <pruet@eng.cmu.ac.th>
Copyright (C) 1998 by Theppitak Karoonboonyanan <thep@links.nectec.or.th>
Copyright (C) 1989, 1991 by Samphan Raruenrom <samphan@thai.com>
......@@ -6,9 +8,10 @@
Permission to use, copy, modify, distribute and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies.
Smaphan Raruenrom , Theppitak Karoonboonyanan and Pruet Boonma makes
no representations about the suitability of this software for any
purpose. It is provided "as is" without express or implied warranty.
Samphan Raruenrom , Theppitak Karoonboonyanan , Pruet Boonma ,
Korakot Chaovavanich and Apisilp Trunganont makes no representations
about the suitability of this software for any purpose. It is provided
"as is" without express or implied warranty.
*/
......@@ -297,7 +300,8 @@ int t_ctype[][TOT_LEVELS] = {
/*0xFC*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
/*0xFD*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
/*0xFE*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
/*0xFF*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
/* Utilize 0xFF for max_sort_chr in my_like_range_tis620 */
/*0xFF*/ { 255 /*IGNORE*/, IGNORE, IGNORE, IGNORE, X },
};
uchar NEAR ctype_tis620[257] =
......@@ -436,10 +440,14 @@ uchar NEAR sort_order_tis620[]=
static uchar* thai2sortable(const uchar * tstr,uint len)
{
/* We use only 3 levels (neglect capitalization). */
const uchar* p = tstr;
uchar *outBuf;
uchar *pRight1, *pRight2, *pRight3, *pRight4;
uchar *pLeft1, *pLeft2, *pLeft3, *pLeft4;
// uchar *pRight1, *pRight2, *pRight3, *pRight4;
// uchar *pLeft1, *pLeft2, *pLeft3, *pLeft4;
uchar *pRight1, *pRight2, *pRight3;
uchar *pLeft1, *pLeft2, *pLeft3;
uint bufSize;
len = (uint) strnlen((char*) tstr,len);
......@@ -460,23 +468,23 @@ static uchar* thai2sortable(const uchar * tstr,uint len)
return((uchar*) tstr);
}
pLeft3 = pRight3;
if(!(pRight4 = (uchar *)malloc(sizeof(uchar) * (len + 1)))) {
/* if(!(pRight4 = (uchar *)malloc(sizeof(uchar) * (len + 1)))) {
free(pRight1);
free(pRight2);
free(pRight3);
return((uchar*) tstr);
}
pLeft4 = pRight4;
pLeft4 = pRight4;*/
while(len--) {
if(isldvowel(*p) && isconsnt(p[1])) {
*pRight1++ = t_ctype[p[1]][0];
*pRight2++ = t_ctype[p[1]][1];
*pRight3++ = t_ctype[p[1]][2];
*pRight4++ = t_ctype[p[1]][3];
// *pRight4++ = t_ctype[p[1]][3];
*pRight1++ = t_ctype[*p][0];
*pRight2++ = t_ctype[*p][1];
*pRight3++ = t_ctype[*p][2];
*pRight4++ = t_ctype[*p][3];
// *pRight4++ = t_ctype[*p][3];
len--;
p += 2;
} else {
......@@ -486,23 +494,24 @@ static uchar* thai2sortable(const uchar * tstr,uint len)
if(*pRight2 != IGNORE) pRight2++;
*pRight3 = t_ctype[*p][2];
if(*pRight3 != IGNORE) pRight3++;
*pRight4 = t_ctype[*p][3];
if(*pRight4 != IGNORE) pRight4++;
/* *pRight4 = t_ctype[*p][3];
if(*pRight4 != IGNORE) pRight4++;*/
p++;
}
}
*pRight1++ = L2_BLANK;
*pRight2++ = L3_BLANK;
*pRight3++ = L4_BLANK;
*pRight4++ = '\0';
// *pRight3++ = L4_BLANK;
*pRight3++ = '\0';
// *pRight4++ = '\0';
memcpy(pRight1, pLeft2, pRight2 - pLeft2);
pRight1 += pRight2 - pLeft2;
memcpy(pRight1, pLeft3, pRight3 - pLeft3);
pRight1 += pRight3 - pLeft3;
memcpy(pRight1, pLeft4, pRight4 - pLeft4);
// pRight1 += pRight3 - pLeft3;
// memcpy(pRight1, pLeft4, pRight4 - pLeft4);
free(pLeft2);
free(pLeft3);
free(pLeft4);
// free(pLeft4);
return(outBuf);
}
......@@ -574,55 +583,58 @@ int my_strxfrm_tis620(uchar * dest, uchar * src, int len)
Arg: String, its length, escape character, resource length, minimal string and maximum string
Ret: Alway 0
*/
/* We just copy this function from opt_range.cc. No need to convert to
thai2sortable string. min_str and max_str will be use for comparison and
converted there. */
#define max_sort_chr ((char) 255)
#define wild_one '_'
#define wild_many '%'
my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape,
uint res_length, char *min_str, char *max_str,
uint *min_length,uint *max_length)
uint *min_length, uint *max_length)
{
char *end;
char *min_org= min_str;
char *min_end = min_str + res_length;
char *tbuff;
uchar *tc;
uint tbuff_length;
const char *end=ptr+ptr_length;
char *min_org=min_str;
char *min_end=min_str+res_length;
char *tmp;
tbuff = (char*) (tc=thai2sortable((uchar*) ptr, ptr_length));
tbuff_length = (uint) buffsize(ptr);
end = tbuff + tbuff_length;
for(;tbuff != end && min_str != min_end; tbuff++)
for (; ptr != end && min_str != min_end ; ptr++)
{
if(*tbuff == escape && tbuff + 1 != end)
if (*ptr == escape && ptr+1 != end)
{
tbuff++;
*min_str++ = *max_str++ = *tbuff;
ptr++; // Skipp escape
*min_str++= *max_str++ = *ptr;
continue;
}
if(*tbuff == '_')
if (*ptr == wild_one) // '_' in SQL
{
*min_str++ = '\0';
*max_str++ = '\255';
*min_str++='\0'; // This should be min char
*max_str++=max_sort_chr;
continue;
}
if(*tbuff == '%')
if (*ptr == wild_many) // '%' in SQL
{
*min_length= (uint) (min_str - min_org);
*max_length= res_length;
do
{
*min_str++ = ' ';
*max_str++ = '\255';
} while(min_str != min_end);
free(tc);
return(0);
*max_length=res_length;
do {
*min_str++ = ' '; // Because if key compression
*max_str++ = max_sort_chr;
} while (min_str != min_end);
return 0;
}
*min_str++ = *max_str++ = *tbuff;
*min_str++= *max_str++ = *ptr;
}
*min_length= *max_length = (uint) (min_str - min_org);
while(min_str != min_end)
{
*min_str++ = *max_str++ = ' ';
}
free(tc);
return(0);
/* Temporary fix for handling wild_one at end of string (key compression) */
// for (tmp= min_str ; tmp > min_org && tmp[-1] == '\0';)
// *--tmp=' ';
while (min_str != min_end)
*min_str++ = *max_str++ = ' '; // Because if key compression
return 0;
}
/* Thai normalization for input sub system
......
#!/usr/bin/perl -w
#
# This is a test with uses 4 processes to insert, delete , check and select
#
$opt_loop_count=200000; # Change this to make test harder/easier
##################### Standard benchmark inits ##############################
use DBI;
use Getopt::Long;
use Benchmark;
package main;
$opt_skip_create=$opt_skip_in=$opt_verbose=$opt_fast_insert=
$opt_lock_tables=$opt_debug=$opt_skip_delete=$opt_fast=$opt_force=0;
$opt_host=""; $opt_db="test";
GetOptions("host=s","db=s","loop-count=i","skip-create","skip-in","skip-delete",
"verbose","fast-insert","lock-tables","debug","fast","force") || 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 "Testing 4 multiple connections to a server with 1 insert, 1 delete\n";
print "1 select and one repair/check connection.\n";
$firsttable = "bench_f1";
####
#### Start timeing and start test
####
$start_time=new Benchmark;
if (!$opt_skip_create)
{
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
$dbh->do("drop table if exists $firsttable");
print "Creating table $firsttable in database $opt_db\n";
$dbh->do("create table $firsttable (id int(6) not null, info varchar(32), marker char(1), primary key(id))") || die $DBI::errstr;
$dbh->disconnect; $dbh=0; # Close handler
}
$|= 1; # Autoflush
####
#### Start the tests
####
test_insert() if (($pid=fork()) == 0); $work{$pid}="insert";
test_delete() if (($pid=fork()) == 0); $work{$pid}="delete";
test_select() if (($pid=fork()) == 0); $work{$pid}="select1";
repair_and_check() if (($pid=fork()) == 0); $work{$pid}="repair/check";
$errors=0;
while (($pid=wait()) != -1)
{
$ret=$?/256;
print "thread '" . $work{$pid} . "' finnished with exit code $ret\n";
$errors++ if ($ret != 0);
}
if (!$opt_skip_delete && !$errors)
{
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
$dbh->do("drop table $firsttable");
$dbh->disconnect; $dbh=0; # Close handler
}
print ($errors ? "Test failed\n" :"Test ok\n");
$end_time=new Benchmark;
print "Total time: " .
timestr(timediff($end_time, $start_time),"noc") . "\n";
exit(0);
#
# Insert records in the table
#
sub test_insert
{
my ($dbh,$i,$sth);
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
for ($i=0 ; $i < $opt_loop_count; $i++)
{
$sth=$dbh->do("insert into $firsttable values ($i,'This is entry $i','')") || die "Got error on insert: $Mysql::db_errstr\n";
$sth=0;
}
$dbh->disconnect; $dbh=0;
print "Test_insert: Inserted $i rows\n";
exit(0);
}
sub test_delete
{
my ($dbh,$i,$sth,@row);
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
sleep(5);
if ($opt_lock_tables)
{
$sth=$dbh->do("lock tables $firsttable WRITE") || die "Got error on lock tables $firsttable: $Mysql::db_errstr\n";
}
$sth=$dbh->prepare("select count(*) from $firsttable") || die "Got error on select from $firsttable: $dbh->errstr\n";
$sth->execute || die $dbh->errstr;
if ((@row = $sth->fetchrow_array()))
{
last if (!$row[0]); # Insert thread is probably ready
}
$sth=$dbh->do("delete from $firsttable") || die "Got error on delete from $firsttable: $dbh->errstr;\n";
}
$sth=0;
$dbh->disconnect; $dbh=0;
print "Test_delete: Deleted all rows $i times\n";
exit(0);
}
#
# select records
#
sub test_select
{
my ($dbh,$i,$sth,@row);
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
$sth=$dbh->prepare("select count(*) from $firsttable") || die "Got error on select from $firsttable: $dbh->errstr;\n";
$sth->execute || die $dbh->errstr;
@row = $sth->fetchrow_array();
$sth=0;
}
$dbh->disconnect; $dbh=0;
print "Test_select: ok\n";
exit(0);
}
sub repair_and_check
{
my ($dbh,$row,$found1,$last_found1,$i,$type, $table);
$found1=0; $last_found1= -1;
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
for ($i=0; $found1 != $last_found1 ; $i++)
{
$type=($i & 2) ? "repair" : "check";
$table=$firsttable;
$last_found1=$found1;
$sth=$dbh->prepare("$type table $table") || die "Got error on prepare: $dbh->errstr\n";
$sth->execute || die $dbh->errstr;
while (($row=$sth->fetchrow_arrayref))
{
if ($row->[3] ne "OK")
{
print "Got error " . $row->[3] . " when doing $type on $table\n";
exit(1);
}
}
$sth=$dbh->prepare("select count(*) from $table") || die "Got error on prepare: $dbh->errstr\n";
$sth->execute || die $dbh->errstr;
@row = $sth->fetchrow_array();
$found1= $row[0];
$sth->finish;
sleep(3);
}
$dbh->disconnect; $dbh=0;
print "check/repair: Did $i repair/checks\n";
exit(0);
}
This diff is collapsed.
#!/usr/bin/perl -w
# This is a test with uses 5 processes to insert, update and select from
# two tables.
# One inserts records in the tables, one updates some record in it and
# the last 3 does different selects on the tables.
#
$opt_loop_count=10000; # Change this to make test harder/easier
##################### Standard benchmark inits ##############################
use Mysql;
use Getopt::Long;
use Benchmark;
package main;
$opt_skip_create=$opt_skip_in=$opt_verbose=$opt_fast_insert=
$opt_lock_tables=$opt_debug=$opt_skip_delete=$opt_fast=$opt_force=0;
$opt_host=""; $opt_db="test";
GetOptions("host=s","db=s","loop-count=i","skip-create","skip-in",
"skip-delete","verbose","fast-insert","lock-tables","debug","fast",
"force") || die "Aborted";
$opt_verbose=$opt_debug=$opt_lock_tables=$opt_fast_insert=$opt_fast=$opt_skip_in=$Mysql::db_errstr=$opt_force=undef; # Ignore warnings from these
print "Testing 5 multiple connections to a server with 1 insert, 1 update\n";
print "and 3 select connections.\n";
$firsttable = "bench_f1";
$secondtable = "bench_f2";
####
#### Start timeing and start test
####
$start_time=new Benchmark;
if (!$opt_skip_create)
{
$dbh = Mysql->Connect($opt_host, $opt_db) || die $Mysql::db_errstr;
$Mysql::QUIET = 1;
$dbh->Query("drop table $firsttable");
$dbh->Query("drop table $secondtable");
$Mysql::QUIET = 0;
print "Creating tables $firsttable and $secondtable in database $opt_db\n";
$dbh->Query("create table $firsttable (id int(6) not null, info varchar(32), marker char(1), primary key(id))") or die $Mysql::db_errstr;
$dbh->Query("create table $secondtable (id int(6) not null, row int(3) not null,value double, primary key(id,row))") or die $Mysql::db_errstr;
$dbh=0; # Close handler
}
$|= 1; # Autoflush
####
#### Start the tests
####
test_1() if (($pid=fork()) == 0); $work{$pid}="insert";
test_2() if (($pid=fork()) == 0); $work{$pid}="update";
test_3() if (($pid=fork()) == 0); $work{$pid}="select1";
test_4() if (($pid=fork()) == 0); $work{$pid}="select2";
test_5() if (($pid=fork()) == 0); $work{$pid}="select3";
$errors=0;
while (($pid=wait()) != -1)
{
$ret=$?/256;
print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
$errors++ if ($ret != 0);
}
if (!$opt_skip_delete && !$errors)
{
$dbh = Mysql->Connect($opt_host, $opt_db) || die $Mysql::db_errstr;
$dbh->Query("drop table $firsttable");
$dbh->Query("drop table $secondtable");
}
print ($errors ? "Test failed\n" :"Test ok\n");
$end_time=new Benchmark;
print "Total time: " .
timestr(timediff($end_time, $start_time),"noc") . "\n";
exit(0);
#
# Insert records in the two tables
#
sub test_1
{
my ($dbh,$tmpvar,$rows,$found,$i);
$dbh = Mysql->Connect($opt_host, $opt_db) || die $Mysql::db_errstr;
$tmpvar=1;
$rows=$found=0;
for ($i=0 ; $i < $opt_loop_count; $i++)
{
$tmpvar^= ((($tmpvar + 63) + $i)*3 % 100000);
$sth=$dbh->Query("insert into $firsttable values ($i,'This is entry $i','')") || die "Got error on insert: $Mysql::db_errstr\n";
$row_count=($i % 7)+1;
$rows+=1+$row_count;
for ($j=0 ; $j < $row_count; $j++)
{
$sth=$dbh->Query("insert into $secondtable values ($i,$j,0)") || die "Got error on insert: $Mysql::db_errstr\n";
}
if (($tmpvar % 10) == 0)
{
$sth=$dbh->Query("select max(info) from $firsttable") || die "Got error on select max(info): $Mysql::db_errstr\n";
$sth=$dbh->Query("select max(value) from $secondtable") || die "Got error on select max(info): $Mysql::db_errstr\n";
$found+=2;
}
}
$dbh=0;
print "Test_1: Inserted $rows rows, found $found rows\n";
exit(0);
}
#
# Update records in both tables
#
sub test_2
{
my ($dbh,$id,$tmpvar,$rows,$found,$i,$max_id,$tmp);
$dbh = Mysql->Connect($opt_host, $opt_db) || die $Mysql::db_errstr;
$tmpvar=111111;
$rows=$found=$max_id=$id=0;
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
$tmp=(($tmpvar + 63) + $i)*3;
$tmp=$tmp-int($tmp/100000)*100000;
$tmpvar^= $tmp;
$tmp=$tmpvar - int($tmpvar/10)*10;
if ($max_id < 2 || $tmp == 0)
{
$max_id=0;
$sth=$dbh->Query("select max(id) from $firsttable where marker=''") || die "Got error select max: $Mysql::db_errstr\n";
if ((@row = $sth->FetchRow()) && defined($row[0]))
{
$found++;
$max_id=$id=$row[0];
}
}
else
{
$id= $tmpvar % ($max_id-1)+1;
}
if ($id)
{
$sth=$dbh->Query("update $firsttable set marker='x' where id=$id") || die "Got error update $firsttable: $Mysql::db_errstr\n";
$rows+=$sth->affected_rows;
if ($sth->affected_rows)
{
$sth=$dbh->Query("update $secondtable set value=$i where id=$id") || die "Got error update $firsttable: $Mysql::db_errstr\n";
$rows+=$sth->affected_rows;
}
}
}
$dbh=0;
print "Test_2: Found $found rows, Updated $rows rows\n";
exit(0);
}
#
# select records
#
sub test_3
{
my ($dbh,$id,$tmpvar,$rows,$i);
$dbh = Mysql->Connect($opt_host, $opt_db) || die $Mysql::db_errstr;
$tmpvar=222222;
$rows=0;
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
$tmpvar^= ((($tmpvar + 63) + $i)*3 % 100000);
$id=$tmpvar % $opt_loop_count;
$sth=$dbh->Query("select id from $firsttable where id=$id") || die "Got error on select from $firsttable: $Mysql::db_errstr\n";
$rows+=$sth->numrows;
}
$dbh=0;
print "Test_3: Found $rows rows\n";
exit(0);
}
#
# Note that this uses row=1 and in some cases won't find any matching
# records
#
sub test_4
{
my ($dbh,$id,$tmpvar,$rows,$i);
$dbh = Mysql->Connect($opt_host, $opt_db) || die $Mysql::db_errstr;
$tmpvar=333333;
$rows=0;
for ($i=0 ; $i < $opt_loop_count; $i++)
{
$tmpvar^= ((($tmpvar + 63) + $i)*3 % 100000);
$id=$tmpvar % $opt_loop_count;
$sth=$dbh->Query("select id from $secondtable where id=$id") || die "Got error on select form $secondtable: $Mysql::db_errstr\n";
$rows+=$sth->numrows;
}
$dbh=0;
print "Test_4: Found $rows rows\n";
exit(0);
}
sub test_5
{
my ($dbh,$id,$tmpvar,$rows,$i,$max_id);
$dbh = Mysql->Connect($opt_host, $opt_db) || die $Mysql::db_errstr;
$tmpvar=444444;
$rows=$max_id=0;
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
$tmpvar^= ((($tmpvar + 63) + $i)*3 % 100000);
if ($max_id == 0 || ($tmpvar % 10 == 0))
{
$sth=$dbh->Query("select max(id) from $firsttable") || die "Got error select max: $Mysql::db_errstr\n";
if ((@row = $sth->FetchRow()) && defined($row[0]))
{
$max_id=$id=$row[0];
}
else
{
$id=0;
}
}
else
{
$id= $tmpvar % $max_id;
}
$sth=$dbh->Query("select value from $firsttable,$secondtable where $firsttable.id=$id and $secondtable.id=$firsttable.id") || die "Got error on select form $secondtable: $Mysql::db_errstr\n";
$rows+=$sth->numrows;
}
$dbh=0;
print "Test_5: Found $rows rows\n";
exit(0);
}
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