Commit fcaa779e authored by monty@donna.mysql.fi's avatar monty@donna.mysql.fi

merge

parents 7de6496f 9ea338ac
mwagner@evoq.mwagner.org mwagner@evoq.mwagner.org
jcole@abel.spaceapes.com jcole@abel.spaceapes.com
monty@donna.mysql.fi
This diff is collapsed.
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include <my_pthread.h> /* because of signal() */ #include <my_pthread.h> /* because of signal() */
#endif #endif
#define ADMIN_VERSION "8.18" #define ADMIN_VERSION "8.19"
#define MAX_MYSQL_VAR 64 #define MAX_MYSQL_VAR 64
#define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */ #define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */
#define MAX_TRUNC_LENGTH 3 #define MAX_TRUNC_LENGTH 3
...@@ -817,8 +817,6 @@ static void usage(void) ...@@ -817,8 +817,6 @@ static void usage(void)
-s, --silent Silently exit if one can't connect to server\n\ -s, --silent Silently exit if one can't connect to server\n\
-S, --socket=... Socket file to use for connection\n"); -S, --socket=... Socket file to use for connection\n");
#include "sslopt-usage.h" #include "sslopt-usage.h"
printf("\
-t, --timeout=... Timeout for connection to the mysqld server\n");
#ifndef DONT_ALLOW_USER_CHANGE #ifndef DONT_ALLOW_USER_CHANGE
printf("\ printf("\
-u, --user=# User for login if not current user\n"); -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. ...@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc) AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line! # 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) AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10 PROTOCOL_VERSION=10
...@@ -660,6 +660,7 @@ int main() ...@@ -660,6 +660,7 @@ int main()
# #
MAX_C_OPTIMIZE="-O6" MAX_C_OPTIMIZE="-O6"
case $SYSTEM_TYPE in case $SYSTEM_TYPE in
*solaris2.7*) *solaris2.7*)
# Solaris 2.7 has a broken /usr/include/widec.h # 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) ...@@ -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)); my_free(info->rec_alloc,MYF(MY_ALLOW_ZERO_PTR));
info->rec_alloc=info->rec_buff=0; info->rec_alloc=info->rec_buff=0;
mi_fix_rec_buff_for_blob(info,info->s->base.pack_reclength);
} }
break; break;
case HA_EXTRA_NORMAL: /* Theese isn't in use */ case HA_EXTRA_NORMAL: /* Theese isn't in use */
......
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
/* Read a record using key */ /* Read a record using key */
/* Ordinary search_flag is 0 ; Give error if no record with 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, 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) enum ha_rkey_function search_flag)
{ {
uchar *key_buff; uchar *key_buff;
MYISAM_SHARE *share=info->s; 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, ...@@ -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); info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
if (raw_key) if (!info->use_packed_key)
{ {
if (key_len == 0) if (key_len == 0)
key_len=USE_WHOLE_KEY; 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, ...@@ -101,11 +101,3 @@ int _mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
err: err:
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
} /* _mi_rkey */ } /* _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 { ...@@ -258,6 +258,7 @@ struct st_myisam_info {
my_bool quick_mode; my_bool quick_mode;
my_bool page_changed; /* If info->buff can't be used for rnext */ 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 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 */ myf lock_wait; /* is 0 or MY_DONT_WAIT */
int (*read_record)(struct st_myisam_info*, my_off_t, byte*); int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
LIST open_list; LIST open_list;
...@@ -630,8 +631,6 @@ void mi_update_status(void* param); ...@@ -630,8 +631,6 @@ void mi_update_status(void* param);
void mi_copy_status(void* to,void *from); void mi_copy_status(void* to,void *from);
my_bool mi_check_status(void* param); my_bool mi_check_status(void* param);
void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows); 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); my_bool check_table_is_closed(const char *name, const char *where);
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share); 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, ...@@ -63,7 +63,9 @@ int myrg_rkey(MYRG_INFO *info,byte *record,int inx, const byte *key,
} }
else 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; info->last_used_table=table+1;
......
...@@ -68,8 +68,10 @@ int _myrg_finish_scan(MYRG_INFO *info, int inx, enum ha_rkey_function type) ...@@ -68,8 +68,10 @@ int _myrg_finish_scan(MYRG_INFO *info, int inx, enum ha_rkey_function type)
for (; table < info->end_table ; table++) for (; table < info->end_table ; table++)
{ {
mi=table->table; mi=table->table;
if ((err=_mi_rkey(mi,NULL,inx,key_buff,pack_key_length, mi->use_packed_key=1;
type,FALSE))) 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 */ if (err == HA_ERR_KEY_NOT_FOUND) /* If end of file */
continue; continue;
......
...@@ -57,13 +57,17 @@ CREATE TABLE t1 ( ...@@ -57,13 +57,17 @@ CREATE TABLE t1 (
PRIMARY KEY (id) PRIMARY KEY (id)
) TYPE=MyISAM; ) TYPE=MyISAM;
ALTER TABLE ALTER TABLE t1 ORDER BY t1.id, t1.status, t1.type_id, t1.user_id, t1.body;
t1 DROP TABLE t1;
ORDER BY
t1.id,
t1.status,
t1.type_id,
t1.user_id,
t1.body;
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, ...@@ -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", Check that the above file is the right version for this program!\n\n",
my_progname,name,ant,error_messages); my_progname,name,ant,error_messages);
VOID(my_close(file,MYF(MY_WME))); 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 */ exit(1); /* We can't continue */
} }
...@@ -115,7 +115,7 @@ err: ...@@ -115,7 +115,7 @@ err:
if (file != FERR) if (file != FERR)
VOID(my_close(file,MYF(MY_WME))); VOID(my_close(file,MYF(MY_WME)));
fprintf(stderr,buff,my_progname,name); 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 */ exit(1); /* We can't continue */
} /* read_texts */ } /* read_texts */
......
...@@ -165,6 +165,7 @@ static SYMBOL symbols[] = { ...@@ -165,6 +165,7 @@ static SYMBOL symbols[] = {
{ "INFILE", SYM(INFILE),0,0}, { "INFILE", SYM(INFILE),0,0},
{ "INNER", SYM(INNER_SYM),0,0}, { "INNER", SYM(INNER_SYM),0,0},
{ "INNOBASE", SYM(INNOBASE_SYM),0,0}, { "INNOBASE", SYM(INNOBASE_SYM),0,0},
{ "INNODB", SYM(INNOBASE_SYM),0,0},
{ "INSERT", SYM(INSERT),0,0}, { "INSERT", SYM(INSERT),0,0},
{ "INSERT_ID", SYM(INSERT_ID),0,0}, { "INSERT_ID", SYM(INSERT_ID),0,0},
{ "INT", SYM(INT_SYM),0,0}, { "INT", SYM(INT_SYM),0,0},
......
...@@ -611,7 +611,7 @@ uint calc_week(TIME *ltime, bool with_year, bool sunday_first_day_of_week, ...@@ -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); void find_date(char *pos,uint *vek,uint flag);
TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end); TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end);
TYPELIB *typelib(List<String> &strings); 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 get_form_pos(File file, uchar *head, TYPELIB *save_names);
ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames, ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames,
const char *newname); const char *newname);
......
...@@ -271,6 +271,8 @@ ulong max_connections,max_insert_delayed_threads,max_used_connections, ...@@ -271,6 +271,8 @@ ulong max_connections,max_insert_delayed_threads,max_used_connections,
max_connect_errors, max_user_connections = 0; max_connect_errors, max_user_connections = 0;
ulong thread_id=1L,current_pid; ulong thread_id=1L,current_pid;
ulong slow_launch_threads = 0; ulong slow_launch_threads = 0;
ulong myisam_max_sort_file_size, myisam_max_extra_sort_file_size;
char mysql_real_data_home[FN_REFLEN], char mysql_real_data_home[FN_REFLEN],
mysql_data_home[2],language[LIBLEN],reg_ext[FN_EXTLEN], mysql_data_home[2],language[LIBLEN],reg_ext[FN_EXTLEN],
default_charset[LIBLEN],mysql_charsets_dir[FN_REFLEN], *charsets_list, default_charset[LIBLEN],mysql_charsets_dir[FN_REFLEN], *charsets_list,
...@@ -584,7 +586,6 @@ static void __cdecl kill_server(int sig_ptr) ...@@ -584,7 +586,6 @@ static void __cdecl kill_server(int sig_ptr)
my_thread_init(); // If this is a new thread my_thread_init(); // If this is a new thread
#endif #endif
close_connections(); close_connections();
sql_print_error(ER(ER_SHUTDOWN_COMPLETE),my_progname);
if (sig != MYSQL_KILL_SIGNAL && sig != 0) if (sig != MYSQL_KILL_SIGNAL && sig != 0)
unireg_abort(1); /* purecov: inspected */ unireg_abort(1); /* purecov: inspected */
else else
...@@ -634,7 +635,7 @@ void unireg_abort(int exit_code) ...@@ -634,7 +635,7 @@ void unireg_abort(int exit_code)
} }
void clean_up(void) void clean_up(bool print_message)
{ {
DBUG_PRINT("exit",("clean_up")); DBUG_PRINT("exit",("clean_up"));
if (cleanup_done++) if (cleanup_done++)
...@@ -655,17 +656,19 @@ void clean_up(void) ...@@ -655,17 +656,19 @@ void clean_up(void)
#ifdef USE_RAID #ifdef USE_RAID
end_raid(); end_raid();
#endif #endif
x_free((gptr) my_errmsg[ERRMAPP]); /* Free messages */
free_defaults(defaults_argv); free_defaults(defaults_argv);
my_free(mysql_tmpdir,MYF(0)); my_free(mysql_tmpdir,MYF(0));
x_free(opt_bin_logname); x_free(opt_bin_logname);
bitmap_free(&temp_pool); bitmap_free(&temp_pool);
free_max_user_conn(); free_max_user_conn();
end_slave();
#ifndef __WIN__ #ifndef __WIN__
if (!opt_bootstrap) if (!opt_bootstrap)
(void) my_delete(pidfile_name,MYF(0)); // This may not always exist (void) my_delete(pidfile_name,MYF(0)); // This may not always exist
#endif #endif
end_slave(); if (print_message)
sql_print_error(ER(ER_SHUTDOWN_COMPLETE),my_progname);
x_free((gptr) my_errmsg[ERRMAPP]); /* Free messages */
my_thread_end(); my_thread_end();
/* Tell main we are ready */ /* Tell main we are ready */
...@@ -1214,6 +1217,7 @@ help in finding out why mysqld died.\n",sig); ...@@ -1214,6 +1217,7 @@ help in finding out why mysqld died.\n",sig);
#if defined(HAVE_LINUXTHREADS) #if defined(HAVE_LINUXTHREADS)
#ifdef __i386__ #ifdef __i386__
trace_stack(); trace_stack();
fflush(stderr);
#endif /* __i386__ */ #endif /* __i386__ */
if (test_flags & TEST_CORE_ON_SIGNAL) if (test_flags & TEST_CORE_ON_SIGNAL)
write_core(sig); write_core(sig);
...@@ -1245,11 +1249,7 @@ static void init_signals(void) ...@@ -1245,11 +1249,7 @@ static void init_signals(void)
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL); sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
if (!(test_flags & TEST_NO_STACKTRACE)) if (!(test_flags & TEST_NO_STACKTRACE))
{ {
#ifdef HAVE_DARWIN_THREADS
sa.sa_handler=( void (*)() ) handle_segfault;
#else
sa.sa_handler=handle_segfault; sa.sa_handler=handle_segfault;
#endif
sigaction(SIGSEGV, &sa, NULL); sigaction(SIGSEGV, &sa, NULL);
#ifdef SIGBUS #ifdef SIGBUS
sigaction(SIGBUS, &sa, NULL); sigaction(SIGBUS, &sa, NULL);
...@@ -1698,6 +1698,10 @@ int main(int argc, char **argv) ...@@ -1698,6 +1698,10 @@ int main(int argc, char **argv)
reset_floating_point_exceptions(); reset_floating_point_exceptions();
init_thr_lock(); init_thr_lock();
/* Fix varibles that are base 1024*1024 */
myisam_max_temp_length= (my_off_t) min(((ulonglong) myisam_max_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE);
myisam_max_extra_temp_length= (my_off_t) min(((ulonglong) myisam_max_extra_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE);
/* Setup log files */ /* Setup log files */
if (opt_log) if (opt_log)
open_log(&mysql_log, glob_hostname, opt_logname, ".log", LOG_NORMAL); open_log(&mysql_log, glob_hostname, opt_logname, ".log", LOG_NORMAL);
...@@ -2460,7 +2464,7 @@ enum options { ...@@ -2460,7 +2464,7 @@ enum options {
OPT_GEMINI_SKIP, OPT_INNOBASE_SKIP, OPT_GEMINI_SKIP, OPT_INNOBASE_SKIP,
OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_TEMP_POOL, OPT_TX_ISOLATION,
OPT_GEMINI_FLUSH_LOG, OPT_GEMINI_RECOVER, OPT_GEMINI_FLUSH_LOG, OPT_GEMINI_RECOVER,
OPT_GEMINI_UNBUFFERED_IO OPT_GEMINI_UNBUFFERED_IO, OPT_SKIP_SAFEMALLOC,
}; };
static struct option long_options[] = { static struct option long_options[] = {
...@@ -2583,6 +2587,7 @@ static struct option long_options[] = { ...@@ -2583,6 +2587,7 @@ static struct option long_options[] = {
{"skip-host-cache", no_argument, 0, (int) OPT_SKIP_HOST_CACHE}, {"skip-host-cache", no_argument, 0, (int) OPT_SKIP_HOST_CACHE},
{"skip-name-resolve", no_argument, 0, (int) OPT_SKIP_RESOLVE}, {"skip-name-resolve", no_argument, 0, (int) OPT_SKIP_RESOLVE},
{"skip-new", no_argument, 0, (int) OPT_SKIP_NEW}, {"skip-new", no_argument, 0, (int) OPT_SKIP_NEW},
{"skip-safemalloc", no_argument, 0, (int) OPT_SKIP_SAFEMALLOC},
{"skip-show-database", no_argument, 0, (int) OPT_SKIP_SHOW_DB}, {"skip-show-database", no_argument, 0, (int) OPT_SKIP_SHOW_DB},
{"skip-slave-start", no_argument, 0, (int) OPT_SKIP_SLAVE_START}, {"skip-slave-start", no_argument, 0, (int) OPT_SKIP_SLAVE_START},
{"skip-networking", no_argument, 0, (int) OPT_SKIP_NETWORKING}, {"skip-networking", no_argument, 0, (int) OPT_SKIP_NETWORKING},
...@@ -2705,6 +2710,11 @@ CHANGEABLE_VAR changeable_vars[] = { ...@@ -2705,6 +2710,11 @@ CHANGEABLE_VAR changeable_vars[] = {
~0L, 1, ~0L, 0, 1 }, ~0L, 1, ~0L, 0, 1 },
{ "myisam_sort_buffer_size", (long*) &myisam_sort_buffer_size, { "myisam_sort_buffer_size", (long*) &myisam_sort_buffer_size,
8192*1024, 4, ~0L, 0, 1 }, 8192*1024, 4, ~0L, 0, 1 },
{ "myisam_max_extra_sort_file_size",
(long*) &myisam_max_extra_sort_file_size,
(long) (MI_MAX_TEMP_LENGTH/(1024L*1024L)), 0, ~0L, 0, 1 },
{ "myisam_max_sort_file_size", (long*) &myisam_max_sort_file_size,
(long) (LONG_MAX/(1024L*1024L)), 0, ~0L, 0, 1 },
{ "net_buffer_length", (long*) &net_buffer_length, { "net_buffer_length", (long*) &net_buffer_length,
16384, 1024, 1024*1024L, MALLOC_OVERHEAD, 1024 }, 16384, 1024, 1024*1024L, MALLOC_OVERHEAD, 1024 },
{ "net_retry_count", (long*) &mysqld_net_retry_count, { "net_retry_count", (long*) &mysqld_net_retry_count,
...@@ -2818,6 +2828,9 @@ struct show_var_st init_vars[]= { ...@@ -2818,6 +2828,9 @@ struct show_var_st init_vars[]= {
{"max_tmp_tables", (char*) &max_tmp_tables, SHOW_LONG}, {"max_tmp_tables", (char*) &max_tmp_tables, SHOW_LONG},
{"max_write_lock_count", (char*) &max_write_lock_count, SHOW_LONG}, {"max_write_lock_count", (char*) &max_write_lock_count, SHOW_LONG},
{"myisam_recover_options", (char*) &myisam_recover_options_str, SHOW_CHAR_PTR}, {"myisam_recover_options", (char*) &myisam_recover_options_str, SHOW_CHAR_PTR},
{"myisam_max_extra_sort_file_size", (char*) &myisam_max_extra_sort_file_size,
SHOW_LONG},
{"myisam_max_sort_file_size",(char*) &myisam_max_sort_file_size, SHOW_LONG},
{"myisam_sort_buffer_size", (char*) &myisam_sort_buffer_size, SHOW_LONG}, {"myisam_sort_buffer_size", (char*) &myisam_sort_buffer_size, SHOW_LONG},
{"net_buffer_length", (char*) &net_buffer_length, SHOW_LONG}, {"net_buffer_length", (char*) &net_buffer_length, SHOW_LONG},
{"net_read_timeout", (char*) &net_read_timeout, SHOW_LONG}, {"net_read_timeout", (char*) &net_read_timeout, SHOW_LONG},
...@@ -2950,6 +2963,10 @@ static void usage(void) ...@@ -2950,6 +2963,10 @@ static void usage(void)
#ifndef DBUG_OFF #ifndef DBUG_OFF
printf("\ printf("\
-#, --debug[=...] Debug log. Default is '%s'\n",default_dbug_option); -#, --debug[=...] Debug log. Default is '%s'\n",default_dbug_option);
#ifdef SAFEMALLOC
puts("\
--skip-safemalloc Don't use the memory allocation checking");
#endif
#endif #endif
puts("\ puts("\
--default-character-set=charset\n\ --default-character-set=charset\n\
...@@ -3042,7 +3059,7 @@ static void usage(void) ...@@ -3042,7 +3059,7 @@ static void usage(void)
#ifdef HAVE_GEMINI_DB #ifdef HAVE_GEMINI_DB
puts("\ puts("\
--gemini-recovery=mode Set Crash Recovery operating mode\n\ --gemini-recovery=mode Set Crash Recovery operating mode\n\
(FULL, NONE, FORCE - default FULL) (FULL, NONE, FORCE - default FULL)\n\
--gemini-flush-log-at-commit\n\ --gemini-flush-log-at-commit\n\
Every commit forces a write to the reovery log\n\ Every commit forces a write to the reovery log\n\
--gemini-unbuffered-io Use unbuffered i/o\n\ --gemini-unbuffered-io Use unbuffered i/o\n\
...@@ -3051,13 +3068,13 @@ static void usage(void) ...@@ -3051,13 +3068,13 @@ static void usage(void)
#endif #endif
#ifdef HAVE_INNOBASE_DB #ifdef HAVE_INNOBASE_DB
puts("\ puts("\
--innobase_data_home_dir=dir The common part for innobase table spaces\n --innobase_data_home_dir=dir The common part for innobase table spaces\n\
--innobase_data_file_path=dir Path to individual files and their sizes\n --innobase_data_file_path=dir Path to individual files and their sizes\n\
--innobase_flush_log_at_trx_commit[=#] --innobase_flush_log_at_trx_commit[=#]\n\
Set to 0 if you don't want to flush logs\n\ Set to 0 if you don't want to flush logs\n\
--innobase_log_arch_dir=dir Where full logs should be archived\n\ --innobase_log_arch_dir=dir Where full logs should be archived\n\
--innobase_log_archive[=#] Set to 1 if you want to have logs archived\n\ --innobase_log_archive[=#] Set to 1 if you want to have logs archived\n\
--innobase_log_group_home_dir=dir Path to Innobase log files. --innobase_log_group_home_dir=dir Path to Innobase log files.\n\
--skip-innobase Don't use innobase (will save memory)\n\ --skip-innobase Don't use innobase (will save memory)\n\
"); ");
#endif /* HAVE_INNOBASE_DB */ #endif /* HAVE_INNOBASE_DB */
...@@ -3677,10 +3694,14 @@ static void get_options(int argc,char **argv) ...@@ -3677,10 +3694,14 @@ static void get_options(int argc,char **argv)
case OPT_MASTER_CONNECT_RETRY: case OPT_MASTER_CONNECT_RETRY:
master_connect_retry= atoi(optarg); master_connect_retry= atoi(optarg);
break; break;
case (int) OPT_SAFE_SHOW_DB: case OPT_SAFE_SHOW_DB:
opt_safe_show_db=1; opt_safe_show_db=1;
break; break;
case OPT_SKIP_SAFEMALLOC:
#ifdef SAFEMALLOC
sf_malloc_quick=1;
#endif
break;
default: default:
fprintf(stderr,"%s: Unrecognized option: %c\n",my_progname,c); fprintf(stderr,"%s: Unrecognized option: %c\n",my_progname,c);
use_help(); use_help();
......
...@@ -111,7 +111,8 @@ static void check_unused(void) ...@@ -111,7 +111,8 @@ static void check_unused(void)
#define check_unused() #define check_unused()
#endif #endif
int list_open_tables(THD *thd,List<char> *tables, const char *db,const char *wild) int list_open_tables(THD *thd,List<char> *tables, const char *db,
const char *wild)
{ {
int result = 0; int result = 0;
uint col_access=thd->col_access; uint col_access=thd->col_access;
...@@ -940,24 +941,28 @@ bool reopen_table(TABLE *table,bool locked) ...@@ -940,24 +941,28 @@ bool reopen_table(TABLE *table,bool locked)
goto end; goto end;
} }
tmp.key_length=table->key_length; /* This list copies variables set by open_table */
tmp.in_use=table->in_use;
tmp.used_keys=tmp.keys_in_use;
tmp.reginfo.lock_type=table->reginfo.lock_type;
tmp.version=refresh_version;
tmp.next=table->next;
tmp.prev=table->prev;
/* This list copies varibles set by open_table */
tmp.tablenr= table->tablenr; tmp.tablenr= table->tablenr;
tmp.tmp_table= table->tmp_table;
tmp.used_fields= table->used_fields; tmp.used_fields= table->used_fields;
tmp.const_table= table->const_table; tmp.const_table= table->const_table;
tmp.outer_join= table->outer_join; tmp.outer_join= table->outer_join;
tmp.null_row= table->null_row; tmp.null_row= table->null_row;
tmp.maybe_null= table->maybe_null;
tmp.status= table->status; tmp.status= table->status;
tmp.keys_in_use_for_query=tmp.used_keys=tmp.keys_in_use;
/* Get state */
tmp.key_length= table->key_length;
tmp.in_use= table->in_use;
tmp.reginfo.lock_type=table->reginfo.lock_type;
tmp.version= refresh_version;
tmp.tmp_table= table->tmp_table;
tmp.grant= table->grant; tmp.grant= table->grant;
/* Replace table in open list */
tmp.next=table->next;
tmp.prev=table->prev;
if (table->file) if (table->file)
VOID(closefrm(table)); // close file, free everything VOID(closefrm(table)); // close file, free everything
......
...@@ -136,9 +136,9 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), ...@@ -136,9 +136,9 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
(hash_get_key) get_var_key, (hash_get_key) get_var_key,
(void (*)(void*)) free_var,0); (void (*)(void*)) free_var,0);
#ifdef USING_TRANSACTIONS #ifdef USING_TRANSACTIONS
bzero((char*) &transaction,sizeof(transaction));
if (opt_using_transactions) if (opt_using_transactions)
{ {
bzero((char*) &transaction,sizeof(transaction));
if (open_cached_file(&transaction.trans_log, if (open_cached_file(&transaction.trans_log,
mysql_tmpdir, LOG_PREFIX, binlog_cache_size, mysql_tmpdir, LOG_PREFIX, binlog_cache_size,
MYF(MY_WME))) MYF(MY_WME)))
......
...@@ -1006,7 +1006,11 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) ...@@ -1006,7 +1006,11 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
if (pthread_kill(tmp->real_id,0)) if (pthread_kill(tmp->real_id,0))
tmp->proc_info="*** DEAD ***"; // This shouldn't happen tmp->proc_info="*** DEAD ***"; // This shouldn't happen
#endif #endif
#ifdef EXTRA_DEBUG
thd_info->start_time= tmp->time_after_lock;
#else
thd_info->start_time= tmp->start_time; thd_info->start_time= tmp->start_time;
#endif
thd_info->query=0; thd_info->query=0;
if (tmp->query) if (tmp->query)
{ {
......
...@@ -240,6 +240,7 @@ Open streams: %10lu\n", ...@@ -240,6 +240,7 @@ Open streams: %10lu\n",
fflush(stdout); fflush(stdout);
if (thd) if (thd)
thd->proc_info="malloc"; thd->proc_info="malloc";
my_checkmalloc();
TERMINATE(stdout); // Write malloc information TERMINATE(stdout); // Write malloc information
if (thd) if (thd)
thd->proc_info=0; 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, 1999 by Pruet Boonma <pruet@eng.cmu.ac.th>
Copyright (C) 1998 by Theppitak Karoonboonyanan <thep@links.nectec.or.th> Copyright (C) 1998 by Theppitak Karoonboonyanan <thep@links.nectec.or.th>
Copyright (C) 1989, 1991 by Samphan Raruenrom <samphan@thai.com> Copyright (C) 1989, 1991 by Samphan Raruenrom <samphan@thai.com>
...@@ -6,9 +8,10 @@ ...@@ -6,9 +8,10 @@
Permission to use, copy, modify, distribute and sell this software Permission to use, copy, modify, distribute and sell this software
and its documentation for any purpose is hereby granted without fee, and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies. provided that the above copyright notice appear in all copies.
Smaphan Raruenrom , Theppitak Karoonboonyanan and Pruet Boonma makes Samphan Raruenrom , Theppitak Karoonboonyanan , Pruet Boonma ,
no representations about the suitability of this software for any Korakot Chaovavanich and Apisilp Trunganont makes no representations
purpose. It is provided "as is" without express or implied warranty. 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] = { ...@@ -297,7 +300,8 @@ int t_ctype[][TOT_LEVELS] = {
/*0xFC*/ { IGNORE, IGNORE, IGNORE, IGNORE, X }, /*0xFC*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
/*0xFD*/ { IGNORE, IGNORE, IGNORE, IGNORE, X }, /*0xFD*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
/*0xFE*/ { 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] = uchar NEAR ctype_tis620[257] =
...@@ -436,10 +440,14 @@ uchar NEAR sort_order_tis620[]= ...@@ -436,10 +440,14 @@ uchar NEAR sort_order_tis620[]=
static uchar* thai2sortable(const uchar * tstr,uint len) static uchar* thai2sortable(const uchar * tstr,uint len)
{ {
/* We use only 3 levels (neglect capitalization). */
const uchar* p = tstr; const uchar* p = tstr;
uchar *outBuf; uchar *outBuf;
uchar *pRight1, *pRight2, *pRight3, *pRight4; // uchar *pRight1, *pRight2, *pRight3, *pRight4;
uchar *pLeft1, *pLeft2, *pLeft3, *pLeft4; // uchar *pLeft1, *pLeft2, *pLeft3, *pLeft4;
uchar *pRight1, *pRight2, *pRight3;
uchar *pLeft1, *pLeft2, *pLeft3;
uint bufSize; uint bufSize;
len = (uint) strnlen((char*) tstr,len); len = (uint) strnlen((char*) tstr,len);
...@@ -460,23 +468,23 @@ static uchar* thai2sortable(const uchar * tstr,uint len) ...@@ -460,23 +468,23 @@ static uchar* thai2sortable(const uchar * tstr,uint len)
return((uchar*) tstr); return((uchar*) tstr);
} }
pLeft3 = pRight3; pLeft3 = pRight3;
if(!(pRight4 = (uchar *)malloc(sizeof(uchar) * (len + 1)))) { /* if(!(pRight4 = (uchar *)malloc(sizeof(uchar) * (len + 1)))) {
free(pRight1); free(pRight1);
free(pRight2); free(pRight2);
free(pRight3); free(pRight3);
return((uchar*) tstr); return((uchar*) tstr);
} }
pLeft4 = pRight4; pLeft4 = pRight4;*/
while(len--) { while(len--) {
if(isldvowel(*p) && isconsnt(p[1])) { if(isldvowel(*p) && isconsnt(p[1])) {
*pRight1++ = t_ctype[p[1]][0]; *pRight1++ = t_ctype[p[1]][0];
*pRight2++ = t_ctype[p[1]][1]; *pRight2++ = t_ctype[p[1]][1];
*pRight3++ = t_ctype[p[1]][2]; *pRight3++ = t_ctype[p[1]][2];
*pRight4++ = t_ctype[p[1]][3]; // *pRight4++ = t_ctype[p[1]][3];
*pRight1++ = t_ctype[*p][0]; *pRight1++ = t_ctype[*p][0];
*pRight2++ = t_ctype[*p][1]; *pRight2++ = t_ctype[*p][1];
*pRight3++ = t_ctype[*p][2]; *pRight3++ = t_ctype[*p][2];
*pRight4++ = t_ctype[*p][3]; // *pRight4++ = t_ctype[*p][3];
len--; len--;
p += 2; p += 2;
} else { } else {
...@@ -486,23 +494,24 @@ static uchar* thai2sortable(const uchar * tstr,uint len) ...@@ -486,23 +494,24 @@ static uchar* thai2sortable(const uchar * tstr,uint len)
if(*pRight2 != IGNORE) pRight2++; if(*pRight2 != IGNORE) pRight2++;
*pRight3 = t_ctype[*p][2]; *pRight3 = t_ctype[*p][2];
if(*pRight3 != IGNORE) pRight3++; if(*pRight3 != IGNORE) pRight3++;
*pRight4 = t_ctype[*p][3]; /* *pRight4 = t_ctype[*p][3];
if(*pRight4 != IGNORE) pRight4++; if(*pRight4 != IGNORE) pRight4++;*/
p++; p++;
} }
} }
*pRight1++ = L2_BLANK; *pRight1++ = L2_BLANK;
*pRight2++ = L3_BLANK; *pRight2++ = L3_BLANK;
*pRight3++ = L4_BLANK; // *pRight3++ = L4_BLANK;
*pRight4++ = '\0'; *pRight3++ = '\0';
// *pRight4++ = '\0';
memcpy(pRight1, pLeft2, pRight2 - pLeft2); memcpy(pRight1, pLeft2, pRight2 - pLeft2);
pRight1 += pRight2 - pLeft2; pRight1 += pRight2 - pLeft2;
memcpy(pRight1, pLeft3, pRight3 - pLeft3); memcpy(pRight1, pLeft3, pRight3 - pLeft3);
pRight1 += pRight3 - pLeft3; // pRight1 += pRight3 - pLeft3;
memcpy(pRight1, pLeft4, pRight4 - pLeft4); // memcpy(pRight1, pLeft4, pRight4 - pLeft4);
free(pLeft2); free(pLeft2);
free(pLeft3); free(pLeft3);
free(pLeft4); // free(pLeft4);
return(outBuf); return(outBuf);
} }
...@@ -574,55 +583,58 @@ int my_strxfrm_tis620(uchar * dest, uchar * src, int len) ...@@ -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 Arg: String, its length, escape character, resource length, minimal string and maximum string
Ret: Alway 0 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, my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape,
uint res_length, char *min_str, char *max_str, uint res_length, char *min_str, char *max_str,
uint *min_length,uint *max_length) uint *min_length, uint *max_length)
{ {
char *end; const char *end=ptr+ptr_length;
char *min_org= min_str; char *min_org=min_str;
char *min_end = min_str + res_length; char *min_end=min_str+res_length;
char *tbuff; char *tmp;
uchar *tc;
uint tbuff_length;
tbuff = (char*) (tc=thai2sortable((uchar*) ptr, ptr_length)); for (; ptr != end && min_str != min_end ; ptr++)
tbuff_length = (uint) buffsize(ptr);
end = tbuff + tbuff_length;
for(;tbuff != end && min_str != min_end; tbuff++)
{ {
if(*tbuff == escape && tbuff + 1 != end) if (*ptr == escape && ptr+1 != end)
{ {
tbuff++; ptr++; // Skipp escape
*min_str++ = *max_str++ = *tbuff; *min_str++= *max_str++ = *ptr;
continue; continue;
} }
if(*tbuff == '_') if (*ptr == wild_one) // '_' in SQL
{ {
*min_str++ = '\0'; *min_str++='\0'; // This should be min char
*max_str++ = '\255'; *max_str++=max_sort_chr;
continue; continue;
} }
if(*tbuff == '%') if (*ptr == wild_many) // '%' in SQL
{ {
*min_length= (uint) (min_str - min_org); *min_length= (uint) (min_str - min_org);
*max_length= res_length; *max_length=res_length;
do do {
{ *min_str++ = ' '; // Because if key compression
*min_str++ = ' '; *max_str++ = max_sort_chr;
*max_str++ = '\255'; } while (min_str != min_end);
} while(min_str != min_end); return 0;
free(tc);
return(0);
} }
*min_str++ = *max_str++ = *tbuff; *min_str++= *max_str++ = *ptr;
} }
*min_length= *max_length = (uint) (min_str - min_org); *min_length= *max_length = (uint) (min_str - min_org);
while(min_str != min_end)
{ /* Temporary fix for handling wild_one at end of string (key compression) */
*min_str++ = *max_str++ = ' '; // for (tmp= min_str ; tmp > min_org && tmp[-1] == '\0';)
} // *--tmp=' ';
free(tc);
return(0); while (min_str != min_end)
*min_str++ = *max_str++ = ' '; // Because if key compression
return 0;
} }
/* Thai normalization for input sub system /* Thai normalization for input sub system
......
...@@ -47,9 +47,9 @@ server-id = 1 ...@@ -47,9 +47,9 @@ server-id = 1
#set-variable = bdb_max_lock=100000 #set-variable = bdb_max_lock=100000
# Uncomment the following if you are using Innobase tables # Uncomment the following if you are using Innobase tables
#innobase_data_home_dir = @datadir@ #innobase_data_home_dir = @localstatedir@/
#innobase_log_group_home_dir = @datadir@ #innobase_log_group_home_dir = @localstatedir@/
#innobase_log_arch_dir = @datadir@ #innobase_log_arch_dir = @localstatedir@/
#innobase_data_file_path = ibdata1:25M;ibdata2:37M;ibdata3:100M;ibdata4:300M #innobase_data_file_path = ibdata1:25M;ibdata2:37M;ibdata3:100M;ibdata4:300M
#set-variable = innobase_mirrored_log_groups=1 #set-variable = innobase_mirrored_log_groups=1
#set-variable = innobase_log_files_in_group=3 #set-variable = innobase_log_files_in_group=3
......
...@@ -43,9 +43,9 @@ server-id = 1 ...@@ -43,9 +43,9 @@ server-id = 1
#set-variable = bdb_max_lock=100000 #set-variable = bdb_max_lock=100000
# Uncomment the following if you are using Innobase tables # Uncomment the following if you are using Innobase tables
#innobase_data_home_dir = @datadir@ #innobase_data_home_dir = @localstatedir@/
#innobase_log_group_home_dir = @datadir@ #innobase_log_group_home_dir = @localstatedir@/
#innobase_log_arch_dir = @datadir@ #innobase_log_arch_dir = @localstatedir@/
#innobase_data_file_path = ibdata1:25M;ibdata2:37M;ibdata3:100M;ibdata4:300M #innobase_data_file_path = ibdata1:25M;ibdata2:37M;ibdata3:100M;ibdata4:300M
#set-variable = innobase_mirrored_log_groups=1 #set-variable = innobase_mirrored_log_groups=1
#set-variable = innobase_log_files_in_group=3 #set-variable = innobase_log_files_in_group=3
......
...@@ -45,9 +45,9 @@ server-id = 1 ...@@ -45,9 +45,9 @@ server-id = 1
#set-variable = bdb_max_lock=10000 #set-variable = bdb_max_lock=10000
# Uncomment the following if you are using Innobase tables # Uncomment the following if you are using Innobase tables
#innobase_data_home_dir = @datadir@ #innobase_data_home_dir = @localstatedir@/
#innobase_log_group_home_dir = @datadir@ #innobase_log_group_home_dir = @localstatedir@/
#innobase_log_arch_dir = @datadir@ #innobase_log_arch_dir = @localstatedir@/
#innobase_data_file_path = ibdata1:25M;ibdata2:37M;ibdata3:100M;ibdata4:300M #innobase_data_file_path = ibdata1:25M;ibdata2:37M;ibdata3:100M;ibdata4:300M
#set-variable = innobase_mirrored_log_groups=1 #set-variable = innobase_mirrored_log_groups=1
#set-variable = innobase_log_files_in_group=3 #set-variable = innobase_log_files_in_group=3
......
...@@ -42,9 +42,9 @@ server-id = 1 ...@@ -42,9 +42,9 @@ server-id = 1
#skip-bdb #skip-bdb
# Uncomment the following if you are using Innobase tables # Uncomment the following if you are using Innobase tables
#innobase_data_home_dir = @datadir@ #innobase_data_home_dir = @localstatedir@/
#innobase_log_group_home_dir = @datadir@ #innobase_log_group_home_dir = @localstatedir@/
#innobase_log_arch_dir = @datadir@ #innobase_log_arch_dir = @localstatedir@/
#innobase_data_file_path = ibdata1:25M;ibdata2:37M;ibdata3:100M;ibdata4:300M #innobase_data_file_path = ibdata1:25M;ibdata2:37M;ibdata3:100M;ibdata4:300M
#set-variable = innobase_mirrored_log_groups=1 #set-variable = innobase_mirrored_log_groups=1
#set-variable = innobase_log_files_in_group=3 #set-variable = innobase_log_files_in_group=3
......
#!/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