diff options
author | unknown <monty@mashka.mysql.fi> | 2002-08-08 03:29:36 +0300 |
---|---|---|
committer | unknown <monty@mashka.mysql.fi> | 2002-08-08 03:29:36 +0300 |
commit | a6b15fdd7682bffc2e197ac50e21332bb9bcf297 (patch) | |
tree | da5d29e4a08217e2773b16c5aef05ab734c760e4 | |
parent | 93f5a0616ab15113844fa211a26c44182af8018c (diff) | |
parent | f01f49916b7a0ea6eaf9f0e4e1dfad911584f8a2 (diff) | |
download | mariadb-git-a6b15fdd7682bffc2e197ac50e21332bb9bcf297.tar.gz |
merge
BitKeeper/etc/logging_ok:
auto-union
include/my_sys.h:
Auto merged
innobase/include/dyn0dyn.h:
Auto merged
innobase/include/dyn0dyn.ic:
Auto merged
myisam/mi_check.c:
Auto merged
sql/ha_berkeley.h:
Auto merged
sql/ha_innodb.h:
Auto merged
sql/item_func.cc:
Auto merged
sql/item_func.h:
Auto merged
sql/item_timefunc.h:
Auto merged
sql/lex.h:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/mysqld.cc:
Auto merged
sql/set_var.cc:
Auto merged
sql/sql_cache.cc:
Auto merged
sql/sql_delete.cc:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_select.cc:
Auto merged
sql/sql_update.cc:
Auto merged
sql/sql_yacc.yy:
Auto merged
225 files changed, 5958 insertions, 6144 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index b42fbc64c53..961cfb5c9a5 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -8,6 +8,7 @@ akishkin@work.mysql.com arjen@co3064164-a.bitbike.com arjen@fred.bitbike.com arjen@george.bitbike.com +bar@bar.udmsearch.izhnet.ru bell@sanja.is.com.ua davida@isil.mysql.com heikki@donna.mysql.fi diff --git a/Docs/manual.ja.texi b/Docs/manual.ja.texi index 34fb201aab4..2a0b0fbf34b 100644 --- a/Docs/manual.ja.texi +++ b/Docs/manual.ja.texi @@ -34271,7 +34271,7 @@ Some small changes to the join table optimizer to make some joins faster. @code{MYSQL} ¤È¤È¤·¤Æ¥³¡¼¥ë¤Ç¤¤º¡¢¤³¤ÎÂå¤ï¤ê¤Ë @code{mysql_field_count()} ¤ò »ÈÍѤ·¤Ê¤¯¤Æ¤Ï¤Ê¤ê¤Þ¤»¤ó¡£ @item -@code{LIBEWRAP} ¤ÎÄɲÃ; Patch by Henning P . Schmiedehausen. +@code{LIBWRAP} ¤ÎÄɲÃ; Patch by Henning P . Schmiedehausen. @item Don't allow @code{AUTO_INCREMENT} for other than numerical columns. @item diff --git a/Docs/manual.texi b/Docs/manual.texi index 1722455c7b2..28e2a027e7a 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -20066,14 +20066,16 @@ If the temporary file used for fast index creation would be bigger than using the key cache by the amount specified here, then prefer the key cache method. This is mainly used to force long character keys in large tables to use the slower key cache method to create the index. -@strong{Note} that this parameter is given in megabytes! +@strong{Note} that this parameter is given in megabytes before 4.0.3 and +in bytes starting from this version. @item @code{myisam_max_sort_file_size} The maximum size of the temporary file MySQL is allowed to use while recreating the index (during @code{REPAIR}, @code{ALTER TABLE} or @code{LOAD DATA INFILE}. If the file-size would be bigger than this, the index will be created through the key cache (which is slower). -@strong{Note} that this parameter is given in megabytes! +@strong{Note} that this parameter is given in megabytes before 4.0.3 and +in bytes starting from this version. @item @code{net_buffer_length} The communication buffer is reset to this size between queries. This @@ -23167,10 +23169,10 @@ exactly what @code{mysqld} thought the client sent to it. @c Note: this instance of "safe_mysql" should not be changed to "mysqld_safe" @c because it's a 3.23.x-specific command Older versions of the @code{mysql.server} script (from MySQL 3.23.4 to 3.23.8) -pass @code{safe_mysqld} a @code{--log} option. If you need better performance -when you start using MySQL in a production environment, you can remove the -@code{--log} option from @code{mysql.server} or change it to -@code{--log-bin}. +pass @code{safe_mysqld} a @code{--log} option (enable general query log). +If you need better performance when you start using MySQL in a production +environment, you can remove the @code{--log} option from @code{mysql.server} +or change it to @code{--log-bin}. @xref{Binary log}. The entries in this log are written as @code{mysqld} receives the questions. This may be different from the order in which the statements are executed. @@ -23249,7 +23251,9 @@ we recommend you to switch to this log format as soon as possible! The binary log contains all information that is available in the update log in a more efficient format. It also contains information about how long -every query that updated the database took. +every query that updated the database took. It doesn't contain queries that +doesn't modify any data. If you want to log all queries (for example to +find a problem query) you should use the general query log. @xref{Query log}. The binary log is also used when you are replicating a slave from a master. @xref{Replication}. @@ -23821,7 +23825,8 @@ the slave to apply updates from one database on the master to the one with a different name on the slave. @item Starting in Version 3.23.28, you can use @code{PURGE MASTER LOGS TO 'log-name'} -to get rid of old logs while the slave is running. +to get rid of old logs while the slave is running. This will remove all old +logs before, but not including @code{'log-name'}. @item Due to the non-transactional nature of MyISAM tables, it is possible to have a query that will only partially update a table and return an error code. This @@ -23854,7 +23859,6 @@ above bugs are conceptually very simple to fix, we have not yet found a way to do this without a sigficant code change that would compromize the stability status of 3.23 branch. There exists a workaround for both if in the rare case it happens to affect your application -- use @code{slave-skip-errors}. - @end itemize @@ -24124,6 +24128,10 @@ Example: Tells the slave server not to start the slave on the startup. The user can start it later with @code{SLAVE START}. +@item @code{slave_compressed_protocol=#} @tab +If 1, then use compression on the slave/client protocol if both +slave and master supports this. + @item @code{slave_net_timeout=#} @tab Number of seconds to wait for more data from the master before aborting the read. @@ -28621,6 +28629,7 @@ and if you can use @code{GLOBAL} or @code{SESSION} with them. @item delayed_queue_size @tab num @tab GLOBAL @item flush @tab bool @tab GLOBAL @item flush_time @tab num @tab GLOBAL +@item foreign_key_checks @tab bool @tab SESSION @item identity @tab num @tab SESSION @item insert_id @tab bool @tab SESSION @item interactive_timeout @tab num @tab GLOBAL | SESSION @@ -28657,6 +28666,7 @@ and if you can use @code{GLOBAL} or @code{SESSION} with them. @item rpl_recovery_rank @tab num @tab GLOBAL @item safe_show_database @tab bool @tab GLOBAL @item server_id @tab num @tab GLOBAL +@item slave_compressed_protocol @tab bool @tab GLOBAL @item slave_net_timeout @tab num @tab GLOBAL @item slow_launch_time @tab num @tab GLOBAL @item sort_buffer_size @tab num @tab GLOBAL | SESSION @@ -28682,6 +28692,7 @@ and if you can use @code{GLOBAL} or @code{SESSION} with them. @item tx_isolation @tab enum @tab GLOBAL | SESSION @item version @tab string @tab GLOBAL @item wait_timeout @tab num @tab GLOBAL | SESSION +@item unique_checks @tab bool @tab SESSION @end multitable Variables that are marked with @code{num} can be given a numerical @@ -37636,8 +37647,8 @@ The following options to @code{mysqld} can be used to change the behaviour of @item @code{--myisam-recover=#} @tab Automatic recovery of crashed tables. @item @code{-O myisam_sort_buffer_size=#} @tab Buffer used when recovering tables. @item @code{--delay-key-write-for-all-tables} @tab Don't flush key buffers between writes for any MyISAM table -@item @code{-O myisam_max_extra_sort_file_size=#} @tab Used to help MySQL to decide when to use the slow but safe key cache index create method. @strong{Note} that this parameter is given in megabytes! -@item @code{-O myisam_max_sort_file_size=#} @tab Don't use the fast sort index method to created index if the temporary file would get bigger than this. @strong{Note} that this paramter is given in megabytes! +@item @code{-O myisam_max_extra_sort_file_size=#} @tab Used to help MySQL to decide when to use the slow but safe key cache index create method. @strong{Note} that this parameter is given in megabytes before 4.0.3 and in bytes starting from this version. +@item @code{-O myisam_max_sort_file_size=#} @tab Don't use the fast sort index method to created index if the temporary file would get bigger than this. @strong{Note} that this parameter is given in megabytes before 4.0.3 and in bytes starting from this version. @item @code{-O bulk_insert_buffer_size=#} @tab Size of tree cache used in bulk insert optimisation. @strong{Note} that this is a limit @strong{per thread}! @end multitable @@ -50156,6 +50167,11 @@ each individual 4.0.x release. @itemize @bullet @item +Big code cleanup in replication code. +@item +If one specifies @code{--code-file}, call @code{setrlmit()} to change allowed +core file size to unlimited, to be able to generate core files. +@item Fixed bug in query cache after temporary table creation. @item Added @code{--count=N} (@code{-c}) to @code{mysqladmin}, to make the @@ -50183,7 +50199,7 @@ Fixed bug in query cache initialisation with very small query cache size. @item Allow @code{DEFAULT} with @code{INSERT} statement. @item -The startup parameters @code{myisam_max_extra_sort_file_size} and +The startup parameters @code{myisam_max_sort_file_size} and @code{myisam_max_extra_sort_file_size} are now given in bytes, not megabytes. @item External system locking of MyISAM/ISAM files is now turned off by default. @@ -50199,6 +50215,8 @@ Fixed a timing bug in @code{DROP DATABASE} New @code{SET [GLOBAL | SESSION]} syntax to change thread specific and global server variables at runtime. @item +Added variable @code{slave_compressed_protocol}. +@item Renamed variable @code{query_cache_startup_type} to @code{query_cache_type}, @code{myisam_bulk_insert_tree_size} to @code{bulk_insert_buffer_size}, @code{record_buffer} to @code{read_buffer_size} and @@ -50786,11 +50804,28 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.52 @itemize @bullet @item +Fixed bug with creating an auto-increment value on second part of a +@code{UNIQUE()} key where first part could contain NULL values. +@item +Don't write slave-timeout reconnects to the error log. +@item +Fixed bug with slave net read timeouting +@item +Fixed bug in ALTERing TABLE of BDB type. +@item +Fixed bug when logging @code{LOAD DATA INFILE} to binary log with no +active database. +@item +Fixed a bug in range optimiser (causing crashes). +@item Fixed possible problem in replication when doing @code{DROP DATABASE} on a database with @code{InnoDB} tables. @item -Fixed @code{mysql_info()} to return 0 for the 'Duplicates' value for -@code{INSERT DELAYED IGNORE} statements. +Fixed that @code{mysql_info()} returns 0 for 'Duplicates' when using +@code{INSERT DELAYED IGNORE}. +@item +Added @code{-DHAVE_BROKEN_REALPATH} to the Mac OS X (darwin) compile +options in @file{configure.in} to fix a failure under high load. @end itemize @node News-3.23.51, News-3.23.50, News-3.23.52, News-3.23.x @@ -53591,7 +53626,7 @@ All C client API macros are now functions to make shared libraries more reliable. Because of this, you can no longer call @code{mysql_num_fields()} on a @code{MYSQL} object, you must use @code{mysql_field_count()} instead. @item -Added use of @code{LIBEWRAP}; patch by Henning P. Schmiedehausen. +Added use of @code{LIBWRAP}; patch by Henning P. Schmiedehausen. @item Don't allow @code{AUTO_INCREMENT} for other than numerical columns. @item diff --git a/bdb/dist/acconfig.h b/bdb/dist/acconfig.h index e30d0e3d2c2..19f85a460d9 100644 --- a/bdb/dist/acconfig.h +++ b/bdb/dist/acconfig.h @@ -52,6 +52,7 @@ #undef HAVE_MUTEX_WIN16 #undef HAVE_MUTEX_WIN32 #undef HAVE_MUTEX_X86_GCC_ASSEMBLY +#undef HAVE_MUTEX_X86_64_GCC_ASSEMBLY /* Define if building on QNX. */ #undef HAVE_QNX diff --git a/bdb/dist/aclocal/mutex.m4 b/bdb/dist/aclocal/mutex.m4 index 5f16ee0e114..a6b1fa1a053 100644 --- a/bdb/dist/aclocal/mutex.m4 +++ b/bdb/dist/aclocal/mutex.m4 @@ -314,6 +314,18 @@ AC_TRY_RUN([main(){ }], [db_cv_mutex="x86/gcc-assembly"]) fi +dnl x86_64/gcc: FreeBSD, NetBSD, BSD/OS, Linux +if test "$db_cv_mutex" = no; then +AC_TRY_RUN([main(){ +#if defined(x86_64) || defined(__x86_64__) +#if defined(__GNUC__) + exit(0); +#endif +#endif + exit(1); +}], [db_cv_mutex="x86_64/gcc-assembly"]) +fi + dnl ia86/gcc: Linux if test "$db_cv_mutex" = no; then AC_TRY_RUN([main(){ diff --git a/bdb/include/mutex.h b/bdb/include/mutex.h index a8a41451012..4c1b265355d 100644 --- a/bdb/include/mutex.h +++ b/bdb/include/mutex.h @@ -611,6 +611,28 @@ typedef unsigned char tsl_t; #endif #endif +#ifdef HAVE_MUTEX_X86_64_GCC_ASSEMBLY +typedef unsigned char tsl_t; + +#ifdef LOAD_ACTUAL_MUTEX_CODE +/* + * For gcc/x86, 0 is clear, 1 is set. + */ +#define MUTEX_SET(tsl) ({ \ + register tsl_t *__l = (tsl); \ + int __r; \ + asm volatile("mov $1,%%rax; lock; xchgb %1,%%al; xor $1,%%rax"\ + : "=&a" (__r), "=m" (*__l) \ + : "1" (*__l) \ + ); \ + __r & 1; \ +}) + +#define MUTEX_UNSET(tsl) (*(tsl) = 0) +#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl) +#endif +#endif + /* * Mutex alignment defaults to one byte. * diff --git a/client/mysqltest.c b/client/mysqltest.c index 72c5c6bee5a..a50e8e4a14c 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -42,7 +42,7 @@ **********************************************************************/ -#define MTEST_VERSION "1.24" +#define MTEST_VERSION "1.25" #include <my_global.h> #include <mysql_embed.h> @@ -85,7 +85,7 @@ time */ #define CON_RETRY_SLEEP 2 -#define MAX_CON_TRIES 5 +#define MAX_CON_TRIES 5 #ifndef OS2 #define SLAVE_POLL_INTERVAL 300000 /* 0.3 of a sec */ @@ -101,7 +101,7 @@ static char *db = 0, *pass=0; const char* user = 0, *host = 0, *unix_sock = 0, *opt_basedir="./"; static int port = 0; static my_bool opt_big_test= 0, opt_compress= 0, silent= 0, verbose = 0, - tty_password= 0; + tty_password= 0; static uint start_lineno, *lineno; const char* manager_user="root",*manager_host=0; char *manager_pass=0; @@ -128,7 +128,7 @@ static uint global_expected_errno[MAX_EXPECTED_ERRORS], global_expected_errors; DYNAMIC_ARRAY q_lines; -typedef struct +typedef struct { char file[FN_REFLEN]; ulong pos; @@ -177,27 +177,27 @@ struct connection* cur_con, *next_con, *cons_end; /* Add new commands before Q_UNKNOWN !*/ enum enum_commands { -Q_CONNECTION=1, Q_QUERY, -Q_CONNECT, Q_SLEEP, -Q_INC, Q_DEC, -Q_SOURCE, Q_DISCONNECT, -Q_LET, Q_ECHO, -Q_WHILE, Q_END_BLOCK, -Q_SYSTEM, Q_RESULT, -Q_REQUIRE, Q_SAVE_MASTER_POS, -Q_SYNC_WITH_MASTER, Q_ERROR, -Q_SEND, Q_REAP, -Q_DIRTY_CLOSE, Q_REPLACE, -Q_PING, Q_EVAL, -Q_RPL_PROBE, Q_ENABLE_RPL_PARSE, +Q_CONNECTION=1, Q_QUERY, +Q_CONNECT, Q_SLEEP, +Q_INC, Q_DEC, +Q_SOURCE, Q_DISCONNECT, +Q_LET, Q_ECHO, +Q_WHILE, Q_END_BLOCK, +Q_SYSTEM, Q_RESULT, +Q_REQUIRE, Q_SAVE_MASTER_POS, +Q_SYNC_WITH_MASTER, Q_ERROR, +Q_SEND, Q_REAP, +Q_DIRTY_CLOSE, Q_REPLACE, +Q_PING, Q_EVAL, +Q_RPL_PROBE, Q_ENABLE_RPL_PARSE, Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT, Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG, Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG, Q_SERVER_START, Q_SERVER_STOP,Q_REQUIRE_MANAGER, Q_WAIT_FOR_SLAVE_TO_STOP, Q_REQUIRE_VERSION, -Q_UNKNOWN, /* Unknown command. */ -Q_COMMENT, /* Comments, ignored. */ +Q_UNKNOWN, /* Unknown command. */ +Q_COMMENT, /* Comments, ignored. */ Q_COMMENT_WITH_COMMAND }; @@ -215,18 +215,18 @@ struct st_query const char *command_names[] = { "connection", "query", - "connect", "sleep", - "inc", "dec", - "source", "disconnect", - "let", "echo", - "while", "end", - "system", "result", - "require", "save_master_pos", + "connect", "sleep", + "inc", "dec", + "source", "disconnect", + "let", "echo", + "while", "end", + "system", "result", + "require", "save_master_pos", "sync_with_master", "error", - "send", "reap", + "send", "reap", "dirty_close", "replace_result", - "ping", "eval", - "rpl_probe", "enable_rpl_parse", + "ping", "eval", + "rpl_probe", "enable_rpl_parse", "disable_rpl_parse", "eval_result", "enable_query_log", "disable_query_log", "enable_result_log", "disable_result_log", @@ -264,7 +264,7 @@ typedef struct st_pointer_array { /* when using array-strings */ TYPELIB typelib; /* Pointer to strings */ byte *str; /* Strings is here */ int7 *flag; /* Flag about each var. */ - uint array_allocs,max_count,length,max_length; + uint array_allocs,max_count,length,max_length; } POINTER_ARRAY; struct st_replace; @@ -314,39 +314,39 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char* query) register int escaped = 0; VAR* v; - for(p = query; (c = *p); ++p) - { - switch(c) - { - case '$': - if(escaped) - { - escaped = 0; - dynstr_append_mem(query_eval, p, 1); - } - else - { - if(!(v = var_get(p, &p, 0, 0))) - die("Bad variable in eval"); - dynstr_append_mem(query_eval, v->str_val, v->str_val_len); - } - break; - case '\\': - if(escaped) - { - escaped = 0; - dynstr_append_mem(query_eval, p, 1); - } - else - escaped = 1; - break; - default: - dynstr_append_mem(query_eval, p, 1); - break; - } + for (p= query; (c = *p); ++p) + { + switch(c) { + case '$': + if (escaped) + { + escaped = 0; + dynstr_append_mem(query_eval, p, 1); + } + else + { + if (!(v = var_get(p, &p, 0, 0))) + die("Bad variable in eval"); + dynstr_append_mem(query_eval, v->str_val, v->str_val_len); + } + break; + case '\\': + if (escaped) + { + escaped = 0; + dynstr_append_mem(query_eval, p, 1); + } + else + escaped = 1; + break; + default: + dynstr_append_mem(query_eval, p, 1); + break; } + } } + static void close_cons() { DBUG_ENTER("close_cons"); @@ -360,6 +360,7 @@ static void close_cons() DBUG_VOID_RETURN; } + static void close_files() { DBUG_ENTER("close_files"); @@ -371,14 +372,15 @@ static void close_files() DBUG_VOID_RETURN; } + static void free_used_memory() { uint i; DBUG_ENTER("free_used_memory"); -#ifndef EMBEDDED_LIBRARY +#ifndef EMBEDDED_LIBRARY if (manager) mysql_manager_close(manager); -#endif +#endif close_cons(); close_files(); hash_free(&var_hash); @@ -389,9 +391,9 @@ static void free_used_memory() my_free((gptr) (*q)->query_buf,MYF(MY_ALLOW_ZERO_PTR)); my_free((gptr) (*q),MYF(0)); } - for(i=0; i < 10; i++) + for (i=0; i < 10; i++) { - if(var_reg[i].alloced_len) + if (var_reg[i].alloced_len) my_free(var_reg[i].str_val, MYF(MY_WME)); } while (embedded_server_arg_count > 1) @@ -503,7 +505,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname) { do_eval(&res_ds, tmp); res_ptr = res_ds.str; - if((res_len = res_ds.length) != ds->length) + if ((res_len = res_ds.length) != ds->length) { res = 2; goto err; @@ -517,10 +519,10 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname) res = (memcmp(res_ptr, ds->str, res_len)) ? 1 : 0; -err: - if(res && eval_result) - str_to_file(fn_format(eval_file, fname, "", ".eval",2), res_ptr, - res_len); +err: + if (res && eval_result) + str_to_file(fn_format(eval_file, fname, "", ".eval",2), res_ptr, + res_len); my_free((gptr) tmp, MYF(0)); my_close(fd, MYF(MY_WME)); @@ -537,8 +539,7 @@ static int check_result(DYNAMIC_STRING* ds, const char* fname, if (res && require_option) abort_not_supported_test(); - switch (res) - { + switch (res) { case 0: break; /* ok */ case 2: @@ -592,7 +593,7 @@ VAR* var_get(const char* var_name, const char** var_name_end, my_bool raw, } --var_name; /* Point at last character */ } - else + else v = var_reg + digit; if (!raw && v->int_dirty) @@ -614,7 +615,7 @@ err: static VAR* var_obtain(char* name, int len) { VAR* v; - if((v = (VAR*)hash_search(&var_hash, name, len))) + if ((v = (VAR*)hash_search(&var_hash, name, len))) return v; v = var_init(0, name, len, "", 0); hash_insert(&var_hash, (byte*)v); @@ -637,7 +638,7 @@ int var_set(char* var_name, char* var_name_end, char* var_val, { v = var_obtain(var_name, var_name_end - var_name); } - else + else v = var_reg + digit; return eval_expr(v, var_val, (const char**)&var_val_end); @@ -667,7 +668,7 @@ int open_file(const char* name) int do_wait_for_slave_to_stop(struct st_query* q __attribute__((unused))) { MYSQL* mysql = &cur_con->mysql; -#ifndef OS2 +#ifndef OS2 struct timeval t; #endif for (;;) @@ -676,7 +677,7 @@ int do_wait_for_slave_to_stop(struct st_query* q __attribute__((unused))) MYSQL_ROW row; int done; LINT_INIT(res); - + if (mysql_query(mysql,"show status like 'Slave_running'") || !(res=mysql_store_result(mysql))) die("Query failed while probing slave for stop: %s", @@ -690,7 +691,7 @@ int do_wait_for_slave_to_stop(struct st_query* q __attribute__((unused))) mysql_free_result(res); if (done) break; -#ifndef OS2 +#ifndef OS2 t.tv_sec=0; t.tv_usec=SLAVE_POLL_INTERVAL; select(0,0,0,0,&t); /* sleep */ @@ -698,7 +699,7 @@ int do_wait_for_slave_to_stop(struct st_query* q __attribute__((unused))) DosSleep(OS2_SLAVE_POLL_INTERVAL); #endif } - + return 0; } @@ -761,7 +762,7 @@ int do_require_version(struct st_query* q) char* p=q->first_argument, *ver_arg; uint ver_arg_len,ver_len; LINT_INIT(res); - + if (!*p) die("Missing version argument in require_version\n"); ver_arg = p; @@ -769,7 +770,7 @@ int do_require_version(struct st_query* q) p++; *p = 0; ver_arg_len = p - ver_arg; - + if (mysql_query(mysql, "select version()") || !(res=mysql_store_result(mysql))) die("Query failed while check server version: %s", @@ -855,7 +856,7 @@ int eval_expr(VAR* v, const char* p, const char** p_end) return 0; } } - else if(*p == '`') + else if (*p == '`') { return var_query_set(v, p, p_end); } @@ -865,7 +866,7 @@ int eval_expr(VAR* v, const char* p, const char** p_end) (int) (*p_end - p) : (int) strlen(p); if (new_val_len + 1 >= v->alloced_len) { - v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ? + v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ? MIN_VAR_ALLOC : new_val_len + 1; if (!(v->str_val = v->str_val ? my_realloc(v->str_val, v->alloced_len+1, @@ -944,6 +945,7 @@ int do_echo(struct st_query* q) return 0; } + int do_sync_with_master(struct st_query* q) { MYSQL_RES* res; @@ -954,31 +956,36 @@ int do_sync_with_master(struct st_query* q) char* p = q->first_argument; int rpl_parse; + if (!master_pos.file[0]) + { + die("Line %u: Calling 'sync_with_master' without calling 'save_master_pos'", start_lineno); + } rpl_parse = mysql_rpl_parse_enabled(mysql); mysql_disable_rpl_parse(mysql); - if(*p) + if (*p) offset = atoi(p); sprintf(query_buf, "select master_pos_wait('%s', %ld)", master_pos.file, master_pos.pos + offset); - if(mysql_query(mysql, query_buf)) - die("At line %u: failed in %s: %d: %s", start_lineno, query_buf, + if (mysql_query(mysql, query_buf)) + die("line %u: failed in %s: %d: %s", start_lineno, query_buf, mysql_errno(mysql), mysql_error(mysql)); - if(!(last_result = res = mysql_store_result(mysql))) + if (!(last_result = res = mysql_store_result(mysql))) die("line %u: mysql_store_result() retuned NULL", start_lineno); - if(!(row = mysql_fetch_row(res))) + if (!(row = mysql_fetch_row(res))) die("line %u: empty result in %s", start_lineno, query_buf); - if(!row[0]) + if (!row[0]) die("Error on slave while syncing with master"); mysql_free_result(res); last_result=0; - if(rpl_parse) + if (rpl_parse) mysql_enable_rpl_parse(mysql); return 0; } + int do_save_master_pos() { MYSQL_RES* res; @@ -989,19 +996,19 @@ int do_save_master_pos() rpl_parse = mysql_rpl_parse_enabled(mysql); mysql_disable_rpl_parse(mysql); - if(mysql_query(mysql, "show master status")) + if (mysql_query(mysql, "show master status")) die("At line %u: failed in show master status: %d: %s", start_lineno, mysql_errno(mysql), mysql_error(mysql)); - if(!(last_result =res = mysql_store_result(mysql))) + if (!(last_result =res = mysql_store_result(mysql))) die("line %u: mysql_store_result() retuned NULL", start_lineno); - if(!(row = mysql_fetch_row(res))) + if (!(row = mysql_fetch_row(res))) die("line %u: empty result in show master status", start_lineno); - strncpy(master_pos.file, row[0], sizeof(master_pos.file)); - master_pos.pos = strtoul(row[1], (char**) 0, 10); + strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1); + master_pos.pos = strtoul(row[1], (char**) 0, 10); mysql_free_result(res); last_result=0; - if(rpl_parse) + if (rpl_parse) mysql_enable_rpl_parse(mysql); return 0; @@ -1027,7 +1034,7 @@ int do_let(struct st_query* q) int do_rpl_probe(struct st_query* q __attribute__((unused))) { - if(mysql_rpl_probe(&cur_con->mysql)) + if (mysql_rpl_probe(&cur_con->mysql)) die("Failed in mysql_rpl_probe(): %s", mysql_error(&cur_con->mysql)); return 0; } @@ -1079,7 +1086,7 @@ int do_sleep(struct st_query* q) p++; p_end = p + 6; - for(;p <= p_end; ++p) + for (;p <= p_end; ++p) { c = (int) (*p - '0'); if (c < 10 && (int) c >= 0) @@ -1882,7 +1889,7 @@ static my_bool get_one_option(int optid, const struct my_option *opt __attribute__((unused)), char *argument) { - switch(optid) { + switch(optid) { case '#': DBUG_PUSH(argument ? argument : "d:t:S:i:O,/tmp/mysqltest.trace"); break; @@ -1975,7 +1982,7 @@ int parse_args(int argc, char **argv) char* safe_str_append(char* buf, const char* str, int size) { int i,c ; - for(i = 0; (c = *str++) && i < size - 1; i++) + for (i = 0; (c = *str++) && i < size - 1; i++) *buf++ = c; *buf = 0; return buf; @@ -2024,7 +2031,7 @@ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, /* -* flags control the phased/stages of query execution to be performed +* flags control the phased/stages of query execution to be performed * if QUERY_SEND bit is on, the query will be sent. If QUERY_REAP is on * the result will be read - for regular query, both bits must be on */ @@ -2123,7 +2130,7 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags) dynstr_append_mem(ds,"\n",1); verbose_msg("query '%s' failed: %d: %s", q->query, mysql_errno(mysql), mysql_error(mysql)); - /* + /* if we do not abort on error, failure to run the query does not fail the whole test case */ @@ -2164,7 +2171,7 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags) while ((row = mysql_fetch_row(res))) { lengths = mysql_fetch_lengths(res); - for(i = 0; i < num_fields; i++) + for (i = 0; i < num_fields; i++) { val = (char*)row[i]; len = lengths[i]; @@ -2202,7 +2209,7 @@ end: last_result=0; if (ds == &ds_tmp) dynstr_free(&ds_tmp); - if(q->type == Q_EVAL) + if (q->type == Q_EVAL) dynstr_free(&eval_query); DBUG_RETURN(error); } @@ -2247,12 +2254,12 @@ static VAR* var_init(VAR* v, const char* name, int name_len, const char* val, if (!val_len && val) val_len = strlen(val) ; val_alloc_len = val_len + 16; /* room to grow */ - if (!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var) + if (!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var) + name_len, MYF(MY_WME)))) die("Out of memory"); tmp_var->name = (name) ? (char*) tmp_var + sizeof(*tmp_var) : 0; - tmp_var->alloced = (v == 0); + tmp_var->alloced = (v == 0); if (!(tmp_var->str_val = my_malloc(val_alloc_len+1, MYF(MY_WME)))) die("Out of memory"); @@ -2286,7 +2293,7 @@ static void var_from_env(const char* name, const char* def_val) if (!(tmp = getenv(name))) tmp = def_val; - v = var_init(0, name, 0, tmp, 0); + v = var_init(0, name, 0, tmp, 0); hash_insert(&var_hash, (byte*)v); } @@ -2377,12 +2384,12 @@ int main(int argc, char** argv) case Q_CONNECT: do_connect(q); break; case Q_CONNECTION: select_connection(q); break; case Q_DISCONNECT: - case Q_DIRTY_CLOSE: + case Q_DIRTY_CLOSE: close_connection(q); break; case Q_RPL_PROBE: do_rpl_probe(q); break; - case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(q); break; + case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(q); break; case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(q); break; - case Q_ENABLE_QUERY_LOG: disable_query_log=0; break; + case Q_ENABLE_QUERY_LOG: disable_query_log=0; break; case Q_DISABLE_QUERY_LOG: disable_query_log=1; break; case Q_ENABLE_RESULT_LOG: disable_result_log=0; break; case Q_DISABLE_RESULT_LOG: disable_result_log=1; break; @@ -2391,22 +2398,22 @@ int main(int argc, char** argv) case Q_REQUIRE_VERSION: do_require_version(q); break; case Q_WAIT_FOR_SLAVE_TO_STOP: do_wait_for_slave_to_stop(q); break; case Q_REQUIRE_MANAGER: do_require_manager(q); break; -#ifndef EMBEDDED_LIBRARY +#ifndef EMBEDDED_LIBRARY case Q_SERVER_START: do_server_start(q); break; case Q_SERVER_STOP: do_server_stop(q); break; -#endif +#endif case Q_INC: do_inc(q); break; case Q_DEC: do_dec(q); break; case Q_ECHO: do_echo(q); break; case Q_SYSTEM: do_system(q); break; case Q_LET: do_let(q); break; - case Q_EVAL_RESULT: eval_result = 1; break; + case Q_EVAL_RESULT: eval_result = 1; break; case Q_EVAL: - if (q->query == q->query_buf) + if (q->query == q->query_buf) q->query= q->first_argument; - /* fall through */ + /* fall through */ case Q_QUERY: - case Q_REAP: + case Q_REAP: { /* We read the result always regardless of the mode for both full @@ -2461,10 +2468,10 @@ int main(int argc, char** argv) case Q_REPLACE: get_replace(q); break; - case Q_SAVE_MASTER_POS: do_save_master_pos(); break; - case Q_SYNC_WITH_MASTER: do_sync_with_master(q); break; + case Q_SAVE_MASTER_POS: do_save_master_pos(); break; + case Q_SYNC_WITH_MASTER: do_sync_with_master(q); break; case Q_COMMENT: /* Ignore row */ - case Q_COMMENT_WITH_COMMAND: + case Q_COMMENT_WITH_COMMAND: case Q_PING: (void) mysql_ping(&cur_con->mysql); break; @@ -2475,8 +2482,7 @@ int main(int argc, char** argv) if (!processed) { current_line_inc = 0; - switch(q->type) - { + switch(q->type) { case Q_WHILE: do_while(q); break; case Q_END_BLOCK: do_done(q); break; default: current_line_inc = 1; break; @@ -2567,7 +2573,7 @@ static int read_server_arguments(const char* name) #define LAST_CHAR_CODE 259 typedef struct st_replace { - bool found; + bool found; struct st_replace *next[256]; } REPLACE; @@ -2673,12 +2679,12 @@ void free_pointer_array(POINTER_ARRAY *pa) #define SET_MALLOC_HUNC 64 typedef struct st_rep_set { - uint *bits; /* Pointer to used sets */ - short next[LAST_CHAR_CODE]; /* Pointer to next sets */ + uint *bits; /* Pointer to used sets */ + short next[LAST_CHAR_CODE]; /* Pointer to next sets */ uint found_len; /* Best match to date */ int found_offset; - uint table_offset; - uint size_of_bits; /* For convinience */ + uint table_offset; + uint size_of_bits; /* For convinience */ } REP_SET; typedef struct st_rep_sets { @@ -3209,7 +3215,7 @@ static uint replace_len(my_string str) /* Replace strings; Return length of result string */ -uint replace_strings(REPLACE *rep, my_string *start,uint *max_length, +uint replace_strings(REPLACE *rep, my_string *start,uint *max_length, const char *from) { reg1 REPLACE *rep_pos; @@ -3218,7 +3224,7 @@ uint replace_strings(REPLACE *rep, my_string *start,uint *max_length, end=(to= *start) + *max_length-1; rep_pos=rep+1; - for(;;) + for (;;) { while (!rep_pos->found) { diff --git a/configure.in b/configure.in index 144447d4cb6..48252847f53 100644 --- a/configure.in +++ b/configure.in @@ -2375,6 +2375,7 @@ AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile \ strings/Makefile regex/Makefile heap/Makefile \ bdb/Makefile \ myisam/Makefile myisammrg/Makefile \ + os2/Makefile os2/include/Makefile os2/include/sys/Makefile \ man/Makefile BUILD/Makefile readline/Makefile vio/Makefile \ libmysql_r/Makefile libmysqld/Makefile libmysqld/examples/Makefile \ libmysql/Makefile client/Makefile os2/Makefile \ diff --git a/include/Makefile.am b/include/Makefile.am index ed2401df9ec..576f557cdd3 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -22,7 +22,7 @@ pkginclude_HEADERS = dbug.h m_string.h my_sys.h my_list.h \ errmsg.h my_global.h my_net.h my_alloc.h\ sslopt-case.h sslopt-longopts.h sslopt-usage.h \ sslopt-vars.h $(BUILT_SOURCES) -noinst_HEADERS = config-win.h \ +noinst_HEADERS = config-win.h config-os2.h \ nisam.h heap.h merge.h my_bitmap.h\ myisam.h myisampack.h myisammrg.h ft_global.h\ my_dir.h mysys_err.h my_base.h \ diff --git a/include/config-os2.h b/include/config-os2.h index 2554cfd8495..7e9684ae3f5 100644 --- a/include/config-os2.h +++ b/include/config-os2.h @@ -26,6 +26,7 @@ #include <os2.h> #include <math.h> #include <io.h> +#include <types.h> /* Define to name of system eg solaris*/ #define SYSTEM_TYPE "IBM OS/2 Warp" @@ -55,6 +56,8 @@ #define FILE_BINARY O_BINARY /* my_fopen in binary mode */ #define S_IROTH S_IREAD /* for my_lib */ +#define CANT_DELETE_OPEN_FILES /* saves open files in a list, for delayed delete */ + #define O_NONBLOCK 0x10 #define NO_OPEN_3 /* For my_create() */ @@ -84,7 +87,7 @@ #define F_WRLCK 2 /* Write lock. */ #define F_UNLCK 0 /* Remove lock. */ -#define S_IFMT 0xF000 /* Mask for file type */ +#define S_IFMT 0x17000 /* Mask for file type */ #define F_TO_EOF 0L /* Param to lockf() to lock rest of file */ #define HUGE_PTR @@ -268,7 +271,7 @@ typedef unsigned long long os_off_t; /* #undef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT */ /* READLINE: */ -#define HAVE_POSIX_SIGNALS 1 +#define HAVE_POSIX_SIGNALS 0 /* sigwait with one argument */ /* #undef HAVE_NONPOSIX_SIGWAIT */ diff --git a/include/my_pthread.h b/include/my_pthread.h index a822d2db484..ffda1a42cc4 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -476,6 +476,9 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, #define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__) #define pthread_mutex_trylock(A) pthread_mutex_lock(A) #define pthread_mutex_t safe_mutex_t +#define safe_mutex_assert_owner(mp) DBUG_ASSERT((mp)->count > 0 && pthread_equal(pthread_self(),(mp)->thread)) +#else +#define safe_mutex_assert_owner(mp) #endif /* SAFE_MUTEX */ /* READ-WRITE thread locking */ diff --git a/include/my_sys.h b/include/my_sys.h index f310b3c3811..de60b7b1a03 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -558,7 +558,7 @@ extern void init_glob_errs(void); extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags); extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags); extern int my_fclose(FILE *fd,myf MyFlags); -extern int my_chsize(File fd,my_off_t newlength,myf MyFlags); +extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags); extern int my_error _VARARGS((int nr,myf MyFlags, ...)); extern int my_printf_error _VARARGS((uint my_err, const char *format, myf MyFlags, ...) @@ -680,6 +680,7 @@ extern int end_io_cache(IO_CACHE *info); extern uint my_b_fill(IO_CACHE *info); extern void my_b_seek(IO_CACHE *info,my_off_t pos); extern uint my_b_gets(IO_CACHE *info, char *to, uint max_length); +extern my_off_t my_b_filelength(IO_CACHE *info); extern uint my_b_printf(IO_CACHE *info, const char* fmt, ...); extern uint my_b_vprintf(IO_CACHE *info, const char* fmt, va_list ap); extern my_bool open_cached_file(IO_CACHE *cache,const char *dir, diff --git a/include/raid.h b/include/raid.h index 4a988760157..b5a5e665824 100644 --- a/include/raid.h +++ b/include/raid.h @@ -27,7 +27,10 @@ C_MODE_START extern const char *raid_type_string[]; C_MODE_END -#if defined(USE_RAID) && !defined(DONT_USE_RAID) +#ifdef DONT_USE_RAID +#undef USE_RAID +#endif +#if defined(USE_RAID) #ifdef __GNUC__ #pragma interface /* gcc class implementation */ @@ -41,7 +44,7 @@ C_MODE_END #define my_write(A,B,C,D) my_raid_write(A,B,C,D) #define my_pwrite(A,B,C,D,E) my_raid_pwrite(A,B,C,D,E) #define my_pread(A,B,C,D,E) my_raid_pread(A,B,C,D,E) -#define my_chsize(A,B,C) my_raid_chsize(A,B,C) +#define my_chsize(A,B,C,D) my_raid_chsize(A,B,C,D) #define my_close(A,B) my_raid_close(A,B) #define my_tell(A,B) my_raid_tell(A,B) #define my_seek(A,B,C,D) my_raid_seek(A,B,C,D) @@ -82,7 +85,7 @@ extern "C" { int my_raid_lock(File,int locktype, my_off_t start, my_off_t length, myf MyFlags); - int my_raid_chsize(File fd, my_off_t newlength, myf MyFlags); + int my_raid_chsize(File fd, my_off_t newlength, int filler, myf MyFlags); int my_raid_close(File, myf MyFlags); int my_raid_fstat(int Filedes, struct stat *buf, myf MyFlags); @@ -113,7 +116,7 @@ class RaidFd { int Write(const byte *Buffer, uint Count, myf MyFlags); int Read(const byte *Buffer, uint Count, myf MyFlags); int Lock(int locktype, my_off_t start, my_off_t length, myf MyFlags); - int Chsize(File fd, my_off_t newlength, myf MyFlags); + int Chsize(File fd, my_off_t newlength, int filler, myf MyFlags); int Fstat(int fd, MY_STAT *stat_area, myf MyFlags ); int Close(myf MyFlags); static bool IsRaid(File fd); diff --git a/include/violite.h b/include/violite.h index 40da31ee1b6..6b73dbcb943 100644 --- a/include/violite.h +++ b/include/violite.h @@ -60,7 +60,7 @@ int vio_write(Vio *vio, const gptr buf, int size); /* * Whenever the socket is set to blocking mode or not. */ -int vio_blocking(Vio *vio, my_bool onoff); +int vio_blocking(Vio *vio, my_bool onoff, my_bool *old_mode); my_bool vio_is_blocking(Vio *vio); /* * setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible. @@ -112,7 +112,8 @@ my_bool vio_poll_read(Vio *vio,uint timeout); #define vio_errno(vio) (vio)->vioerrno(vio) #define vio_read(vio, buf, size) (vio)->read(vio,buf,size) #define vio_write(vio, buf, size) (vio)->write(vio, buf, size) -#define vio_blocking(vio, set_blocking_mode) (vio)->vioblocking(vio, set_blocking_mode) +#define vio_blocking(vio, set_blocking_mode, old_mode)\ + (vio)->vioblocking(vio, set_blocking_mode, old_mode) #define vio_is_blocking(vio) (vio)->is_blocking(vio) #define vio_fastsend(vio) (vio)->fastsend(vio) #define vio_keepalive(vio, set_keep_alive) (vio)->viokeepalive(vio, set_keep_alive) @@ -213,7 +214,7 @@ struct st_vio int (*vioerrno)(Vio*); int (*read)(Vio*, gptr, int); int (*write)(Vio*, gptr, int); - int (*vioblocking)(Vio*, my_bool); + int (*vioblocking)(Vio*, my_bool, my_bool *); my_bool (*is_blocking)(Vio*); int (*viokeepalive)(Vio*, my_bool); int (*fastsend)(Vio*); diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index 0263996a429..38d97785832 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -572,6 +572,13 @@ btr_page_get_father_for_rec( if (btr_node_ptr_get_child_page_no(node_ptr) != buf_frame_get_page_no(page)) { + fprintf(stderr, +"InnoDB: Dump of the child page:\n"); + buf_page_print(buf_frame_align(page)); + fprintf(stderr, +"InnoDB: Dump of the parent page:\n"); + buf_page_print(buf_frame_align(node_ptr)); + fprintf(stderr, "InnoDB: Corruption of an index tree: table %s, index %s,\n" "InnoDB: father ptr page no %lu, child page no %lu\n", @@ -581,6 +588,12 @@ btr_page_get_father_for_rec( buf_frame_get_page_no(page)); page_rec_print(page_rec_get_next(page_get_infimum_rec(page))); page_rec_print(node_ptr); + + fprintf(stderr, +"InnoDB: You should dump + drop + reimport the table to fix the\n" +"InnoDB: corruption. If the crash happens at the database startup, see\n" +"InnoDB: section 6.1 of http://www.innodb.com/ibman.html about forcing\n" +"InnoDB: recovery. Then dump + drop + reimport.\n"); } ut_a(btr_node_ptr_get_child_page_no(node_ptr) == @@ -780,12 +793,14 @@ top_loop: /***************************************************************** Reorganizes an index page. */ - +static void btr_page_reorganize_low( /*====================*/ - ibool low, /* in: TRUE if locks should not be updated, i.e., - there cannot exist locks on the page */ + ibool recovery,/* in: TRUE if called in recovery: locks should not + be updated, i.e., there cannot exist locks on the + page, and a hash index should not be dropped: it + cannot exist */ page_t* page, /* in: page to be reorganized */ mtr_t* mtr) /* in: mtr */ { @@ -805,7 +820,9 @@ btr_page_reorganize_low( /* Copy the old page to temporary space */ buf_frame_copy(new_page, page); - btr_search_drop_page_hash_index(page); + if (!recovery) { + btr_search_drop_page_hash_index(page); + } /* Recreate the page: note that global data on page (possible segment headers, next page-field, etc.) is preserved intact */ @@ -820,7 +837,7 @@ btr_page_reorganize_low( /* Copy max trx id to recreated page */ page_set_max_trx_id(page, page_get_max_trx_id(new_page)); - if (!low) { + if (!recovery) { /* Update the record lock bitmaps */ lock_move_reorganize_page(page, new_page); } @@ -2059,8 +2076,7 @@ btr_discard_page( btr_search_drop_page_hash_index(page); - if ((left_page_no == FIL_NULL) - && (btr_page_get_level(page, mtr) > 0)) { + if (left_page_no == FIL_NULL && btr_page_get_level(page, mtr) > 0) { /* We have to mark the leftmost node pointer on the right side page as the predefined minimum record */ diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index 1274719cf7d..1fe322be81e 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -36,9 +36,16 @@ Created 10/16/1994 Heikki Tuuri #include "ibuf0ibuf.h" #include "lock0lock.h" +/* If the following is set to TRUE, this module prints a lot of +trace information of individual record operations */ +ibool btr_cur_print_record_ops = FALSE; + ulint btr_cur_rnd = 0; ulint btr_cur_n_non_sea = 0; +ulint btr_cur_n_sea = 0; +ulint btr_cur_n_non_sea_old = 0; +ulint btr_cur_n_sea_old = 0; /* In the optimistic insert, if the insert does not fit, but this much space can be released by page reorganize, then it is reorganized */ @@ -187,11 +194,7 @@ btr_cur_search_to_nth_level( tuple must be set so that it cannot get compared to the node ptr page number field! */ ulint mode, /* in: PAGE_CUR_L, ...; - NOTE that if the search is made using a unique - prefix of a record, mode should be - PAGE_CUR_LE, not PAGE_CUR_GE, as the latter - may end up on the previous page relative to the - record! Inserts should always be made using + Inserts should always be made using PAGE_CUR_LE to search the position! */ ulint latch_mode, /* in: BTR_SEARCH_LEAF, ..., ORed with BTR_INSERT and BTR_ESTIMATE; @@ -268,7 +271,7 @@ btr_cur_search_to_nth_level( #ifdef UNIV_SEARCH_PERF_STAT info->n_searches++; #endif - if (btr_search_latch.writer != RW_LOCK_NOT_LOCKED + if (btr_search_latch.writer == RW_LOCK_NOT_LOCKED && latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ && !estimate && btr_search_guess_on_hash(index, info, tuple, mode, @@ -283,14 +286,14 @@ btr_cur_search_to_nth_level( || mode != PAGE_CUR_LE); ut_ad(cursor->low_match != ULINT_UNDEFINED || mode != PAGE_CUR_LE); + btr_cur_n_sea++; + return; } #endif #endif - -#ifdef UNIV_SEARCH_PERF_STAT btr_cur_n_non_sea++; -#endif + /* If the hash search did not succeed, do binary search down the tree */ @@ -796,15 +799,28 @@ btr_cur_optimistic_insert( ulint data_size; ulint extra_size; ulint type; - ulint err; - - ut_ad(dtuple_check_typed(entry)); + ulint err; *big_rec = NULL; page = btr_cur_get_page(cursor); index = cursor->index; + if (!dtuple_check_typed_no_assert(entry)) { + fprintf(stderr, +"InnoDB: Error in a tuple to insert into table %lu index %lu\n", + index->table_name, index->name); + } + + if (btr_cur_print_record_ops && thr) { + printf( + "Trx with id %lu %lu going to insert to table %s index %s\n", + ut_dulint_get_high(thr_get_trx(thr)->id), + ut_dulint_get_low(thr_get_trx(thr)->id), + index->table_name, index->name); + dtuple_print(entry); + } + ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); max_size = page_get_max_insert_size_after_reorganize(page, 1); @@ -928,7 +944,7 @@ calculate_sizes_again: buf_frame_get_page_no(page), max_size, rec_size + PAGE_DIR_SLOT_SIZE, type); */ - if (!(type & (DICT_CLUSTERED | DICT_UNIQUE))) { + if (!(type & DICT_CLUSTERED)) { /* We have added a record to page: update its free bits */ ibuf_update_free_bits_if_full(cursor->index, page, max_size, rec_size + PAGE_DIR_SLOT_SIZE); @@ -1258,6 +1274,15 @@ btr_cur_update_sec_rec_in_place( rec = btr_cur_get_rec(cursor); + if (btr_cur_print_record_ops && thr) { + printf( + "Trx with id %lu %lu going to update table %s index %s\n", + ut_dulint_get_high(thr_get_trx(thr)->id), + ut_dulint_get_low(thr_get_trx(thr)->id), + index->table_name, index->name); + rec_print(rec); + } + err = lock_sec_rec_modify_check_and_lock(0, rec, index, thr); if (err != DB_SUCCESS) { @@ -1312,6 +1337,15 @@ btr_cur_update_in_place( index = cursor->index; trx = thr_get_trx(thr); + if (btr_cur_print_record_ops && thr) { + printf( + "Trx with id %lu %lu going to update table %s index %s\n", + ut_dulint_get_high(thr_get_trx(thr)->id), + ut_dulint_get_low(thr_get_trx(thr)->id), + index->table_name, index->name); + rec_print(rec); + } + /* Do lock checking and undo logging */ err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info, thr, &roll_ptr); @@ -1323,6 +1357,12 @@ btr_cur_update_in_place( block = buf_block_align(rec); if (block->is_hashed) { + if (row_upd_changes_ord_field_binary(NULL, index, update)) { + + /* Remove possible hash index pointer to this record */ + btr_search_update_hash_on_delete(cursor); + } + rw_lock_x_lock(&btr_search_latch); } @@ -1398,6 +1438,15 @@ btr_cur_optimistic_update( rec = btr_cur_get_rec(cursor); index = cursor->index; + if (btr_cur_print_record_ops && thr) { + printf( + "Trx with id %lu %lu going to update table %s index %s\n", + ut_dulint_get_high(thr_get_trx(thr)->id), + ut_dulint_get_low(thr_get_trx(thr)->id), + index->table_name, index->name); + rec_print(rec); + } + ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); if (!row_upd_changes_field_size(rec, index, update)) { @@ -1973,6 +2022,15 @@ btr_cur_del_mark_set_clust_rec( rec = btr_cur_get_rec(cursor); index = cursor->index; + if (btr_cur_print_record_ops && thr) { + printf( + "Trx with id %lu %lu going to del mark table %s index %s\n", + ut_dulint_get_high(thr_get_trx(thr)->id), + ut_dulint_get_low(thr_get_trx(thr)->id), + index->table_name, index->name); + rec_print(rec); + } + ut_ad(index->type & DICT_CLUSTERED); ut_ad(rec_get_deleted_flag(rec) == FALSE); @@ -2102,6 +2160,15 @@ btr_cur_del_mark_set_sec_rec( rec = btr_cur_get_rec(cursor); + if (btr_cur_print_record_ops && thr) { + printf( + "Trx with id %lu %lu going to del mark table %s index %s\n", + ut_dulint_get_high(thr_get_trx(thr)->id), + ut_dulint_get_low(thr_get_trx(thr)->id), + cursor->index->table_name, cursor->index->name); + rec_print(rec); + } + err = lock_sec_rec_modify_check_and_lock(flags, rec, cursor->index, thr); if (err != DB_SUCCESS) { diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c index 8a54d9de9c0..cfdfefebd1a 100644 --- a/innobase/btr/btr0sea.c +++ b/innobase/btr/btr0sea.c @@ -15,6 +15,7 @@ Created 2/17/1996 Heikki Tuuri #include "page0page.h" #include "page0cur.h" #include "btr0cur.h" +#include "btr0pcur.h" #include "btr0btr.h" ulint btr_search_n_succ = 0; @@ -145,6 +146,8 @@ btr_search_info_create( info = mem_heap_alloc(heap, sizeof(btr_search_t)); + info->magic_n = BTR_SEARCH_MAGIC_N; + info->last_search = NULL; info->n_direction = 0; info->root_guess = NULL; @@ -159,6 +162,12 @@ btr_search_info_create( info->n_patt_succ = 0; info->n_searches = 0; + /* Set some sensible values */ + info->n_fields = 1; + info->n_bytes = 0; + + info->side = BTR_SEARCH_LEFT_SIDE; + return(info); } @@ -197,7 +206,7 @@ btr_search_info_update_hash( /* Test if the search would have succeeded using the recommended hash prefix */ - if ((info->n_fields >= n_unique) && (cursor->up_match >= n_unique)) { + if (info->n_fields >= n_unique && cursor->up_match >= n_unique) { info->n_hash_potential++; @@ -207,8 +216,8 @@ btr_search_info_update_hash( cmp = ut_pair_cmp(info->n_fields, info->n_bytes, cursor->low_match, cursor->low_bytes); - if (((info->side == BTR_SEARCH_LEFT_SIDE) && (cmp <= 0)) - || ((info->side == BTR_SEARCH_RIGHT_SIDE) && (cmp > 0))) { + if ((info->side == BTR_SEARCH_LEFT_SIDE && cmp <= 0) + || (info->side == BTR_SEARCH_RIGHT_SIDE && cmp > 0)) { goto set_new_recomm; } @@ -216,8 +225,8 @@ btr_search_info_update_hash( cmp = ut_pair_cmp(info->n_fields, info->n_bytes, cursor->up_match, cursor->up_bytes); - if (((info->side == BTR_SEARCH_LEFT_SIDE) && (cmp > 0)) - || ((info->side == BTR_SEARCH_RIGHT_SIDE) && (cmp <= 0))) { + if ((info->side == BTR_SEARCH_LEFT_SIDE && cmp > 0) + || (info->side == BTR_SEARCH_RIGHT_SIDE && cmp <= 0)) { goto set_new_recomm; } @@ -233,19 +242,18 @@ set_new_recomm: info->hash_analysis = 0; - if ((cursor->up_match >= n_unique) - || (cursor->low_match >= n_unique)) { - info->n_fields = n_unique; - info->n_bytes = 0; - - info->side = BTR_SEARCH_LEFT_SIDE; - } - cmp = ut_pair_cmp(cursor->up_match, cursor->up_bytes, cursor->low_match, cursor->low_bytes); if (cmp == 0) { info->n_hash_potential = 0; + /* For extra safety, we set some sensible values here */ + + info->n_fields = 1; + info->n_bytes = 0; + + info->side = BTR_SEARCH_LEFT_SIDE; + } else if (cmp > 0) { info->n_hash_potential = 1; @@ -305,6 +313,9 @@ btr_search_update_block_hash_info( info->last_hash_succ = FALSE; + ut_a(block->magic_n == BUF_BLOCK_MAGIC_N); + ut_a(info->magic_n == BTR_SEARCH_MAGIC_N); + if ((block->n_hash_helps > 0) && (info->n_hash_potential > 0) && (block->n_fields == info->n_fields) @@ -440,7 +451,9 @@ btr_search_info_update_slow( rw_lock_x_unlock(&btr_search_latch); } - if (build_index) { + if (build_index) { + ut_a(block->n_fields + block->n_bytes > 0); + btr_search_build_page_hash_index(block->frame, block->n_fields, block->n_bytes, @@ -622,6 +635,7 @@ btr_search_guess_on_hash( dulint tree_id; #ifdef notdefined btr_cur_t cursor2; + btr_pcur_t pcur; #endif ut_ad(index && info && tuple && cursor && mtr); ut_ad((latch_mode == BTR_SEARCH_LEAF) @@ -664,6 +678,9 @@ btr_search_guess_on_hash( rw_lock_s_lock(&btr_search_latch); } + ut_a(btr_search_latch.writer != RW_LOCK_EX); + ut_a(btr_search_latch.reader_count > 0); + rec = ha_search_and_get_data(btr_search_sys->hash_index, fold); if (!rec) { @@ -754,7 +771,26 @@ btr_search_guess_on_hash( btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode, &cursor2, 0, mtr); - ut_a(btr_cur_get_rec(&cursor2) == btr_cur_get_rec(cursor)); + if (mode == PAGE_CUR_GE + && btr_cur_get_rec(&cursor2) == page_get_supremum_rec( + buf_frame_align(btr_cur_get_rec(&cursor2)))) { + + /* If mode is PAGE_CUR_GE, then the binary search + in the index tree may actually take us to the supremum + of the previous page */ + + info->last_hash_succ = FALSE; + + btr_pcur_open_on_user_rec(index, tuple, mode, latch_mode, + &pcur, mtr); + ut_a(btr_pcur_get_rec(&pcur) == btr_cur_get_rec(cursor)); + } else { + ut_a(btr_cur_get_rec(&cursor2) == btr_cur_get_rec(cursor)); + } + + /* NOTE that it is theoretically possible that the above assertions + fail if the page of the cursor gets removed from the buffer pool + meanwhile! Thus it might not be a bug. */ info->last_hash_succ = TRUE; #endif @@ -835,6 +871,8 @@ btr_search_drop_page_hash_index( n_fields = block->curr_n_fields; n_bytes = block->curr_n_bytes; + ut_a(n_fields + n_bytes > 0); + rw_lock_s_unlock(&btr_search_latch); n_recs = page_get_n_recs(page); @@ -851,6 +889,14 @@ btr_search_drop_page_hash_index( rec = page_get_infimum_rec(page); rec = page_rec_get_next(rec); + if (rec != sup) { + ut_a(n_fields <= rec_get_n_fields(rec)); + + if (n_bytes > 0) { + ut_a(n_fields < rec_get_n_fields(rec)); + } + } + tree_id = btr_page_get_index_id(page); prev_fold = 0; @@ -861,7 +907,7 @@ btr_search_drop_page_hash_index( fold = rec_fold(rec, n_fields, n_bytes, tree_id); - if ((fold == prev_fold) && (prev_fold != 0)) { + if (fold == prev_fold && prev_fold != 0) { goto next_rec; } @@ -873,6 +919,7 @@ btr_search_drop_page_hash_index( n_cached++; next_rec: rec = page_rec_get_next(rec); + prev_fold = fold; } rw_lock_x_lock(&btr_search_latch); @@ -913,7 +960,7 @@ btr_search_drop_page_hash_when_freed( mtr_start(&mtr); /* We assume that if the caller has a latch on the page, - then the caller has already drooped the hash index for the page, + then the caller has already dropped the hash index for the page, and we never get here. Therefore we can acquire the s-latch to the page without fearing a deadlock. */ @@ -980,6 +1027,8 @@ btr_search_build_page_hash_index( return; } + ut_a(n_fields + n_bytes > 0); + /* Calculate and cache fold values and corresponding records into an array for fast insertion to the hash index */ @@ -995,6 +1044,14 @@ btr_search_build_page_hash_index( rec = page_get_infimum_rec(page); rec = page_rec_get_next(rec); + if (rec != sup) { + ut_a(n_fields <= rec_get_n_fields(rec)); + + if (n_bytes > 0) { + ut_a(n_fields < rec_get_n_fields(rec)); + } + } + /* FIXME: in a mixed tree, all records may not have enough ordering fields: */ @@ -1126,6 +1183,8 @@ btr_search_move_or_delete_hash_entries( rw_lock_s_unlock(&btr_search_latch); + ut_a(n_fields + n_bytes > 0); + btr_search_build_page_hash_index(new_page, n_fields, n_bytes, side); ut_a(n_fields == block->curr_n_fields); @@ -1166,9 +1225,11 @@ btr_search_update_hash_on_delete( return; } + ut_a(block->curr_n_fields + block->curr_n_bytes > 0); + table = btr_search_sys->hash_index; - tree_id = ((cursor->index)->tree)->id; + tree_id = cursor->index->tree->id; fold = rec_fold(rec, block->curr_n_fields, block->curr_n_bytes, tree_id); @@ -1285,7 +1346,6 @@ btr_search_update_hash_on_insert( if (rec != page_get_infimum_rec(page)) { fold = rec_fold(rec, n_fields, n_bytes, tree_id); - } else { if (side == BTR_SEARCH_LEFT_SIDE) { @@ -1370,7 +1430,7 @@ btr_search_print_info(void) rw_lock_x_lock(&btr_search_latch); - ha_print_info(btr_search_sys->hash_index); +/* ha_print_info(btr_search_sys->hash_index); */ rw_lock_x_unlock(&btr_search_latch); } @@ -1436,11 +1496,71 @@ btr_search_validate(void) /*=====================*/ /* out: TRUE if ok */ { + buf_block_t* block; + page_t* page; + ha_node_t* node; + ulint n_page_dumps = 0; + ibool ok = TRUE; + ulint i; + char rec_str[500]; + rw_lock_x_lock(&btr_search_latch); + + for (i = 0; i < hash_get_n_cells(btr_search_sys->hash_index); i++) { + node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node; + + while (node != NULL) { + block = buf_block_align(node->data); + page = buf_frame_align(node->data); + + if (!block->is_hashed + || node->fold != rec_fold((rec_t*)(node->data), + block->curr_n_fields, + block->curr_n_bytes, + btr_page_get_index_id(page))) { + ok = FALSE; + ut_print_timestamp(stderr); + + fprintf(stderr, +" InnoDB: Error in an adaptive hash index pointer to page %lu\n" +"ptr mem address %lu index id %lu %lu, node fold %lu, rec fold %lu\n", + buf_frame_get_page_no(page), + (ulint)(node->data), + ut_dulint_get_high(btr_page_get_index_id(page)), + ut_dulint_get_low(btr_page_get_index_id(page)), + node->fold, rec_fold((rec_t*)(node->data), + block->curr_n_fields, + block->curr_n_bytes, + btr_page_get_index_id(page))); + + rec_sprintf(rec_str, 450, (rec_t*)(node->data)); + + fprintf(stderr, + "InnoDB: Record %s\n" + "InnoDB: on that page.", rec_str); + + fprintf(stderr, +"Page mem address %lu, is hashed %lu, n fields %lu, n bytes %lu\n" +"side %lu\n", + (ulint)page, block->is_hashed, block->curr_n_fields, + block->curr_n_bytes, block->curr_side); + + if (n_page_dumps < 20) { + buf_page_print(page); + n_page_dumps++; + } + } + + node = node->next; + } + } - ut_a(ha_validate(btr_search_sys->hash_index)); + if (!ha_validate(btr_search_sys->hash_index)) { + + ok = FALSE; + } rw_lock_x_unlock(&btr_search_latch); - return(TRUE); + return(ok); } diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c index e840e9f143d..663c6cefce6 100644 --- a/innobase/buf/buf0buf.c +++ b/innobase/buf/buf0buf.c @@ -1126,12 +1126,50 @@ buf_page_get_known_nowait( } /************************************************************************ +Inits a page to the buffer buf_pool, for use in ibbackup --restore. */ + +void +buf_page_init_for_backup_restore( +/*=============================*/ + ulint space, /* in: space id */ + ulint offset, /* in: offset of the page within space + in units of a page */ + buf_block_t* block) /* in: block to init */ +{ + /* Set the state of the block */ + block->magic_n = BUF_BLOCK_MAGIC_N; + + block->state = BUF_BLOCK_FILE_PAGE; + block->space = space; + block->offset = offset; + + block->lock_hash_val = 0; + block->lock_mutex = NULL; + + block->freed_page_clock = 0; + + block->newest_modification = ut_dulint_zero; + block->oldest_modification = ut_dulint_zero; + + block->accessed = FALSE; + block->buf_fix_count = 0; + block->io_fix = 0; + + block->n_hash_helps = 0; + block->is_hashed = FALSE; + block->n_fields = 1; + block->n_bytes = 0; + block->side = BTR_SEARCH_LEFT_SIDE; + + block->file_page_was_freed = FALSE; +} + +/************************************************************************ Inits a page to the buffer buf_pool. */ static void buf_page_init( /*==========*/ - /* out: pointer to the block */ ulint space, /* in: space id */ ulint offset, /* in: offset of the page within space in units of a page */ @@ -1141,6 +1179,8 @@ buf_page_init( ut_ad(block->state == BUF_BLOCK_READY_FOR_USE); /* Set the state of the block */ + block->magic_n = BUF_BLOCK_MAGIC_N; + block->state = BUF_BLOCK_FILE_PAGE; block->space = space; block->offset = offset; @@ -1758,8 +1798,10 @@ buf_get_n_pending_ios(void) Prints info of the buffer i/o. */ void -buf_print_io(void) -/*==============*/ +buf_print_io( +/*=========*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end)/* in: buffer end */ { time_t current_time; double time_elapsed; @@ -1767,19 +1809,28 @@ buf_print_io(void) ut_ad(buf_pool); + if (buf_end - buf < 400) { + + return; + } + size = buf_pool_get_curr_size() / UNIV_PAGE_SIZE; mutex_enter(&(buf_pool->mutex)); - printf("Free list length %lu \n", UT_LIST_GET_LEN(buf_pool->free)); - printf("LRU list length %lu \n", UT_LIST_GET_LEN(buf_pool->LRU)); - printf("Flush list length %lu \n", + buf += sprintf(buf, + "Free list length %lu \n", UT_LIST_GET_LEN(buf_pool->free)); + buf += sprintf(buf, + "LRU list length %lu \n", UT_LIST_GET_LEN(buf_pool->LRU)); + buf += sprintf(buf, + "Flush list length %lu \n", UT_LIST_GET_LEN(buf_pool->flush_list)); - printf("Buffer pool size %lu\n", size); + buf += sprintf(buf, "Buffer pool size %lu\n", size); - printf("Pending reads %lu \n", buf_pool->n_pend_reads); + buf += sprintf(buf, "Pending reads %lu \n", buf_pool->n_pend_reads); - printf("Pending writes: LRU %lu, flush list %lu, single page %lu\n", + buf += sprintf(buf, + "Pending writes: LRU %lu, flush list %lu, single page %lu\n", buf_pool->n_flush[BUF_FLUSH_LRU], buf_pool->n_flush[BUF_FLUSH_LIST], buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]); @@ -1789,10 +1840,10 @@ buf_print_io(void) buf_pool->last_printout_time = current_time; - printf("Pages read %lu, created %lu, written %lu\n", + buf += sprintf(buf, "Pages read %lu, created %lu, written %lu\n", buf_pool->n_pages_read, buf_pool->n_pages_created, buf_pool->n_pages_written); - printf("%.2f reads/s, %.2f creates/s, %.2f writes/s\n", + buf += sprintf(buf, "%.2f reads/s, %.2f creates/s, %.2f writes/s\n", (buf_pool->n_pages_read - buf_pool->n_pages_read_old) / time_elapsed, (buf_pool->n_pages_created - buf_pool->n_pages_created_old) @@ -1801,13 +1852,14 @@ buf_print_io(void) / time_elapsed); if (buf_pool->n_page_gets > buf_pool->n_page_gets_old) { - printf("Buffer pool hit rate %lu / 1000\n", + buf += sprintf(buf, "Buffer pool hit rate %lu / 1000\n", 1000 - ((1000 * (buf_pool->n_pages_read - buf_pool->n_pages_read_old)) / (buf_pool->n_page_gets - buf_pool->n_page_gets_old))); } else { - printf("No buffer pool activity since the last printout\n"); + buf += sprintf(buf, + "No buffer pool activity since the last printout\n"); } buf_pool->n_page_gets_old = buf_pool->n_page_gets; diff --git a/innobase/buf/buf0rea.c b/innobase/buf/buf0rea.c index db187cdd896..475a5bd9cbd 100644 --- a/innobase/buf/buf0rea.c +++ b/innobase/buf/buf0rea.c @@ -100,6 +100,11 @@ buf_read_page_low( block = buf_page_init_for_read(mode, space, offset); if (block != NULL) { + if (buf_debug_prints) { + printf("Posting read request for page %lu, sync %lu\n", + offset, sync); + } + fil_io(OS_FILE_READ | wake_later, sync, space, offset, 0, UNIV_PAGE_SIZE, (void*)block->frame, (void*)block); @@ -467,6 +472,12 @@ buf_read_ahead_linear( count = 0; + /* Since Windows XP seems to schedule the i/o handler thread + very eagerly, and consequently it does not wait for the + full read batch to be posted, we use special heuristics here */ + + os_aio_simulated_put_read_threads_to_sleep(); + for (i = low; i < high; i++) { /* It is only sensible to do read-ahead in the non-sync aio mode: hence FALSE as the first parameter */ @@ -556,16 +567,34 @@ buf_read_recv_pages( highest page number the last in the array */ ulint n_stored) /* in: number of page numbers in the array */ { + ulint count; ulint i; for (i = 0; i < n_stored; i++) { + count = 0; + + os_aio_print_debug = FALSE; + while (buf_pool->n_pend_reads >= RECV_POOL_N_FREE_BLOCKS / 2) { os_aio_simulated_wake_handler_threads(); os_thread_sleep(500000); + + count++; + + if (count > 100) { + fprintf(stderr, +"InnoDB: Error: InnoDB has waited for 50 seconds for pending\n" +"InnoDB: reads to the buffer pool to be finished.\n" +"InnoDB: Number of pending reads %lu\n", buf_pool->n_pend_reads); + + os_aio_print_debug = TRUE; + } } + os_aio_print_debug = FALSE; + if ((i + 1 == n_stored) && sync) { buf_read_page_low(TRUE, BUF_READ_ANY_PAGE, space, page_nos[i]); diff --git a/innobase/data/data0data.c b/innobase/data/data0data.c index 03abcb9b6e0..8ab5acb4da7 100644 --- a/innobase/data/data0data.c +++ b/innobase/data/data0data.c @@ -64,6 +64,35 @@ dtuple_get_nth_field_noninline( return(dtuple_get_nth_field(tuple, n)); } +/************************************************************************* +Tests if dfield data length and content is equal to the given. */ + +ibool +dfield_data_is_binary_equal( +/*========================*/ + /* out: TRUE if equal */ + dfield_t* field, /* in: field */ + ulint len, /* in: data length or UNIV_SQL_NULL */ + byte* data) /* in: data */ +{ + if (len != field->len) { + + return(FALSE); + } + + if (len == UNIV_SQL_NULL) { + + return(TRUE); + } + + if (0 != ut_memcmp(field->data, data, len)) { + + return(FALSE); + } + + return(TRUE); +} + /**************************************************************** Returns TRUE if lengths of two dtuples are equal and respective data fields in them are equal when compared with collation in char fields (not as binary @@ -154,6 +183,69 @@ dtuple_set_n_fields( } /************************************************************** +Checks that a data field is typed. */ +static +ibool +dfield_check_typed_no_assert( +/*=========================*/ + /* out: TRUE if ok */ + dfield_t* field) /* in: data field */ +{ + if (dfield_get_type(field)->mtype > DATA_MYSQL + || dfield_get_type(field)->mtype < DATA_VARCHAR) { + + fprintf(stderr, +"InnoDB: Error: data field type %lu, len %lu\n", + dfield_get_type(field)->mtype, dfield_get_len(field)); + return(FALSE); + } + + return(TRUE); +} + +/************************************************************** +Checks that a data tuple is typed. */ + +ibool +dtuple_check_typed_no_assert( +/*=========================*/ + /* out: TRUE if ok */ + dtuple_t* tuple) /* in: tuple */ +{ + dfield_t* field; + ulint i; + char err_buf[1000]; + + if (dtuple_get_n_fields(tuple) > REC_MAX_N_FIELDS) { + fprintf(stderr, +"InnoDB: Error: index entry has %lu fields\n", + dtuple_get_n_fields(tuple)); + + dtuple_sprintf(err_buf, 900, tuple); + fprintf(stderr, +"InnoDB: Tuple contents: %s\n", err_buf); + + return(FALSE); + } + + for (i = 0; i < dtuple_get_n_fields(tuple); i++) { + + field = dtuple_get_nth_field(tuple, i); + + if (!dfield_check_typed_no_assert(field)) { + + dtuple_sprintf(err_buf, 900, tuple); + fprintf(stderr, +"InnoDB: Tuple contents: %s\n", err_buf); + + return(FALSE); + } + } + + return(TRUE); +} + +/************************************************************** Checks that a data field is typed. Asserts an error if not. */ ibool @@ -162,8 +254,15 @@ dfield_check_typed( /* out: TRUE if ok */ dfield_t* field) /* in: data field */ { - ut_a(dfield_get_type(field)->mtype <= DATA_MYSQL); - ut_a(dfield_get_type(field)->mtype >= DATA_VARCHAR); + if (dfield_get_type(field)->mtype > DATA_MYSQL + || dfield_get_type(field)->mtype < DATA_VARCHAR) { + + fprintf(stderr, +"InnoDB: Error: data field type %lu, len %lu\n", + dfield_get_type(field)->mtype, dfield_get_len(field)); + + ut_a(0); + } return(TRUE); } @@ -460,9 +559,21 @@ dtuple_convert_big_rec( ibool is_externally_stored; ulint i; ulint j; + char err_buf[1000]; + ut_a(dtuple_check_typed_no_assert(entry)); + size = rec_get_converted_size(entry); + if (size > 1000000000) { + fprintf(stderr, +"InnoDB: Warning: tuple size very big: %lu\n", size); + + dtuple_sprintf(err_buf, 900, entry); + fprintf(stderr, +"InnoDB: Tuple contents: %s\n", err_buf); + } + heap = mem_heap_create(size + dtuple_get_n_fields(entry) * sizeof(big_rec_field_t) + 1000); diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c index 0da59d39646..60beeacf435 100644 --- a/innobase/dict/dict0crea.c +++ b/innobase/dict/dict0crea.c @@ -153,6 +153,7 @@ dict_create_sys_tables_tuple( if (table->type == DICT_TABLE_CLUSTER_MEMBER) { dfield_set_data(dfield, table->cluster_name, ut_strlen(table->cluster_name)); + ut_a(0); /* Oracle-style clusters are not supported yet */ } else { dfield_set_data(dfield, NULL, UNIV_SQL_NULL); } diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index b053724c0e3..5abec8dbb1e 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -261,7 +261,7 @@ dict_table_get_index_noninline( { return(dict_table_get_index(table, name)); } - + /************************************************************************ Initializes the autoinc counter. It is not an error to initialize an already initialized counter. */ @@ -2810,6 +2810,12 @@ dict_update_statistics_low( index = dict_table_get_first_index(table); + if (index == NULL) { + /* Table definition is corrupt */ + + return; + } + while (index) { size = btr_get_size(index, BTR_TOTAL_SIZE); @@ -3201,6 +3207,14 @@ dict_print_info_on_foreign_keys( buf2 += sprintf(buf2, ")"); + if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) { + buf2 += sprintf(buf2, " ON DELETE CASCADE"); + } + + if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) { + buf2 += sprintf(buf2, " ON DELETE SET NULL"); + } + foreign = UT_LIST_GET_NEXT(foreign_list, foreign); } diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c index 221a6c7dabb..e9caa37fecc 100644 --- a/innobase/dict/dict0load.c +++ b/innobase/dict/dict0load.c @@ -21,33 +21,6 @@ Created 4/24/1996 Heikki Tuuri #include "dict0boot.h" /************************************************************************ -Loads definitions for table columns. */ -static -void -dict_load_columns( -/*==============*/ - dict_table_t* table, /* in: table */ - mem_heap_t* heap); /* in: memory heap for temporary storage */ -/************************************************************************ -Loads definitions for table indexes. */ -static -void -dict_load_indexes( -/*==============*/ - dict_table_t* table, /* in: table */ - mem_heap_t* heap); /* in: memory heap for temporary storage */ -/************************************************************************ -Loads definitions for index fields. */ -static -void -dict_load_fields( -/*=============*/ - dict_table_t* table, /* in: table */ - dict_index_t* index, /* in: index whose fields to load */ - mem_heap_t* heap); /* in: memory heap for temporary storage */ - - -/************************************************************************ Finds the first table name in the given database. */ char* @@ -194,7 +167,12 @@ loop: fprintf(stderr, "InnoDB: Failed to load table %s\n", table_name); } else { - dict_update_statistics_low(table, TRUE); + /* The table definition was corrupt if there + is no index */ + + if (dict_table_get_first_index(table)) { + dict_update_statistics_low(table, TRUE); + } dict_table_print_low(table); } @@ -208,6 +186,361 @@ loop: } /************************************************************************ +Loads definitions for table columns. */ +static +void +dict_load_columns( +/*==============*/ + dict_table_t* table, /* in: table */ + mem_heap_t* heap) /* in: memory heap for temporary storage */ +{ + dict_table_t* sys_columns; + dict_index_t* sys_index; + btr_pcur_t pcur; + dtuple_t* tuple; + dfield_t* dfield; + rec_t* rec; + byte* field; + ulint len; + byte* buf; + char* name_buf; + char* name; + ulint mtype; + ulint prtype; + ulint col_len; + ulint prec; + ulint i; + mtr_t mtr; + + ut_ad(mutex_own(&(dict_sys->mutex))); + + mtr_start(&mtr); + + sys_columns = dict_table_get_low((char*) "SYS_COLUMNS"); + sys_index = UT_LIST_GET_FIRST(sys_columns->indexes); + + tuple = dtuple_create(heap, 1); + dfield = dtuple_get_nth_field(tuple, 0); + + buf = mem_heap_alloc(heap, 8); + mach_write_to_8(buf, table->id); + + dfield_set_data(dfield, buf, 8); + dict_index_copy_types(tuple, sys_index, 1); + + btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, + BTR_SEARCH_LEAF, &pcur, &mtr); + for (i = 0; i < table->n_cols - DATA_N_SYS_COLS; i++) { + + rec = btr_pcur_get_rec(&pcur); + + ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr)); + + ut_a(!rec_get_deleted_flag(rec)); + + field = rec_get_nth_field(rec, 0, &len); + ut_ad(len == 8); + ut_a(ut_dulint_cmp(table->id, mach_read_from_8(field)) == 0); + + field = rec_get_nth_field(rec, 1, &len); + ut_ad(len == 4); + ut_a(i == mach_read_from_4(field)); + + ut_a(0 == ut_strcmp((char*) "NAME", + dict_field_get_col( + dict_index_get_nth_field( + dict_table_get_first_index(sys_columns), 4))->name)); + + field = rec_get_nth_field(rec, 4, &len); + + name_buf = mem_heap_alloc(heap, len + 1); + ut_memcpy(name_buf, field, len); + name_buf[len] = '\0'; + + name = name_buf; + + field = rec_get_nth_field(rec, 5, &len); + mtype = mach_read_from_4(field); + + field = rec_get_nth_field(rec, 6, &len); + prtype = mach_read_from_4(field); + + field = rec_get_nth_field(rec, 7, &len); + col_len = mach_read_from_4(field); + + ut_a(0 == ut_strcmp((char*) "PREC", + dict_field_get_col( + dict_index_get_nth_field( + dict_table_get_first_index(sys_columns), 8))->name)); + + field = rec_get_nth_field(rec, 8, &len); + prec = mach_read_from_4(field); + + dict_mem_table_add_col(table, name, mtype, prtype, col_len, + prec); + btr_pcur_move_to_next_user_rec(&pcur, &mtr); + } + + btr_pcur_close(&pcur); + mtr_commit(&mtr); +} + +/************************************************************************ +Loads definitions for index fields. */ +static +void +dict_load_fields( +/*=============*/ + dict_table_t* table, /* in: table */ + dict_index_t* index, /* in: index whose fields to load */ + mem_heap_t* heap) /* in: memory heap for temporary storage */ +{ + dict_table_t* sys_fields; + dict_index_t* sys_index; + btr_pcur_t pcur; + dtuple_t* tuple; + dfield_t* dfield; + char* col_name; + rec_t* rec; + byte* field; + ulint len; + byte* buf; + ulint i; + mtr_t mtr; + + ut_ad(mutex_own(&(dict_sys->mutex))); + + UT_NOT_USED(table); + + mtr_start(&mtr); + + sys_fields = dict_table_get_low((char*) "SYS_FIELDS"); + sys_index = UT_LIST_GET_FIRST(sys_fields->indexes); + + tuple = dtuple_create(heap, 1); + dfield = dtuple_get_nth_field(tuple, 0); + + buf = mem_heap_alloc(heap, 8); + mach_write_to_8(buf, index->id); + + dfield_set_data(dfield, buf, 8); + dict_index_copy_types(tuple, sys_index, 1); + + btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, + BTR_SEARCH_LEAF, &pcur, &mtr); + for (i = 0; i < index->n_fields; i++) { + + rec = btr_pcur_get_rec(&pcur); + + ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr)); + if (rec_get_deleted_flag(rec)) { + fprintf(stderr, +"InnoDB: Error: data dictionary entry for table %s is corrupt!\n", +"InnoDB: An index field is delete marked.\n", + table->name); + } + + field = rec_get_nth_field(rec, 0, &len); + ut_ad(len == 8); + ut_a(ut_memcmp(buf, field, len) == 0); + + field = rec_get_nth_field(rec, 1, &len); + ut_ad(len == 4); + ut_a(i == mach_read_from_4(field)); + + ut_a(0 == ut_strcmp((char*) "COL_NAME", + dict_field_get_col( + dict_index_get_nth_field( + dict_table_get_first_index(sys_fields), 4))->name)); + + field = rec_get_nth_field(rec, 4, &len); + + col_name = mem_heap_alloc(heap, len + 1); + ut_memcpy(col_name, field, len); + col_name[len] = '\0'; + + dict_mem_index_add_field(index, col_name, 0); + + btr_pcur_move_to_next_user_rec(&pcur, &mtr); + } + + btr_pcur_close(&pcur); + mtr_commit(&mtr); +} + +/************************************************************************ +Loads definitions for table indexes. Adds them to the data dictionary +cache. */ +static +ibool +dict_load_indexes( +/*==============*/ + /* out: TRUE if ok, FALSE if corruption + of dictionary table */ + dict_table_t* table, /* in: table */ + mem_heap_t* heap) /* in: memory heap for temporary storage */ +{ + dict_table_t* sys_indexes; + dict_index_t* sys_index; + dict_index_t* index; + btr_pcur_t pcur; + dtuple_t* tuple; + dfield_t* dfield; + rec_t* rec; + byte* field; + ulint len; + ulint name_len; + char* name_buf; + ulint type; + ulint space; + ulint page_no; + ulint n_fields; + byte* buf; + ibool is_sys_table; + dulint id; + mtr_t mtr; + + ut_ad(mutex_own(&(dict_sys->mutex))); + + if ((ut_dulint_get_high(table->id) == 0) + && (ut_dulint_get_low(table->id) < DICT_HDR_FIRST_ID)) { + is_sys_table = TRUE; + } else { + is_sys_table = FALSE; + } + + mtr_start(&mtr); + + sys_indexes = dict_table_get_low((char*) "SYS_INDEXES"); + sys_index = UT_LIST_GET_FIRST(sys_indexes->indexes); + + tuple = dtuple_create(heap, 1); + dfield = dtuple_get_nth_field(tuple, 0); + + buf = mem_heap_alloc(heap, 8); + mach_write_to_8(buf, table->id); + + dfield_set_data(dfield, buf, 8); + dict_index_copy_types(tuple, sys_index, 1); + + btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, + BTR_SEARCH_LEAF, &pcur, &mtr); + for (;;) { + if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) { + + break; + } + + rec = btr_pcur_get_rec(&pcur); + + field = rec_get_nth_field(rec, 0, &len); + ut_ad(len == 8); + + if (ut_memcmp(buf, field, len) != 0) { + break; + } + + if (rec_get_deleted_flag(rec)) { + fprintf(stderr, +"InnoDB: Error: data dictionary entry for table %s is corrupt!\n" +"InnoDB: An index is delete marked.\n", + table->name); + + btr_pcur_close(&pcur); + mtr_commit(&mtr); + + return(FALSE); + } + + field = rec_get_nth_field(rec, 1, &len); + ut_ad(len == 8); + id = mach_read_from_8(field); + + ut_a(0 == ut_strcmp("NAME", + dict_field_get_col( + dict_index_get_nth_field( + dict_table_get_first_index(sys_indexes), 4))->name)); + + field = rec_get_nth_field(rec, 4, &name_len); + + name_buf = mem_heap_alloc(heap, name_len + 1); + ut_memcpy(name_buf, field, name_len); + name_buf[name_len] = '\0'; + + field = rec_get_nth_field(rec, 5, &len); + n_fields = mach_read_from_4(field); + + field = rec_get_nth_field(rec, 6, &len); + type = mach_read_from_4(field); + + field = rec_get_nth_field(rec, 7, &len); + space = mach_read_from_4(field); + + ut_a(0 == ut_strcmp((char*) "PAGE_NO", + dict_field_get_col( + dict_index_get_nth_field( + dict_table_get_first_index(sys_indexes), 8))->name)); + + field = rec_get_nth_field(rec, 8, &len); + page_no = mach_read_from_4(field); + + if (page_no == FIL_NULL) { + + fprintf(stderr, + "InnoDB: Error: trying to load index %s for table %s\n" + "InnoDB: but the index tree has been freed!\n", + name_buf, table->name); + + btr_pcur_close(&pcur); + mtr_commit(&mtr); + + return(FALSE); + } + + if ((type & DICT_CLUSTERED) == 0 + && NULL == dict_table_get_first_index(table)) { + + fprintf(stderr, + "InnoDB: Error: trying to load index %s for table %s\n" + "InnoDB: but the first index was not clustered!\n", + name_buf, table->name); + + btr_pcur_close(&pcur); + mtr_commit(&mtr); + + return(FALSE); + } + + if (is_sys_table + && ((type & DICT_CLUSTERED) + || ((table == dict_sys->sys_tables) + && (name_len == ut_strlen("ID_IND")) + && (0 == ut_memcmp(name_buf, "ID_IND", + name_len))))) { + + /* The index was created in memory already in + booting */ + } else { + index = dict_mem_index_create(table->name, name_buf, + space, type, n_fields); + index->page_no = page_no; + index->id = id; + + dict_load_fields(table, index, heap); + + dict_index_add_to_cache(table, index); + } + + btr_pcur_move_to_next_user_rec(&pcur, &mtr); + } + + btr_pcur_close(&pcur); + mtr_commit(&mtr); + + return(TRUE); +} + +/************************************************************************ Loads a table definition and also all its index definitions, and also the cluster definition if the table is a member in a cluster. Also loads all foreign key constraints where the foreign key is in the table or where @@ -338,7 +671,7 @@ dict_load_table( dict_load_columns(table, heap); dict_table_add_to_cache(table); - + dict_load_indexes(table, heap); ut_a(DB_SUCCESS == dict_load_foreigns(table->name)); @@ -436,8 +769,6 @@ dict_load_table_on_id( /* Load the table definition to memory */ table = dict_load_table(name); - - ut_a(table); btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -468,324 +799,6 @@ dict_load_sys_table( } /************************************************************************ -Loads definitions for table columns. */ -static -void -dict_load_columns( -/*==============*/ - dict_table_t* table, /* in: table */ - mem_heap_t* heap) /* in: memory heap for temporary storage */ -{ - dict_table_t* sys_columns; - dict_index_t* sys_index; - btr_pcur_t pcur; - dtuple_t* tuple; - dfield_t* dfield; - rec_t* rec; - byte* field; - ulint len; - byte* buf; - char* name_buf; - char* name; - ulint mtype; - ulint prtype; - ulint col_len; - ulint prec; - ulint i; - mtr_t mtr; - - ut_ad(mutex_own(&(dict_sys->mutex))); - - mtr_start(&mtr); - - sys_columns = dict_table_get_low((char *) "SYS_COLUMNS"); - sys_index = UT_LIST_GET_FIRST(sys_columns->indexes); - - tuple = dtuple_create(heap, 1); - dfield = dtuple_get_nth_field(tuple, 0); - - buf = mem_heap_alloc(heap, 8); - mach_write_to_8(buf, table->id); - - dfield_set_data(dfield, buf, 8); - dict_index_copy_types(tuple, sys_index, 1); - - btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, - BTR_SEARCH_LEAF, &pcur, &mtr); - for (i = 0; i < table->n_cols - DATA_N_SYS_COLS; i++) { - - rec = btr_pcur_get_rec(&pcur); - - ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr)); - - ut_a(!rec_get_deleted_flag(rec)); - - field = rec_get_nth_field(rec, 0, &len); - ut_ad(len == 8); - ut_a(ut_dulint_cmp(table->id, mach_read_from_8(field)) == 0); - - field = rec_get_nth_field(rec, 1, &len); - ut_ad(len == 4); - ut_a(i == mach_read_from_4(field)); - - ut_a(0 == ut_strcmp((char *) "NAME", - dict_field_get_col( - dict_index_get_nth_field( - dict_table_get_first_index(sys_columns), 4))->name)); - - field = rec_get_nth_field(rec, 4, &len); - - name_buf = mem_heap_alloc(heap, len + 1); - ut_memcpy(name_buf, field, len); - name_buf[len] = '\0'; - - name = name_buf; - - field = rec_get_nth_field(rec, 5, &len); - mtype = mach_read_from_4(field); - - field = rec_get_nth_field(rec, 6, &len); - prtype = mach_read_from_4(field); - - field = rec_get_nth_field(rec, 7, &len); - col_len = mach_read_from_4(field); - - ut_a(0 == ut_strcmp((char *) "PREC", - dict_field_get_col( - dict_index_get_nth_field( - dict_table_get_first_index(sys_columns), 8))->name)); - - field = rec_get_nth_field(rec, 8, &len); - prec = mach_read_from_4(field); - - dict_mem_table_add_col(table, name, mtype, prtype, col_len, - prec); - btr_pcur_move_to_next_user_rec(&pcur, &mtr); - } - - btr_pcur_close(&pcur); - mtr_commit(&mtr); -} - -/************************************************************************ -Loads definitions for table indexes. Adds them to the data dictionary cache. -*/ -static -void -dict_load_indexes( -/*==============*/ - dict_table_t* table, /* in: table */ - mem_heap_t* heap) /* in: memory heap for temporary storage */ -{ - dict_table_t* sys_indexes; - dict_index_t* sys_index; - dict_index_t* index; - btr_pcur_t pcur; - dtuple_t* tuple; - dfield_t* dfield; - rec_t* rec; - byte* field; - ulint len; - ulint name_len; - char* name_buf; - ulint type; - ulint space; - ulint page_no; - ulint n_fields; - byte* buf; - ibool is_sys_table; - dulint id; - mtr_t mtr; - - ut_ad(mutex_own(&(dict_sys->mutex))); - - if ((ut_dulint_get_high(table->id) == 0) - && (ut_dulint_get_low(table->id) < DICT_HDR_FIRST_ID)) { - is_sys_table = TRUE; - } else { - is_sys_table = FALSE; - } - - mtr_start(&mtr); - - sys_indexes = dict_table_get_low((char *) "SYS_INDEXES"); - sys_index = UT_LIST_GET_FIRST(sys_indexes->indexes); - - tuple = dtuple_create(heap, 1); - dfield = dtuple_get_nth_field(tuple, 0); - - buf = mem_heap_alloc(heap, 8); - mach_write_to_8(buf, table->id); - - dfield_set_data(dfield, buf, 8); - dict_index_copy_types(tuple, sys_index, 1); - - btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, - BTR_SEARCH_LEAF, &pcur, &mtr); - for (;;) { - if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) { - - break; - } - - rec = btr_pcur_get_rec(&pcur); - - field = rec_get_nth_field(rec, 0, &len); - ut_ad(len == 8); - - if (ut_memcmp(buf, field, len) != 0) { - break; - } - - ut_a(!rec_get_deleted_flag(rec)); - - field = rec_get_nth_field(rec, 1, &len); - ut_ad(len == 8); - id = mach_read_from_8(field); - - ut_a(0 == ut_strcmp((char *) "NAME", - dict_field_get_col( - dict_index_get_nth_field( - dict_table_get_first_index(sys_indexes), 4))->name)); - - field = rec_get_nth_field(rec, 4, &name_len); - - name_buf = mem_heap_alloc(heap, name_len + 1); - ut_memcpy(name_buf, field, name_len); - name_buf[name_len] = '\0'; - - field = rec_get_nth_field(rec, 5, &len); - n_fields = mach_read_from_4(field); - - field = rec_get_nth_field(rec, 6, &len); - type = mach_read_from_4(field); - - field = rec_get_nth_field(rec, 7, &len); - space = mach_read_from_4(field); - - ut_a(0 == ut_strcmp((char *) "PAGE_NO", - dict_field_get_col( - dict_index_get_nth_field( - dict_table_get_first_index(sys_indexes), 8))->name)); - - field = rec_get_nth_field(rec, 8, &len); - page_no = mach_read_from_4(field); - - if (is_sys_table - && ((type & DICT_CLUSTERED) - || ((table == dict_sys->sys_tables) - && (name_len == ut_strlen((char *) "ID_IND")) - && (0 == ut_memcmp(name_buf, (char *) "ID_IND", - name_len))))) { - - /* The index was created in memory already in - booting */ - } else { - index = dict_mem_index_create(table->name, name_buf, - space, type, n_fields); - index->page_no = page_no; - index->id = id; - - dict_load_fields(table, index, heap); - - if (index->type & DICT_CLUSTERED == 0 - && NULL == dict_table_get_first_index(table)) { - - fprintf(stderr, - "InnoDB: Error: trying to load index %s for table %s\n" - "InnoDB: but the first index was not clustered\n", - index->name, table->name); - } else { - dict_index_add_to_cache(table, index); - } - } - - btr_pcur_move_to_next_user_rec(&pcur, &mtr); - } - - btr_pcur_close(&pcur); - mtr_commit(&mtr); -} - -/************************************************************************ -Loads definitions for index fields. */ -static -void -dict_load_fields( -/*=============*/ - dict_table_t* table, /* in: table */ - dict_index_t* index, /* in: index whose fields to load */ - mem_heap_t* heap) /* in: memory heap for temporary storage */ -{ - dict_table_t* sys_fields; - dict_index_t* sys_index; - btr_pcur_t pcur; - dtuple_t* tuple; - dfield_t* dfield; - char* col_name; - rec_t* rec; - byte* field; - ulint len; - byte* buf; - ulint i; - mtr_t mtr; - - ut_ad(mutex_own(&(dict_sys->mutex))); - - UT_NOT_USED(table); - - mtr_start(&mtr); - - sys_fields = dict_table_get_low((char *) "SYS_FIELDS"); - sys_index = UT_LIST_GET_FIRST(sys_fields->indexes); - - tuple = dtuple_create(heap, 1); - dfield = dtuple_get_nth_field(tuple, 0); - - buf = mem_heap_alloc(heap, 8); - mach_write_to_8(buf, index->id); - - dfield_set_data(dfield, buf, 8); - dict_index_copy_types(tuple, sys_index, 1); - - btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, - BTR_SEARCH_LEAF, &pcur, &mtr); - for (i = 0; i < index->n_fields; i++) { - - rec = btr_pcur_get_rec(&pcur); - - ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr)); - ut_a(!rec_get_deleted_flag(rec)); - - field = rec_get_nth_field(rec, 0, &len); - ut_ad(len == 8); - ut_a(ut_memcmp(buf, field, len) == 0); - - field = rec_get_nth_field(rec, 1, &len); - ut_ad(len == 4); - ut_a(i == mach_read_from_4(field)); - - ut_a(0 == ut_strcmp((char *) "COL_NAME", - dict_field_get_col( - dict_index_get_nth_field( - dict_table_get_first_index(sys_fields), 4))->name)); - - field = rec_get_nth_field(rec, 4, &len); - - col_name = mem_heap_alloc(heap, len + 1); - ut_memcpy(col_name, field, len); - col_name[len] = '\0'; - - dict_mem_index_add_field(index, col_name, 0); - - btr_pcur_move_to_next_user_rec(&pcur, &mtr); - } - - btr_pcur_close(&pcur); - mtr_commit(&mtr); -} - -/************************************************************************ Loads foreign key constraint col names (also for the referenced table). */ static void diff --git a/innobase/dict/dict0mem.c b/innobase/dict/dict0mem.c index 52f46062065..9a4c94de885 100644 --- a/innobase/dict/dict0mem.c +++ b/innobase/dict/dict0mem.c @@ -65,6 +65,9 @@ dict_mem_table_create( table->cached = FALSE; + table->mix_id = ut_dulint_zero; + table->mix_len = 0; + table->cols = mem_heap_alloc(heap, (n_cols + DATA_N_SYS_COLS) * sizeof(dict_col_t)); UT_LIST_INIT(table->indexes); diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index 35f3792f041..da4aee5db76 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -573,17 +573,20 @@ fil_read_flushed_lsn_and_arch_log_no( ulint* max_arch_log_no) /* in/out: */ { byte* buf; + byte* buf2; dulint flushed_lsn; ulint arch_log_no; - buf = ut_malloc(UNIV_PAGE_SIZE); - + buf2 = ut_malloc(2 * UNIV_PAGE_SIZE); + /* Align the memory for a possibel read from a raw device */ + buf = ut_align(buf2, UNIV_PAGE_SIZE); + os_file_read(data_file, buf, 0, 0, UNIV_PAGE_SIZE); flushed_lsn = mach_read_from_8(buf + FIL_PAGE_FILE_FLUSH_LSN); arch_log_no = mach_read_from_4(buf + FIL_PAGE_ARCH_LOG_NO); - ut_free(buf); + ut_free(buf2); if (!one_read_already) { *min_flushed_lsn = flushed_lsn; diff --git a/innobase/fsp/fsp0fsp.c b/innobase/fsp/fsp0fsp.c index 08608731f2e..32e7f5bcad7 100644 --- a/innobase/fsp/fsp0fsp.c +++ b/innobase/fsp/fsp0fsp.c @@ -2608,6 +2608,7 @@ fseg_free_page_low( ulint not_full_n_used; ulint state; ulint i; + char errbuf[200]; ut_ad(seg_inode && mtr); ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N) == @@ -2621,8 +2622,25 @@ fseg_free_page_low( descr = xdes_get_descriptor(space, page, mtr); ut_a(descr); - ut_a(xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr) - == FALSE); + if (xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr) + != FALSE) { + ut_sprintf_buf(errbuf, descr, 40); + fprintf(stderr, +"InnoDB: Dump of the tablespace extent descriptor: %s\n", errbuf); + + fprintf(stderr, +"InnoDB: Serious error! InnoDB is trying to free page %lu\n", +"InnoDB: though it is already marked as free in the tablespace!\n" +"InnoDB: The tablespace free space info is corrupt.\n" +"InnoDB: You may need to dump your InnoDB tables and recreate the whole\n" +"InnoDB: database!\n", page); + + fprintf(stderr, +"InnoDB: If the InnoDB recovery crashes here, see section 6.1\n" +"InnoDB: of http://www.innodb.com/ibman.html about forcing recovery.\n"); + ut_a(0); + } + state = xdes_get_state(descr, mtr); if (state != XDES_FSEG) { diff --git a/innobase/ha/ha0ha.c b/innobase/ha/ha0ha.c index 3e4473126cf..c3ad6cdca76 100644 --- a/innobase/ha/ha0ha.c +++ b/innobase/ha/ha0ha.c @@ -194,7 +194,7 @@ ha_delete( node = ha_search_with_data(table, fold, data); - ut_ad(node); + ut_a(node); ha_delete_hash_node(table, node); } @@ -232,6 +232,16 @@ ha_remove_all_nodes_to_page( node = ha_chain_get_next(table, node); } } + + /* Check that all nodes really got deleted */ + + node = ha_chain_get_first(table, fold); + + while (node) { + ut_a(buf_frame_align(ha_node_get_data(node)) != page); + + node = ha_chain_get_next(table, node); + } } /***************************************************************** @@ -245,6 +255,7 @@ ha_validate( { hash_cell_t* cell; ha_node_t* node; + ibool ok = TRUE; ulint i; for (i = 0; i < hash_get_n_cells(table); i++) { @@ -254,13 +265,21 @@ ha_validate( node = cell->node; while (node) { - ut_a(hash_calc_hash(node->fold, table) == i); + if (hash_calc_hash(node->fold, table) != i) { + ut_print_timestamp(stderr); + fprintf(stderr, +"InnoDB: Error: hash table node fold value %lu does not\n" +"InnoDB: match with the cell number %lu.\n", + node->fold, i); + + ok = FALSE; + } node = node->next; } } - return(TRUE); + return(ok); } /***************************************************************** @@ -269,16 +288,22 @@ Prints info of a hash table. */ void ha_print_info( /*==========*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end,/* in: buffer end */ hash_table_t* table) /* in: hash table */ { hash_cell_t* cell; - ha_node_t* node; +/* ha_node_t* node; */ ulint nodes = 0; ulint cells = 0; ulint len = 0; ulint max_len = 0; ulint i; + if (buf_end - buf < 200) { + return; + } + for (i = 0; i < hash_get_n_cells(table); i++) { cell = hash_get_nth_cell(table, i); @@ -286,7 +311,7 @@ ha_print_info( if (cell->node) { cells++; - +/* len = 0; node = cell->node; @@ -306,12 +331,10 @@ ha_print_info( if (len > max_len) { max_len = len; } +*/ } } - printf("Hash table size %lu, used cells %lu, nodes %lu\n", - hash_get_n_cells(table), cells, nodes); - printf("max chain length %lu\n", max_len); - - ut_a(ha_validate(table)); + buf += sprintf(buf, "Hash table size %lu, used cells %lu\n", + hash_get_n_cells(table), cells); } diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index a6355ce7ca5..b7d691485cc 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -687,21 +687,21 @@ ibuf_bitmap_get_map_page( /**************************************************************************** Sets the free bits of the page in the ibuf bitmap. This is done in a separate mini-transaction, hence this operation does not restrict further work to only -ibuf bitmap operations, which would result if the latch to the bitmap pag +ibuf bitmap operations, which would result if the latch to the bitmap page were kept. */ UNIV_INLINE void ibuf_set_free_bits_low( /*===================*/ ulint type, /* in: index type */ - page_t* page, /* in: index page; free bit is reset if the index is - a non-clustered non-unique, and page level is 0 */ + page_t* page, /* in: index page; free bit is set if the index is + non-clustered and page level is 0 */ ulint val, /* in: value to set: < 4 */ mtr_t* mtr) /* in: mtr */ { page_t* bitmap_page; - if (type & (DICT_CLUSTERED | DICT_UNIQUE)) { + if (type & DICT_CLUSTERED) { return; } @@ -735,8 +735,8 @@ void ibuf_set_free_bits( /*===============*/ ulint type, /* in: index type */ - page_t* page, /* in: index page; free bit is reset if the index is - a non-clustered non-unique, and page level is 0 */ + page_t* page, /* in: index page; free bit is set if the index is + non-clustered and page level is 0 */ ulint val, /* in: value to set: < 4 */ ulint max_val)/* in: ULINT_UNDEFINED or a maximum value which the bits must have before setting; this is for @@ -745,7 +745,7 @@ ibuf_set_free_bits( mtr_t mtr; page_t* bitmap_page; - if (type & (DICT_CLUSTERED | DICT_UNIQUE)) { + if (type & DICT_CLUSTERED) { return; } @@ -2026,7 +2026,7 @@ ibuf_insert_low( ulint n_stored; ulint bits; - ut_a(!(index->type & (DICT_UNIQUE | DICT_CLUSTERED))); + ut_a(!(index->type & DICT_CLUSTERED)); ut_ad(dtuple_check_typed(entry)); do_merge = FALSE; @@ -2256,10 +2256,7 @@ ibuf_insert( ut_ad(dtuple_check_typed(entry)); - if (index->type & DICT_CLUSTERED || index->type & DICT_UNIQUE) { - - return(FALSE); - } + ut_a(!(index->type & DICT_CLUSTERED)); if (rec_get_converted_size(entry) >= page_get_free_space_of_empty() / 2) { @@ -2304,6 +2301,7 @@ ibuf_insert_to_index_page( rec_t* rec; page_t* bitmap_page; ulint old_bits; + char errbuf[1000]; ut_ad(ibuf_inside()); ut_ad(dtuple_check_typed(entry)); @@ -2326,11 +2324,24 @@ ibuf_insert_to_index_page( /* This time the record must fit */ if (!page_cur_tuple_insert(&page_cur, entry, mtr)) { - printf( - "Ibuf insert fails; page free %lu, dtuple size %lu\n", + + ut_print_timestamp(stderr); + + fprintf(stderr, +"InnoDB: Error: Insert buffer insert fails; page free %lu, dtuple size %lu\n", page_get_max_insert_size(page, 1), rec_get_converted_size(entry)); + dtuple_sprintf(errbuf, 900, entry); + + fprintf(stderr, +"InnoDB: Cannot insert index record %s\n", errbuf); + + fprintf(stderr, +"InnoDB: The table where where this index record belongs\n" +"InnoDB: is now probably corrupt. Please run CHECK TABLE on\n" +"InnoDB: that table.\n"); + bitmap_page = ibuf_bitmap_get_map_page( buf_frame_get_space_id(page), buf_frame_get_page_no(page), @@ -2341,9 +2352,11 @@ ibuf_insert_to_index_page( buf_frame_get_page_no(page), IBUF_BITMAP_FREE, mtr); - printf("Bitmap bits %lu\n", old_bits); - - ut_error; + fprintf(stderr, "Bitmap bits %lu\n", old_bits); + + fprintf(stderr, +"InnoDB: Send a detailed bug report to mysql@lists.mysql.com!\n"); + } } } @@ -2692,22 +2705,30 @@ ibuf_validate_low(void) Prints info of ibuf. */ void -ibuf_print(void) -/*============*/ +ibuf_print( +/*=======*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end)/* in: buffer end */ { ibuf_data_t* data; #ifdef UNIV_IBUF_DEBUG ulint i; #endif + if (buf_end - buf < 500) { + return; + } + mutex_enter(&ibuf_mutex); data = UT_LIST_GET_FIRST(ibuf->data_list); while (data) { - printf( + buf += sprintf(buf, "Ibuf for space %lu: size %lu, free list len %lu, seg size %lu,\n", data->space, data->size, data->free_list_len, data->seg_size); - printf("%lu inserts, %lu merged recs, %lu merges\n", + + buf += sprintf(buf, + "%lu inserts, %lu merged recs, %lu merges\n", data->n_inserts, data->n_merged_recs, data->n_merges); #ifdef UNIV_IBUF_DEBUG for (i = 0; i < IBUF_COUNT_N_PAGES; i++) { diff --git a/innobase/include/btr0btr.h b/innobase/include/btr0btr.h index d22f9d79c1c..bf433c0c264 100644 --- a/innobase/include/btr0btr.h +++ b/innobase/include/btr0btr.h @@ -204,16 +204,6 @@ btr_page_reorganize( page_t* page, /* in: page to be reorganized */ mtr_t* mtr); /* in: mtr */ /***************************************************************** -Reorganizes an index page. */ - -void -btr_page_reorganize_low( -/*====================*/ - ibool low, /* in: TRUE if locks should not be updated, i.e., - there cannot exist locks on the page */ - page_t* page, /* in: page to be reorganized */ - mtr_t* mtr); /* in: mtr */ -/***************************************************************** Decides if the page should be split at the convergence point of inserts converging to left. */ diff --git a/innobase/include/btr0cur.h b/innobase/include/btr0cur.h index bce1f0685cc..b01cbd9a875 100644 --- a/innobase/include/btr0cur.h +++ b/innobase/include/btr0cur.h @@ -709,6 +709,9 @@ allowed to free an inherited external field. */ #define BTR_EXTERN_INHERITED_FLAG 64 extern ulint btr_cur_n_non_sea; +extern ulint btr_cur_n_sea; +extern ulint btr_cur_n_non_sea_old; +extern ulint btr_cur_n_sea_old; #ifndef UNIV_NONINL #include "btr0cur.ic" diff --git a/innobase/include/btr0sea.h b/innobase/include/btr0sea.h index fdf5cf375a3..14feca5d5c5 100644 --- a/innobase/include/btr0sea.h +++ b/innobase/include/btr0sea.h @@ -176,6 +176,7 @@ btr_search_validate(void); /* The search info struct in an index */ struct btr_search_struct{ + ulint magic_n; /* magic number */ /* The following 4 fields are currently not used: */ rec_t* last_search; /* pointer to the lower limit record of the previous search; NULL if not known */ @@ -220,6 +221,8 @@ struct btr_search_struct{ ulint n_searches; /* number of searches */ }; +#define BTR_SEARCH_MAGIC_N 1112765 + /* The hash index system */ typedef struct btr_search_sys_struct btr_search_sys_t; diff --git a/innobase/include/buf0buf.h b/innobase/include/buf0buf.h index 5ddbf39335a..b80ed96f54c 100644 --- a/innobase/include/buf0buf.h +++ b/innobase/include/buf0buf.h @@ -219,6 +219,16 @@ buf_page_create( a page */ mtr_t* mtr); /* in: mini-transaction handle */ /************************************************************************ +Inits a page to the buffer buf_pool, for use in ibbackup --restore. */ + +void +buf_page_init_for_backup_restore( +/*=============================*/ + ulint space, /* in: space id */ + ulint offset, /* in: offset of the page within space + in units of a page */ + buf_block_t* block); /* in: block to init */ +/************************************************************************ Decrements the bufferfix count of a buffer control block and releases a latch, if specified. */ UNIV_INLINE @@ -438,7 +448,7 @@ Prints info of the buffer pool data structure. */ void buf_print(void); -/*===========*/ +/*============*/ /************************************************************************* Returns the number of pending buf pool ios. */ @@ -449,8 +459,10 @@ buf_get_n_pending_ios(void); Prints info of the buffer i/o. */ void -buf_print_io(void); -/*==============*/ +buf_print_io( +/*=========*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end);/* in: buffer end */ /************************************************************************* Checks that all file pages in the buffer are in a replaceable state. */ @@ -605,6 +617,7 @@ struct buf_block_struct{ /* 1. General fields */ + ulint magic_n; /* magic number to check */ ulint state; /* state of the control block: BUF_BLOCK_NOT_USED, ... */ byte* frame; /* pointer to buffer frame which @@ -729,6 +742,8 @@ struct buf_block_struct{ frees a page in buffer pool */ }; +#define BUF_BLOCK_MAGIC_N 41526563 + /* The buffer pool structure. NOTE! The definition appears here only for other modules of this directory (buf) to see it. Do not use from outside! */ diff --git a/innobase/include/buf0buf.ic b/innobase/include/buf0buf.ic index 52bee0eb282..e5a2c480922 100644 --- a/innobase/include/buf0buf.ic +++ b/innobase/include/buf0buf.ic @@ -209,7 +209,7 @@ buf_block_align( ut_ad((ulint)ptr >= (ulint)frame_zero); - block = buf_pool_get_nth_block(buf_pool, (ptr - frame_zero) + block = buf_pool_get_nth_block(buf_pool, ((ulint)(ptr - frame_zero)) >> UNIV_PAGE_SIZE_SHIFT); ut_a(block >= buf_pool->blocks); ut_a(block < buf_pool->blocks + buf_pool->max_size); @@ -236,7 +236,7 @@ buf_block_align_low( ut_ad((ulint)ptr >= (ulint)frame_zero); - block = buf_pool_get_nth_block(buf_pool, (ptr - frame_zero) + block = buf_pool_get_nth_block(buf_pool, ((ulint)(ptr - frame_zero)) >> UNIV_PAGE_SIZE_SHIFT); ut_a(block >= buf_pool->blocks); ut_a(block < buf_pool->blocks + buf_pool->max_size); diff --git a/innobase/include/buf0rea.h b/innobase/include/buf0rea.h index 1efe67369ab..aed965a6b21 100644 --- a/innobase/include/buf0rea.h +++ b/innobase/include/buf0rea.h @@ -89,7 +89,7 @@ buf_read_recv_pages( /* The size in pages of the area which the read-ahead algorithms read if invoked */ -#define BUF_READ_AHEAD_AREA ut_min(32, buf_pool->curr_size / 16) +#define BUF_READ_AHEAD_AREA ut_min(64, ut_2_power_up(buf_pool->curr_size / 32)) /* Modes used in read-ahead */ #define BUF_READ_IBUF_PAGES_ONLY 131 diff --git a/innobase/include/data0data.h b/innobase/include/data0data.h index c19d7ea5552..e0fb06e5018 100644 --- a/innobase/include/data0data.h +++ b/innobase/include/data0data.h @@ -123,7 +123,7 @@ dfield_datas_are_binary_equal( dfield_t* field2);/* in: field */ /************************************************************************* Tests if dfield data length and content is equal to the given. */ -UNIV_INLINE + ibool dfield_data_is_binary_equal( /*========================*/ @@ -279,6 +279,14 @@ dtuple_check_typed( /* out: TRUE if ok */ dtuple_t* tuple); /* in: tuple */ /************************************************************** +Checks that a data tuple is typed. */ + +ibool +dtuple_check_typed_no_assert( +/*=========================*/ + /* out: TRUE if ok */ + dtuple_t* tuple); /* in: tuple */ +/************************************************************** Validates the consistency of a tuple which must be complete, i.e, all fields must have been set. */ diff --git a/innobase/include/data0data.ic b/innobase/include/data0data.ic index 0750a3894d1..d356664df21 100644 --- a/innobase/include/data0data.ic +++ b/innobase/include/data0data.ic @@ -154,30 +154,6 @@ dfield_datas_are_binary_equal( } /************************************************************************* -Tests if dfield data length and content is equal to the given. */ -UNIV_INLINE -ibool -dfield_data_is_binary_equal( -/*========================*/ - /* out: TRUE if equal */ - dfield_t* field, /* in: field */ - ulint len, /* in: data length or UNIV_SQL_NULL */ - byte* data) /* in: data */ -{ - if (len != field->len) { - - return(FALSE); - } - - if (len != UNIV_SQL_NULL && 0 != ut_memcmp(field->data, data, len)) { - - return(FALSE); - } - - return(TRUE); -} - -/************************************************************************* Gets info bits in a data tuple. */ UNIV_INLINE ulint diff --git a/innobase/include/ha0ha.h b/innobase/include/ha0ha.h index aeed7c32eff..945b1198a41 100644 --- a/innobase/include/ha0ha.h +++ b/innobase/include/ha0ha.h @@ -127,6 +127,8 @@ Prints info of a hash table. */ void ha_print_info( /*==========*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end,/* in: buffer end */ hash_table_t* table); /* in: hash table */ diff --git a/innobase/include/ibuf0ibuf.h b/innobase/include/ibuf0ibuf.h index fac28461be4..a290e90e4db 100644 --- a/innobase/include/ibuf0ibuf.h +++ b/innobase/include/ibuf0ibuf.h @@ -269,8 +269,10 @@ ibuf_count_get( Prints info of ibuf. */ void -ibuf_print(void); -/*============*/ +ibuf_print( +/*=======*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end);/* in: buffer end */ #define IBUF_HEADER_PAGE_NO FSP_IBUF_HEADER_PAGE_NO #define IBUF_TREE_ROOT_PAGE_NO FSP_IBUF_TREE_ROOT_PAGE_NO diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h index 5a15b78b869..80afba97416 100644 --- a/innobase/include/lock0lock.h +++ b/innobase/include/lock0lock.h @@ -460,6 +460,8 @@ Prints info of a table lock. */ void lock_table_print( /*=============*/ + char* buf, /* in/out: buffer where to print, must be at least + 500 bytes */ lock_t* lock); /* in: table type lock */ /************************************************************************* Prints info of a record lock. */ @@ -467,13 +469,17 @@ Prints info of a record lock. */ void lock_rec_print( /*===========*/ + char* buf, /* in/out: buffer where to print, must be at least + 500 bytes */ lock_t* lock); /* in: record type lock */ /************************************************************************* Prints info of locks for all transactions. */ void -lock_print_info(void); -/*=================*/ +lock_print_info( +/*============*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end);/* in: buffer end */ /************************************************************************* Validates the lock queue on a table. */ diff --git a/innobase/include/log0log.h b/innobase/include/log0log.h index eeb4f2e45f1..5d848b85658 100644 --- a/innobase/include/log0log.h +++ b/innobase/include/log0log.h @@ -157,6 +157,14 @@ log_io_complete( /*============*/ log_group_t* group); /* in: log group */ /********************************************************** +Flushes the log files to the disk, using, for example, the Unix fsync. +This function does the flush even if the user has set +srv_flush_log_at_trx_commit = FALSE. */ + +void +log_flush_to_disk(void); +/*===================*/ +/********************************************************** This function is called, e.g., when a transaction wants to commit. It checks that the log has been flushed to disk up to the last log entry written by the transaction. If there is a flush running, it waits and checks if the flush @@ -260,7 +268,9 @@ log_reset_first_header_and_checkpoint( /*==================================*/ byte* hdr_buf,/* in: buffer which will be written to the start of the first log file */ - dulint lsn); /* in: lsn of the start of the first log file */ + dulint start); /* in: lsn of the start of the first log file; + we pretend that there is a checkpoint at + start + LOG_BLOCK_HDR_SIZE */ /************************************************************************ Starts an archiving operation. */ @@ -463,6 +473,15 @@ log_block_init( byte* log_block, /* in: pointer to the log buffer */ dulint lsn); /* in: lsn within the log block */ /**************************************************************** +Initializes a log block in the log buffer in the old, < 3.23.52 format, where +there was no checksum yet. */ +UNIV_INLINE +void +log_block_init_in_old_format( +/*=========================*/ + byte* log_block, /* in: pointer to the log buffer */ + dulint lsn); /* in: lsn within the log block */ +/**************************************************************** Converts a lsn to a log block number. */ UNIV_INLINE ulint @@ -474,8 +493,10 @@ log_block_convert_lsn_to_no( Prints info of the log. */ void -log_print(void); -/*===========*/ +log_print( +/*======*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end);/* in: buffer end */ extern log_t* log_sys; @@ -523,7 +544,10 @@ extern log_t* log_sys; bytes */ /* Offsets of a log block trailer from the end of the block */ -#define LOG_BLOCK_TRL_NO 4 /* log block number */ +#define LOG_BLOCK_TRL_CHECKSUM 4 /* 1 byte checksum of the log block + contents */ +#define LOG_BLOCK_TRL_NO 3 /* 3 lowest bytes of the log block + number */ #define LOG_BLOCK_TRL_SIZE 4 /* trailer size in bytes */ /* Offsets for a checkpoint field */ @@ -558,11 +582,22 @@ extern log_t* log_sys; #define LOG_GROUP_ID 0 /* log group number */ #define LOG_FILE_START_LSN 4 /* lsn of the start of data in this log file */ -#define LOG_FILE_NO 12 /* 4-byte archived log file number */ +#define LOG_FILE_NO 12 /* 4-byte archived log file number; + this field is only defined in an + archived log file */ +#define LOG_FILE_WAS_CREATED_BY_HOT_BACKUP 16 + /* a 32-byte field which contains + the string 'ibbackup' and the + creation time if the log file was + created by ibbackup --restore; + when mysqld is first time started + on the restored database, it can + print helpful info for the user */ #define LOG_FILE_ARCH_COMPLETED OS_FILE_LOG_BLOCK_SIZE /* this 4-byte field is TRUE when the writing of an archived log file - has been completed */ + has been completed; this field is + only defined in an archived log file */ #define LOG_FILE_END_LSN (OS_FILE_LOG_BLOCK_SIZE + 4) /* lsn where the archived log file at least extends: actually the @@ -572,7 +607,14 @@ extern log_t* log_sys; is defined only when an archived log file has been completely written */ #define LOG_CHECKPOINT_1 OS_FILE_LOG_BLOCK_SIZE + /* first checkpoint field in the log + header; we write alternately to the + checkpoint fields when we make new + checkpoints; this field is only defined + in the first log file of a log group */ #define LOG_CHECKPOINT_2 (3 * OS_FILE_LOG_BLOCK_SIZE) + /* second checkpoint field in the log + header */ #define LOG_FILE_HDR_SIZE (4 * OS_FILE_LOG_BLOCK_SIZE) #define LOG_GROUP_OK 301 @@ -678,7 +720,7 @@ struct log_struct{ write i/o has been completed for all log groups */ dulint flush_lsn; /* end lsn for the current flush */ - ulint flush_end_offset;/* the data in buffer ha been flushed + ulint flush_end_offset;/* the data in buffer has been flushed up to this offset when the current flush ends: this field will then be copied to buf_next_to_write */ diff --git a/innobase/include/log0log.ic b/innobase/include/log0log.ic index e5c313d129b..36e65239374 100644 --- a/innobase/include/log0log.ic +++ b/innobase/include/log0log.ic @@ -179,7 +179,7 @@ log_block_get_trl_no( trailer */ byte* log_block) /* in: log block */ { - return(mach_read_from_4(log_block + OS_FILE_LOG_BLOCK_SIZE + return(mach_read_from_3(log_block + OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_NO)); } @@ -192,8 +192,8 @@ log_block_set_trl_no( byte* log_block, /* in: log block */ ulint n) /* in: log block number */ { - mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_NO, - n); + mach_write_to_3(log_block + OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_NO, + n & 0xFFFFFF); } /**************************************************************** @@ -237,6 +237,29 @@ log_block_init( log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE); log_block_set_first_rec_group(log_block, 0); } + +/**************************************************************** +Initializes a log block in the log buffer in the old format, where there +was no checksum yet. */ +UNIV_INLINE +void +log_block_init_in_old_format( +/*=========================*/ + byte* log_block, /* in: pointer to the log buffer */ + dulint lsn) /* in: lsn within the log block */ +{ + ulint no; + + ut_ad(mutex_own(&(log_sys->mutex))); + + no = log_block_convert_lsn_to_no(lsn); + + log_block_set_hdr_no(log_block, no); + mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE + - LOG_BLOCK_TRL_NO - 1, no); + log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE); + log_block_set_first_rec_group(log_block, 0); +} /**************************************************************** Writes to the log the string given. The log must be released with diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index 01fa12955ff..b7911c5014a 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -16,6 +16,7 @@ Created 10/21/1995 Heikki Tuuri os_file_write */ extern ibool os_do_not_call_flush_at_each_write; extern ibool os_has_said_disk_full; +extern ibool os_aio_print_debug; #ifdef __WIN__ @@ -33,6 +34,8 @@ extern ibool os_has_said_disk_full; typedef int os_file_t; #endif +extern ulint os_innodb_umask; + /* If this flag is TRUE, then we will use the native aio of the OS (provided we compiled Innobase with it in), otherwise we will use simulated aio we build below with threads */ @@ -309,6 +312,15 @@ Wakes up simulated aio i/o-handler threads if they have something to do. */ void os_aio_simulated_wake_handler_threads(void); /*=======================================*/ +/************************************************************************** +This function can be called if one wants to post a batch of reads and +prefers an i/o-handler thread to handle them all at once later. You must +call os_aio_simulated_wake_handler_threads later to ensure the threads +are not left sleeping! */ + +void +os_aio_simulated_put_read_threads_to_sleep(void); +/*============================================*/ #ifdef WIN_ASYNC_IO /************************************************************************** @@ -391,8 +403,10 @@ os_aio_validate(void); Prints info of the aio arrays. */ void -os_aio_print(void); -/*==============*/ +os_aio_print( +/*=========*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end);/* in: buffer end */ /************************************************************************** Checks that all slots in the system have been freed, that is, there are no pending io operations. */ diff --git a/innobase/include/os0thread.h b/innobase/include/os0thread.h index 2e4b6f0f6ee..0d6fa5a8f37 100644 --- a/innobase/include/os0thread.h +++ b/innobase/include/os0thread.h @@ -12,8 +12,10 @@ Created 9/8/1995 Heikki Tuuri #include "univ.i" -/* Maximum number of threads which can be created in the program */ -#define OS_THREAD_MAX_N 1000 +/* Maximum number of threads which can be created in the program; +this is also the size of the wait slot array for MySQL threads which +can wait inside InnoDB */ +#define OS_THREAD_MAX_N 10000 /* Possible fixed priorities for threads */ #define OS_THREAD_PRIORITY_NONE 100 diff --git a/innobase/include/page0page.h b/innobase/include/page0page.h index 8e68381b868..2f77127466f 100644 --- a/innobase/include/page0page.h +++ b/innobase/include/page0page.h @@ -328,7 +328,7 @@ page_dir_calc_reserved_space( ulint n_recs); /* in: number of records */ /******************************************************************* Looks for the directory slot which owns the given record. */ -UNIV_INLINE + ulint page_dir_find_owner_slot( /*=====================*/ diff --git a/innobase/include/page0page.ic b/innobase/include/page0page.ic index f84fe5a5606..e7c0f8ee07c 100644 --- a/innobase/include/page0page.ic +++ b/innobase/include/page0page.ic @@ -479,6 +479,8 @@ page_rec_get_next( offs = rec_get_next_offs(rec); + ut_a(offs < UNIV_PAGE_SIZE); + if (offs == 0) { return(NULL); @@ -487,40 +489,6 @@ page_rec_get_next( return(page + offs); } -/******************************************************************* -Looks for the directory slot which owns the given record. */ -UNIV_INLINE -ulint -page_dir_find_owner_slot( -/*=====================*/ - /* out: the directory slot number */ - rec_t* rec) /* in: the physical record */ -{ - ulint i; - page_t* page; - page_dir_slot_t* slot; - - ut_ad(page_rec_check(rec)); - - while (rec_get_n_owned(rec) == 0) { - rec = page_rec_get_next(rec); - } - - page = buf_frame_align(rec); - - i = page_dir_get_n_slots(page) - 1; - slot = page_dir_get_nth_slot(page, i); - - while (page_dir_slot_get_rec(slot) != rec) { - ut_a(i > 0); - - i--; - slot = page_dir_get_nth_slot(page, i); - } - - return(i); -} - /**************************************************************** Sets the pointer to the next record on the page. */ UNIV_INLINE @@ -534,7 +502,7 @@ page_rec_set_next( page_t* page; ut_ad(page_rec_check(rec)); - ut_ad((next == NULL) + ut_a((next == NULL) || (buf_frame_align(rec) == buf_frame_align(next))); page = buf_frame_align(rec); @@ -573,7 +541,7 @@ page_rec_get_prev( slot_no = page_dir_find_owner_slot(rec); - ut_ad(slot_no != 0); + ut_a(slot_no != 0); slot = page_dir_get_nth_slot(page, slot_no - 1); @@ -584,7 +552,7 @@ page_rec_get_prev( rec2 = page_rec_get_next(rec2); } - ut_ad(prev_rec); + ut_a(prev_rec); return(prev_rec); } diff --git a/innobase/include/rem0rec.ic b/innobase/include/rem0rec.ic index 6b96e3056fa..aaa3c58a003 100644 --- a/innobase/include/rem0rec.ic +++ b/innobase/include/rem0rec.ic @@ -970,8 +970,6 @@ rec_fold( ut_ad(n_fields <= rec_get_n_fields(rec)); ut_ad((n_fields < rec_get_n_fields(rec)) || (n_bytes == 0)); ut_ad(n_fields + n_bytes > 0); - /* Only the page supremum and infimum records have 1 field: */ - ut_ad(rec_get_n_fields(rec) > 1); n_fields_rec = rec_get_n_fields(rec); diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index 13b3dffd874..8152c534f48 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -230,6 +230,19 @@ row_update_cascade_for_mysql( or set null operation */ dict_table_t* table); /* in: table where we do the operation */ /************************************************************************* +Locks the data dictionary exclusively for performing a table create +operation. */ + +void +row_mysql_lock_data_dictionary(void); +/*================================*/ +/************************************************************************* +Unlocks the data dictionary exclusively lock. */ + +void +row_mysql_unlock_data_dictionary(void); +/*==================================*/ +/************************************************************************* Does a table creation operation for MySQL. If the name of the created table ends to characters INNODB_MONITOR, then this also starts printing of monitor output by the master thread. */ diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index 6777a24e7db..178c7b6971f 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -357,6 +357,14 @@ srv_error_monitor_thread( /* out: a dummy parameter */ void* arg); /* in: a dummy parameter required by os_thread_create */ +/********************************************************************** +Sprintfs to a buffer the output of the InnoDB Monitor. */ + +void +srv_sprintf_innodb_monitor( +/*=======================*/ + char* buf, /* in/out: buffer which must be at least 4 kB */ + ulint len); /* in: length of the buffer */ /* Types for the threads existing in the system. Threads of types 4 - 9 diff --git a/innobase/include/sync0arr.h b/innobase/include/sync0arr.h index f0134894997..765ad33afea 100644 --- a/innobase/include/sync0arr.h +++ b/innobase/include/sync0arr.h @@ -114,6 +114,8 @@ Prints info of the wait array. */ void sync_array_print_info( /*==================*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end,/* in: buffer end */ sync_array_t* arr); /* in: wait array */ diff --git a/innobase/include/sync0sync.h b/innobase/include/sync0sync.h index 4f55709a5d7..5bfa0bc2d48 100644 --- a/innobase/include/sync0sync.h +++ b/innobase/include/sync0sync.h @@ -117,14 +117,18 @@ FUNCTION PROTOTYPES FOR DEBUGGING */ Prints wait info of the sync system. */ void -sync_print_wait_info(void); -/*======================*/ +sync_print_wait_info( +/*=================*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end); /* in: buffer end */ /*********************************************************************** Prints info of the sync system. */ void -sync_print(void); -/*============*/ +sync_print( +/*=======*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end); /* in: buffer end */ /********************************************************************** Checks that the mutex has been initialized. */ diff --git a/innobase/include/trx0roll.h b/innobase/include/trx0roll.h index c456768e820..820af4cd014 100644 --- a/innobase/include/trx0roll.h +++ b/innobase/include/trx0roll.h @@ -102,11 +102,13 @@ trx_rollback( calling function can start running a new query thread */ /*********************************************************************** -Rollback uncommitted transactions which have no user session. */ +Rollback or clean up transactions which have no user session. If the +transaction already was committed, then we clean up a possible insert +undo log. If the transaction was not yet committed, then we roll it back. */ void -trx_rollback_all_without_sess(void); -/*===============================*/ +trx_rollback_or_clean_all_without_sess(void); +/*========================================*/ /******************************************************************** Finishes a transaction rollback. */ diff --git a/innobase/include/trx0sys.h b/innobase/include/trx0sys.h index 60d5adb72d1..b08df7f6901 100644 --- a/innobase/include/trx0sys.h +++ b/innobase/include/trx0sys.h @@ -24,6 +24,14 @@ Created 3/26/1996 Heikki Tuuri #include "fsp0fsp.h" #include "read0types.h" +/* In a MySQL replication slave, in crash recovery we store the master log +file name and position here. We have successfully got the updates to InnoDB +up to this position. If .._pos is -1, it means no crash recovery was needed, +or there was no master log position info inside InnoDB. */ + +extern char trx_sys_mysql_master_log_name[]; +extern ib_longlong trx_sys_mysql_master_log_pos; + /* The transaction system */ extern trx_sys_t* trx_sys; @@ -229,13 +237,18 @@ trx_in_trx_list( trx_t* in_trx);/* in: trx */ /********************************************************************* Updates the offset information about the end of the MySQL binlog entry -which corresponds to the transaction just being committed. */ +which corresponds to the transaction just being committed. In a MySQL +replication slave updates the latest master binlog position up to which +replication has proceeded. */ void trx_sys_update_mysql_binlog_offset( /*===============================*/ - trx_t* trx, /* in: transaction being committed */ - mtr_t* mtr); /* in: mtr */ + char* file_name,/* in: MySQL log file name */ + ib_longlong offset, /* in: position in that log file */ + ulint field, /* in: offset of the MySQL log info field in + the trx sys header */ + mtr_t* mtr); /* in: mtr */ /********************************************************************* Prints to stderr the MySQL binlog offset info in the trx system header if the magic number shows it valid. */ @@ -243,15 +256,17 @@ the magic number shows it valid. */ void trx_sys_print_mysql_binlog_offset(void); /*===================================*/ +/********************************************************************* +Prints to stderr the MySQL master log offset info in the trx system header if +the magic number shows it valid. */ + +void +trx_sys_print_mysql_master_log_pos(void); +/*====================================*/ /* The automatically created system rollback segment has this id */ #define TRX_SYS_SYSTEM_RSEG_ID 0 -/* Max number of rollback segments: the number of segment specification slots -in the transaction system array; rollback segment id must fit in one byte, -therefore 256 */ -#define TRX_SYS_N_RSEGS 256 - /* Space id and page no where the trx system file copy resides */ #define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */ #define TRX_SYS_PAGE_NO FSP_TRX_SYS_PAGE_NO @@ -277,22 +292,29 @@ therefore 256 */ segment specification slots */ /*-------------------------------------------------------------*/ -#define TRX_SYS_MYSQL_LOG_NAME_LEN 32 +/* Max number of rollback segments: the number of segment specification slots +in the transaction system array; rollback segment id must fit in one byte, +therefore 256; each slot is currently 8 bytes in size */ +#define TRX_SYS_N_RSEGS 256 + +#define TRX_SYS_MYSQL_LOG_NAME_LEN 512 #define TRX_SYS_MYSQL_LOG_MAGIC_N 873422344 +/* The offset of the MySQL replication info on the trx system header page; +this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */ +#define TRX_SYS_MYSQL_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 2000) + /* The offset of the MySQL binlog offset info on the trx system header page */ -#define TRX_SYS_MYSQL_LOG_INFO (UNIV_PAGE_SIZE - 300) +#define TRX_SYS_MYSQL_LOG_INFO (UNIV_PAGE_SIZE - 1000) #define TRX_SYS_MYSQL_LOG_MAGIC_N_FLD 0 /* magic number which shows if we have valid data in the MySQL binlog info; the value is ..._MAGIC_N if yes */ -#define TRX_SYS_MYSQL_LOG_NAME 4 /* MySQL log file name */ -#define TRX_SYS_MYSQL_LOG_OFFSET_HIGH (4 + TRX_SYS_MYSQL_LOG_NAME_LEN) - /* high 4 bytes of the offset +#define TRX_SYS_MYSQL_LOG_OFFSET_HIGH 4 /* high 4 bytes of the offset within that file */ -#define TRX_SYS_MYSQL_LOG_OFFSET_LOW (8 + TRX_SYS_MYSQL_LOG_NAME_LEN) - /* low 4 bytes of the offset +#define TRX_SYS_MYSQL_LOG_OFFSET_LOW 8 /* low 4 bytes of the offset within that file */ +#define TRX_SYS_MYSQL_LOG_NAME 12 /* MySQL log file name */ /* The offset of the doublewrite buffer header on the trx system header page */ #define TRX_SYS_DOUBLEWRITE (UNIV_PAGE_SIZE - 200) diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h index 261f33d3dc3..83789966514 100644 --- a/innobase/include/trx0trx.h +++ b/innobase/include/trx0trx.h @@ -124,6 +124,15 @@ void trx_commit_off_kernel( /*==================*/ trx_t* trx); /* in: transaction */ +/******************************************************************** +Cleans up a transaction at database startup. The cleanup is needed if +the transaction already got to the middle of a commit when the database +crashed, andf we cannot roll it back. */ + +void +trx_cleanup_at_db_startup( +/*======================*/ + trx_t* trx); /* in: transaction */ /************************************************************************** Does the transaction commit for MySQL. */ @@ -252,7 +261,9 @@ own the kernel mutex. */ void trx_print( /*======*/ - trx_t* trx); /* in: transaction */ + char* buf, /* in/out: buffer where to print, must be at least + 500 bytes */ + trx_t* trx); /* in: transaction */ /* Signal to a transaction */ @@ -322,13 +333,24 @@ struct trx_struct{ void* mysql_thd; /* MySQL thread handle corresponding to this trx, or NULL */ char* mysql_log_file_name; - /* If MySQL binlog is used, this field + /* if MySQL binlog is used, this field contains a pointer to the latest file name; this is NULL if binlog is not used */ - ib_longlong mysql_log_offset;/* If MySQL binlog is used, this field + ib_longlong mysql_log_offset;/* if MySQL binlog is used, this field contains the end offset of the binlog entry */ + char* mysql_master_log_file_name; + /* if the database server is a MySQL + replication slave, we have here the + master binlog name up to which + replication has processed; otherwise + this is a pointer to a null character */ + ib_longlong mysql_master_log_pos; + /* if the database server is a MySQL + replication slave, this is the + position in the log file up to which + replication has processed */ os_thread_id_t mysql_thread_id;/* id of the MySQL thread associated with this transaction object */ /*------------------------------*/ diff --git a/innobase/include/univ.i b/innobase/include/univ.i index 160a435319a..c852741d5ac 100644 --- a/innobase/include/univ.i +++ b/innobase/include/univ.i @@ -9,41 +9,26 @@ Created 1/20/1994 Heikki Tuuri #ifndef univ_i #define univ_i -#if (defined(_WIN32) || defined(_WIN64)) && !defined(MYSQL_SERVER) +#if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) && !defined(MYSQL_SERVER) #define __WIN__ #include <windows.h> -/* When compiling for Itanium IA64, undefine the flag below to prevent use -of 32-bit assembler */ - -#ifndef WIN64 +#if !defined(WIN64) && !defined(_WIN64) #define UNIV_CAN_USE_X86_ASSEMBLER #endif -/* If you want to check for errors with compiler level -W4, -comment out the above include of windows.h and let the following defines -be defined: -#define HANDLE void* -#define CRITICAL_SECTION ulint -*/ - #ifdef _NT_ #define __NT__ #endif #else -/* The Unix version */ - -/* Most C compilers other than gcc do not know 'extern inline' */ -#if !defined(__GNUC__) && !defined(__WIN__) -#undef UNIV_MUST_NOT_INLINE -#define UNIV_MUST_NOT_INLINE -#endif +/* The defines used with MySQL */ /* Include two header files from MySQL to make the Unix flavor used -in compiling more Posix-compatible. We assume that 'innobase' is a -subdirectory of 'mysql'. */ +in compiling more Posix-compatible. These headers also define __WIN__ +if we are compiling on Windows. */ + #include <my_global.h> #include <my_pthread.h> @@ -60,6 +45,20 @@ subdirectory of 'mysql'. */ #include <sched.h> #endif +/* When compiling for Itanium IA64, undefine the flag below to prevent use +of the 32-bit x86 assembler in mutex operations. */ + +#if defined(__WIN__) && !defined(WIN64) && !defined(_WIN64) +#define UNIV_CAN_USE_X86_ASSEMBLER +#endif + +/* We only try to do explicit inlining of functions with gcc and +Microsoft Visual C++ */ + +#if !defined(__GNUC__) && !defined(__WIN__) +#define UNIV_MUST_NOT_INLINE +#endif + #ifdef HAVE_PREAD #define HAVE_PWRITE #endif diff --git a/innobase/include/ut0ut.h b/innobase/include/ut0ut.h index 338460d7de9..408788016c1 100644 --- a/innobase/include/ut0ut.h +++ b/innobase/include/ut0ut.h @@ -114,7 +114,7 @@ ut_2_exp( ulint n); /* in: number */ /***************************************************************** Calculates fast the number rounded up to the nearest power of 2. */ -UNIV_INLINE + ulint ut_2_power_up( /*==========*/ @@ -155,6 +155,13 @@ ut_print_timestamp( /*===============*/ FILE* file); /* in: file where to print */ /************************************************************** +Sprintfs a timestamp to a buffer. */ + +void +ut_sprintf_timestamp( +/*=================*/ + char* buf); /* in: buffer where to sprintf */ +/************************************************************** Returns current year, month, day. */ void diff --git a/innobase/include/ut0ut.ic b/innobase/include/ut0ut.ic index 90f25d2b382..9d7dd283f29 100644 --- a/innobase/include/ut0ut.ic +++ b/innobase/include/ut0ut.ic @@ -172,25 +172,3 @@ ut_2_exp( { return(1 << n); } - -/***************************************************************** -Calculates fast the number rounded up to the nearest power of 2. */ -UNIV_INLINE -ulint -ut_2_power_up( -/*==========*/ - /* out: first power of 2 which is >= n */ - ulint n) /* in: number != 0 */ -{ - ulint res; - - res = 1; - - ut_ad(n > 0); - - while (res < n) { - res = res * 2; - } - - return(res); -} diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index b168ba41771..7588a576a86 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -1542,6 +1542,15 @@ lock_rec_enqueue_waiting( trx = thr_get_trx(thr); + if (trx->dict_operation) { + ut_print_timestamp(stderr); + + fprintf(stderr, +" InnoDB: Error: a record lock wait happens in a dictionary operation!\n" +"InnoDB: Table name %s. Send a bug report to mysql@lists.mysql.com\n", +index->table_name); + } + /* Enqueue the lock request that will wait to be granted */ lock = lock_rec_create(type_mode | LOCK_WAIT, rec, index, trx); @@ -2915,7 +2924,7 @@ lock_table_enqueue_waiting( trx_t* trx; ut_ad(mutex_own(&kernel_mutex)); - + /* Test if there already is some other reason to suspend thread: we do not enqueue a lock request if the query thread should be stopped anyway */ @@ -2927,6 +2936,15 @@ lock_table_enqueue_waiting( } trx = thr_get_trx(thr); + + if (trx->dict_operation) { + ut_print_timestamp(stderr); + + fprintf(stderr, +" InnoDB: Error: a table lock wait happens in a dictionary operation!\n" +"InnoDB: Table name %s. Send a bug report to mysql@lists.mysql.com\n", +table->name); + } /* Enqueue the lock request that will wait to be granted */ @@ -3309,34 +3327,37 @@ Prints info of a table lock. */ void lock_table_print( /*=============*/ + char* buf, /* in/out: buffer where to print, must be at least + 500 bytes */ lock_t* lock) /* in: table type lock */ { ut_ad(mutex_own(&kernel_mutex)); ut_a(lock_get_type(lock) == LOCK_TABLE); - printf("TABLE LOCK table %s trx id %lu %lu", + buf += sprintf(buf, "TABLE LOCK table %s trx id %lu %lu", lock->un_member.tab_lock.table->name, (lock->trx)->id.high, (lock->trx)->id.low); if (lock_get_mode(lock) == LOCK_S) { - printf(" lock mode S"); + buf += sprintf(buf, " lock mode S"); } else if (lock_get_mode(lock) == LOCK_X) { - printf(" lock_mode X"); + buf += sprintf(buf, " lock_mode X"); } else if (lock_get_mode(lock) == LOCK_IS) { - printf(" lock_mode IS"); + buf += sprintf(buf, " lock_mode IS"); } else if (lock_get_mode(lock) == LOCK_IX) { - printf(" lock_mode IX"); + buf += sprintf(buf, " lock_mode IX"); } else if (lock_get_mode(lock) == LOCK_AUTO_INC) { - printf(" lock_mode AUTO-INC"); + buf += sprintf(buf, " lock_mode AUTO-INC"); } else { - printf(" unknown lock_mode %lu", lock_get_mode(lock)); + buf += sprintf(buf, + " unknown lock_mode %lu", lock_get_mode(lock)); } if (lock_get_wait(lock)) { - printf(" waiting"); + buf += sprintf(buf, " waiting"); } - printf("\n"); + buf += sprintf(buf, "\n"); } /************************************************************************* @@ -3345,6 +3366,8 @@ Prints info of a record lock. */ void lock_rec_print( /*===========*/ + char* buf, /* in/out: buffer where to print, must be at least + 500 bytes */ lock_t* lock) /* in: record type lock */ { page_t* page; @@ -3352,8 +3375,7 @@ lock_rec_print( ulint page_no; ulint i; ulint count = 0; - ulint len; - char buf[200]; + char* buf_start = buf; mtr_t mtr; ut_ad(mutex_own(&kernel_mutex)); @@ -3362,32 +3384,32 @@ lock_rec_print( space = lock->un_member.rec_lock.space; page_no = lock->un_member.rec_lock.page_no; - printf("RECORD LOCKS space id %lu page no %lu n bits %lu", + buf += sprintf(buf, "RECORD LOCKS space id %lu page no %lu n bits %lu", space, page_no, lock_rec_get_n_bits(lock)); - printf(" table %s index %s trx id %lu %lu", + buf += sprintf(buf, " table %s index %s trx id %lu %lu", lock->index->table->name, lock->index->name, (lock->trx)->id.high, (lock->trx)->id.low); if (lock_get_mode(lock) == LOCK_S) { - printf(" lock mode S"); + buf += sprintf(buf, " lock mode S"); } else if (lock_get_mode(lock) == LOCK_X) { - printf(" lock_mode X"); + buf += sprintf(buf, " lock_mode X"); } else { ut_error; } if (lock_rec_get_gap(lock)) { - printf(" gap type lock"); + buf += sprintf(buf, " gap type lock"); } if (lock_get_wait(lock)) { - printf(" waiting"); + buf += sprintf(buf, " waiting"); } mtr_start(&mtr); - printf("\n"); + buf += sprintf(buf, "\n"); /* If the page is not in the buffer pool, we cannot load it because we have the kernel mutex and ibuf operations would @@ -3406,28 +3428,28 @@ lock_rec_print( for (i = 0; i < lock_rec_get_n_bits(lock); i++) { + if (buf - buf_start > 300) { + + buf += sprintf(buf, + "Suppressing further record lock prints for this page\n"); + return; + } + if (lock_rec_get_nth_bit(lock, i)) { - printf("Record lock, heap no %lu ", i); + buf += sprintf(buf, "Record lock, heap no %lu ", i); if (page) { - len = rec_sprintf(buf, 190, + buf += rec_sprintf(buf, 120, page_find_rec_with_heap_no(page, i)); - buf[len] = '\0'; - printf("%s", buf); + *buf = '\0'; } - printf("\n"); + buf += sprintf(buf, "\n"); count++; } - - if (count >= 3) { - printf( - "3 LOCKS PRINTED FOR THIS TRX AND PAGE: SUPPRESSING FURTHER PRINTS\n"); - goto end_prints; - } } -end_prints: + mtr_commit(&mtr); } @@ -3462,8 +3484,10 @@ lock_get_n_rec_locks(void) Prints info of locks for all transactions. */ void -lock_print_info(void) -/*=================*/ +lock_print_info( +/*============*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end)/* in: buffer end */ { lock_t* lock; trx_t* trx; @@ -3476,11 +3500,15 @@ lock_print_info(void) ulint i; mtr_t mtr; - printf("Trx id counter %lu %lu\n", + if (buf_end - buf < 600) { + return; + } + + buf += sprintf(buf, "Trx id counter %lu %lu\n", ut_dulint_get_high(trx_sys->max_trx_id), ut_dulint_get_low(trx_sys->max_trx_id)); - printf( + buf += sprintf(buf, "Purge done for trx's n:o < %lu %lu undo n:o < %lu %lu\n", ut_dulint_get_high(purge_sys->purge_trx_no), ut_dulint_get_low(purge_sys->purge_trx_no), @@ -3489,7 +3517,8 @@ lock_print_info(void) lock_mutex_enter_kernel(); - printf("Total number of lock structs in row lock hash table %lu\n", + buf += sprintf(buf, + "Total number of lock structs in row lock hash table %lu\n", lock_get_n_rec_locks()); /* First print info on non-active transactions */ @@ -3497,9 +3526,15 @@ lock_print_info(void) trx = UT_LIST_GET_FIRST(trx_sys->mysql_trx_list); while (trx) { + if (buf_end - buf < 600) { + return; + } + if (trx->conc_state == TRX_NOT_STARTED) { - printf("---"); - trx_print(trx); + buf += sprintf(buf, "---"); + trx_print(buf, trx); + + buf += strlen(buf); } trx = UT_LIST_GET_NEXT(mysql_trx_list, trx); @@ -3528,12 +3563,22 @@ loop: return; } + if (buf_end - buf < 600) { + return; + } + if (nth_lock == 0) { - printf("---"); - trx_print(trx); + buf += sprintf(buf, "---"); + trx_print(buf, trx); + buf += strlen(buf); + + if (buf_end - buf < 500) { + return; + } + if (trx->read_view) { - printf( + buf += sprintf(buf, "Trx read view will not see trx with id >= %lu %lu, sees < %lu %lu\n", ut_dulint_get_high(trx->read_view->low_limit_id), ut_dulint_get_low(trx->read_view->low_limit_id), @@ -3542,16 +3587,17 @@ loop: } if (trx->que_state == TRX_QUE_LOCK_WAIT) { - printf( + buf += sprintf(buf, "------------------TRX IS WAITING FOR THE LOCK:\n"); if (lock_get_type(trx->wait_lock) == LOCK_REC) { - lock_rec_print(trx->wait_lock); + lock_rec_print(buf, trx->wait_lock); } else { - lock_table_print(trx->wait_lock); + lock_table_print(buf, trx->wait_lock); } - printf( + buf += strlen(buf); + buf += sprintf(buf, "------------------\n"); } } @@ -3580,6 +3626,10 @@ loop: goto loop; } + if (buf_end - buf < 500) { + return; + } + if (lock_get_type(lock) == LOCK_REC) { space = lock->un_member.rec_lock.space; page_no = lock->un_member.rec_lock.page_no; @@ -3600,19 +3650,21 @@ loop: goto loop; } - lock_rec_print(lock); + lock_rec_print(buf, lock); } else { ut_ad(lock_get_type(lock) == LOCK_TABLE); - lock_table_print(lock); + lock_table_print(buf, lock); } + buf += strlen(buf); + load_page_first = TRUE; nth_lock++; if (nth_lock >= 10) { - printf( + buf += sprintf(buf, "10 LOCKS PRINTED FOR THIS TRX: SUPPRESSING FURTHER PRINTS\n"); nth_trx++; diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c index 5ec1274d117..9748384183c 100644 --- a/innobase/log/log0log.c +++ b/innobase/log/log0log.c @@ -162,6 +162,8 @@ log_reserve_and_open( ulint archived_lsn_age; ulint count = 0; ulint dummy; + + ut_a(len < log->buf_size / 2); loop: mutex_enter(&(log->mutex)); @@ -663,6 +665,8 @@ log_init(void) log_sys->buf_next_to_write = 0; + log_sys->flush_lsn = ut_dulint_zero; + log_sys->written_to_some_lsn = log_sys->lsn; log_sys->written_to_all_lsn = log_sys->lsn; @@ -777,9 +781,15 @@ log_group_init( *(group->file_header_bufs + i) = ut_align( mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE), OS_FILE_LOG_BLOCK_SIZE); + + memset(*(group->file_header_bufs + i), '\0', + LOG_FILE_HDR_SIZE); + *(group->archive_file_header_bufs + i) = ut_align( mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE), OS_FILE_LOG_BLOCK_SIZE); + memset(*(group->archive_file_header_bufs + i), '\0', + LOG_FILE_HDR_SIZE); } group->archive_space_id = archive_space_id; @@ -791,6 +801,8 @@ log_group_init( mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE), OS_FILE_LOG_BLOCK_SIZE); + memset(group->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE); + UT_LIST_ADD_LAST(log_groups, log_sys->log_groups, group); ut_a(log_calc_max_ages()); @@ -839,7 +851,7 @@ log_group_check_flush_completion( { ut_ad(mutex_own(&(log_sys->mutex))); - if (!log_sys->one_flushed && (group->n_pending_writes == 0)) { + if (!log_sys->one_flushed && group->n_pending_writes == 0) { if (log_debug_writes) { printf("Log flushed first to group %lu\n", group->id); @@ -933,16 +945,20 @@ log_io_complete( return; } + ut_a(0); /* We currently use synchronous writing of the + logs and cannot end up here! */ + if (srv_unix_file_flush_method != SRV_UNIX_O_DSYNC - && srv_unix_file_flush_method != SRV_UNIX_NOSYNC) { + && srv_unix_file_flush_method != SRV_UNIX_NOSYNC + && srv_flush_log_at_trx_commit != 2) { fil_flush(group->space_id); } mutex_enter(&(log_sys->mutex)); - ut_ad(group->n_pending_writes > 0); - ut_ad(log_sys->n_pending_writes > 0); + ut_a(group->n_pending_writes > 0); + ut_a(log_sys->n_pending_writes > 0); group->n_pending_writes--; log_sys->n_pending_writes--; @@ -956,6 +972,57 @@ log_io_complete( } /********************************************************** +Flushes the log files to the disk, using, for example, the Unix fsync. +This function does the flush even if the user has set +srv_flush_log_at_trx_commit = FALSE. */ + +void +log_flush_to_disk(void) +/*===================*/ +{ + log_group_t* group; +loop: + mutex_enter(&(log_sys->mutex)); + + if (log_sys->n_pending_writes > 0) { + /* A log file write is running */ + + mutex_exit(&(log_sys->mutex)); + + /* Wait for the log file write to complete and try again */ + + os_event_wait(log_sys->no_flush_event); + + goto loop; + } + + group = UT_LIST_GET_FIRST(log_sys->log_groups); + + log_sys->n_pending_writes++; + group->n_pending_writes++; + + os_event_reset(log_sys->no_flush_event); + os_event_reset(log_sys->one_flushed_event); + + mutex_exit(&(log_sys->mutex)); + + fil_flush(group->space_id); + + mutex_enter(&(log_sys->mutex)); + + ut_a(group->n_pending_writes == 1); + ut_a(log_sys->n_pending_writes == 1); + + group->n_pending_writes--; + log_sys->n_pending_writes--; + + os_event_set(log_sys->no_flush_event); + os_event_set(log_sys->one_flushed_event); + + mutex_exit(&(log_sys->mutex)); +} + +/********************************************************** Writes a log file header to a log file space. */ static void @@ -970,7 +1037,6 @@ log_group_file_header_flush( { byte* buf; ulint dest_offset; - ibool sync; ut_ad(mutex_own(&(log_sys->mutex))); @@ -981,15 +1047,11 @@ log_group_file_header_flush( mach_write_to_4(buf + LOG_GROUP_ID, group->id); mach_write_to_8(buf + LOG_FILE_START_LSN, start_lsn); - dest_offset = nth_file * group->file_size; - - sync = FALSE; + /* Wipe over possible label of ibbackup --restore */ + memcpy(buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, " ", 4); - if (type == LOG_RECOVER) { + dest_offset = nth_file * group->file_size; - sync = TRUE; - } - if (log_debug_writes) { printf( "Writing log file header to group %lu file %lu\n", group->id, @@ -997,14 +1059,9 @@ log_group_file_header_flush( } if (log_do_write) { - if (type == LOG_FLUSH) { - log_sys->n_pending_writes++; - group->n_pending_writes++; - } - log_sys->n_log_ios++; - fil_io(OS_FILE_WRITE | OS_FILE_LOG, sync, group->space_id, + fil_io(OS_FILE_WRITE | OS_FILE_LOG, TRUE, group->space_id, dest_offset / UNIV_PAGE_SIZE, dest_offset % UNIV_PAGE_SIZE, OS_FILE_LOG_BLOCK_SIZE, @@ -1013,6 +1070,31 @@ log_group_file_header_flush( } /********************************************************** +Stores a 1-byte checksum to the trailer checksum field of a log block +before writing it to a log file. This checksum is used in recovery to +check the consistency of a log block. The checksum is simply the 8 low +bits of 1 + the sum of the bytes in the log block except the trailer bytes. */ +static +void +log_block_store_checksum( +/*=====================*/ + byte* block) /* in/out: pointer to a log block */ +{ + ulint i; + ulint sum; + + sum = 1; + + for (i = 0; i < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE; i++) { + sum += (ulint)(*(block + i)); + } + + mach_write_to_1(block + OS_FILE_LOG_BLOCK_SIZE + - LOG_BLOCK_TRL_CHECKSUM, + 0xFF & sum); +} + +/********************************************************** Writes a buffer to a log file group. */ void @@ -1032,20 +1114,13 @@ log_group_write_buf( header */ { ulint write_len; - ibool sync; ibool write_header; ulint next_offset; + ulint i; ut_ad(mutex_own(&(log_sys->mutex))); - ut_ad(len % OS_FILE_LOG_BLOCK_SIZE == 0); - ut_ad(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0); - - sync = FALSE; - - if (type == LOG_RECOVER) { - - sync = TRUE; - } + ut_a(len % OS_FILE_LOG_BLOCK_SIZE == 0); + ut_a(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0); if (new_data_offset == 0) { write_header = TRUE; @@ -1076,7 +1151,6 @@ loop: } if (log_debug_writes) { - ulint i; printf( "Writing log file segment to group %lu offset %lu len %lu\n" @@ -1100,15 +1174,17 @@ loop: } } - if (log_do_write) { - if (type == LOG_FLUSH) { - log_sys->n_pending_writes++; - group->n_pending_writes++; - } + /* Calculate the checksums for each log block and write them to + the trailer fields of the log blocks */ + + for (i = 0; i < write_len / OS_FILE_LOG_BLOCK_SIZE; i++) { + log_block_store_checksum(buf + i * OS_FILE_LOG_BLOCK_SIZE); + } + if (log_do_write) { log_sys->n_log_ios++; - fil_io(OS_FILE_WRITE | OS_FILE_LOG, sync, group->space_id, + fil_io(OS_FILE_WRITE | OS_FILE_LOG, TRUE, group->space_id, next_offset / UNIV_PAGE_SIZE, next_offset % UNIV_PAGE_SIZE, write_len, buf, group); } @@ -1126,15 +1202,15 @@ loop: /********************************************************** This function is called, e.g., when a transaction wants to commit. It checks -that the log has been flushed to disk up to the last log entry written by the -transaction. If there is a flush running, it waits and checks if the flush -flushed enough. If not, starts a new flush. */ +that the log has been written to the log file up to the last log entry written +by the transaction. If there is a flush running, it waits and checks if the +flush flushed enough. If not, starts a new flush. */ void log_flush_up_to( /*============*/ dulint lsn, /* in: log sequence number up to which the log should - be flushed, ut_dulint_max if not specified */ + be written, ut_dulint_max if not specified */ ulint wait) /* in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP, or LOG_WAIT_ALL_GROUPS */ { @@ -1144,6 +1220,7 @@ log_flush_up_to( ulint area_start; ulint area_end; ulint loop_count; + ulint unlock; if (recv_no_ibuf_operations) { /* Recovery is running and no operations on the log files are @@ -1209,6 +1286,12 @@ loop: ut_dulint_get_low(log_sys->lsn)); } + log_sys->n_pending_writes++; + + group = UT_LIST_GET_FIRST(log_sys->log_groups); + group->n_pending_writes++; /* We assume here that we have only + one log group! */ + os_event_reset(log_sys->no_flush_event); os_event_reset(log_sys->one_flushed_event); @@ -1254,6 +1337,36 @@ loop: group = UT_LIST_GET_NEXT(log_groups, group); } + mutex_exit(&(log_sys->mutex)); + + if (srv_unix_file_flush_method != SRV_UNIX_O_DSYNC + && srv_unix_file_flush_method != SRV_UNIX_NOSYNC + && srv_flush_log_at_trx_commit != 2) { + + group = UT_LIST_GET_FIRST(log_sys->log_groups); + + fil_flush(group->space_id); + } + + mutex_enter(&(log_sys->mutex)); + + group = UT_LIST_GET_FIRST(log_sys->log_groups); + + ut_a(group->n_pending_writes == 1); + ut_a(log_sys->n_pending_writes == 1); + + group->n_pending_writes--; + log_sys->n_pending_writes--; + + unlock = log_group_check_flush_completion(group); + unlock = unlock | log_sys_check_flush_completion(); + + log_flush_do_unlocks(unlock); + + mutex_exit(&(log_sys->mutex)); + + return; + do_waits: mutex_exit(&(log_sys->mutex)); @@ -1539,15 +1652,23 @@ log_reset_first_header_and_checkpoint( /*==================================*/ byte* hdr_buf,/* in: buffer which will be written to the start of the first log file */ - dulint lsn) /* in: lsn of the start of the first log file - + LOG_BLOCK_HDR_SIZE */ + dulint start) /* in: lsn of the start of the first log file; + we pretend that there is a checkpoint at + start + LOG_BLOCK_HDR_SIZE */ { ulint fold; byte* buf; - + dulint lsn; + mach_write_to_4(hdr_buf + LOG_GROUP_ID, 0); - mach_write_to_8(hdr_buf + LOG_FILE_START_LSN, lsn); + mach_write_to_8(hdr_buf + LOG_FILE_START_LSN, start); + + lsn = ut_dulint_add(start, LOG_BLOCK_HDR_SIZE); + /* Write the label of ibbackup --restore */ + sprintf(hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, "ibbackup "); + ut_sprintf_timestamp(hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP + + strlen("ibbackup ")); buf = hdr_buf + LOG_CHECKPOINT_1; mach_write_to_8(buf + LOG_CHECKPOINT_NO, ut_dulint_zero); @@ -2965,15 +3086,22 @@ log_check_log_recs( Prints info of the log. */ void -log_print(void) -/*===========*/ +log_print( +/*======*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end)/* in: buffer end */ { double time_elapsed; time_t current_time; + if (buf_end - buf < 300) { + + return; + } + mutex_enter(&(log_sys->mutex)); - printf("Log sequence number %lu %lu\n" + buf += sprintf(buf, "Log sequence number %lu %lu\n" "Log flushed up to %lu %lu\n" "Last checkpoint at %lu %lu\n", ut_dulint_get_high(log_sys->lsn), @@ -2987,7 +3115,7 @@ log_print(void) time_elapsed = difftime(current_time, log_sys->last_printout_time); - printf( + buf += sprintf(buf, "%lu pending log writes, %lu pending chkp writes\n" "%lu log i/o's done, %.2f log i/o's/second\n", log_sys->n_pending_writes, diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index c31719f7bb0..53f75c176ea 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -568,6 +568,55 @@ recv_read_cp_info_for_backup( return(TRUE); } +/********************************************************** +Checks the 1-byte checksum to the trailer checksum field of a log block. +We also accept a log block in the old format where the checksum field +contained the highest byte of the log block number. */ +static +ibool +log_block_checksum_is_ok_or_old_format( +/*===================================*/ + /* out: TRUE if ok, or if the log block may be in the + format of InnoDB version < 3.23.52 */ + byte* block) /* in: pointer to a log block */ +{ + ulint i; + ulint sum; + + sum = 1; + + for (i = 0; i < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE; i++) { + sum += (ulint)(*(block + i)); + } + +/* printf("Checksum %lu, byte %lu\n", 0xFF & sum, + mach_read_from_1(block + OS_FILE_LOG_BLOCK_SIZE + - LOG_BLOCK_TRL_CHECKSUM)); +*/ + if (mach_read_from_1(block + OS_FILE_LOG_BLOCK_SIZE + - LOG_BLOCK_TRL_CHECKSUM) + == (0xFF & sum)) { + + return(TRUE); + } + + if (((0xFF000000 & log_block_get_hdr_no(block)) >> 24) + == mach_read_from_1(block + OS_FILE_LOG_BLOCK_SIZE + - LOG_BLOCK_TRL_CHECKSUM)) { + + /* We assume the log block is in the format of + InnoDB version < 3.23.52 and the block is ok */ +/* + fprintf(stderr, +"InnoDB: Scanned old format < InnoDB-3.23.52 log block number %lu\n", + log_block_get_hdr_no(block)); +*/ + return(TRUE); + } + + return(FALSE); +} + /*********************************************************************** Scans the log segment and n_bytes_scanned is set to the length of valid log scanned. */ @@ -598,12 +647,13 @@ recv_scan_log_seg_for_backup( no = log_block_get_hdr_no(log_block); - /* fprintf(stderr, "Log block header no %lu\n", no); */ +/* fprintf(stderr, "Log block header no %lu\n", no); */ - if (no != log_block_get_trl_no(log_block) - || no != log_block_convert_lsn_to_no(*scanned_lsn)) { - -/* printf( + if ((no & 0xFFFFFF) != log_block_get_trl_no(log_block) + || no != log_block_convert_lsn_to_no(*scanned_lsn) + || !log_block_checksum_is_ok_or_old_format(log_block)) { +/* + printf( "Log block n:o %lu, trailer n:o %lu, scanned lsn n:o %lu\n", no, log_block_get_trl_no(log_block), log_block_convert_lsn_to_no(*scanned_lsn)); @@ -611,8 +661,8 @@ recv_scan_log_seg_for_backup( /* Garbage or an incompletely written log block */ log_block += OS_FILE_LOG_BLOCK_SIZE; - -/* printf( +/* + printf( "Next log block n:o %lu, trailer n:o %lu\n", log_block_get_hdr_no(log_block), log_block_get_trl_no(log_block)); @@ -629,11 +679,11 @@ recv_scan_log_seg_for_backup( /* Garbage from a log buffer flush which was made before the most recent database recovery */ - +/* printf("Scanned cp n:o %lu, block cp n:o %lu\n", *scanned_checkpoint_no, log_block_get_checkpoint_no(log_block)); - +*/ break; } @@ -1011,7 +1061,7 @@ recv_recover_page( page_lsn = page_newest_lsn; } } else { - /* In recovery from a backup we do not use the buffer + /* In recovery from a backup we do not really use the buffer pool */ page_newest_lsn = ut_dulint_zero; @@ -1361,6 +1411,14 @@ recv_apply_log_recs_for_backup( nth_page_in_file >> (32 - UNIV_PAGE_SIZE_SHIFT), UNIV_PAGE_SIZE); + /* We simulate a page read made by the buffer pool, + to make sure recovery works ok. We must init the + block corresponding to buf_pool->frame_zero + (== page) */ + + buf_page_init_for_backup_restore(0, i, + buf_block_align(page)); + recv_recover_page(TRUE, FALSE, page, 0, i); buf_flush_init_for_writing(page, @@ -2037,8 +2095,33 @@ recv_scan_log_recs( /* fprintf(stderr, "Log block header no %lu\n", no); */ - if (no != log_block_get_trl_no(log_block) - || no != log_block_convert_lsn_to_no(scanned_lsn)) { + if ((no & 0xFFFFFF) != log_block_get_trl_no(log_block) + || no != log_block_convert_lsn_to_no(scanned_lsn) + || !log_block_checksum_is_ok_or_old_format(log_block)) { + + if ((no & 0xFFFFFF) == log_block_get_trl_no(log_block) + && no == log_block_convert_lsn_to_no(scanned_lsn) + && !log_block_checksum_is_ok_or_old_format( + log_block)) { + fprintf(stderr, +"InnoDB: Log block no %lu at lsn %lu %lu has\n" +"InnoDB: ok header and trailer, but checksum field contains %lu\n", + no, ut_dulint_get_high(scanned_lsn), + ut_dulint_get_low(scanned_lsn), + mach_read_from_1(log_block + + OS_FILE_LOG_BLOCK_SIZE + - LOG_BLOCK_TRL_CHECKSUM)); + } + + if ((no & 0xFFFFFF) + != log_block_get_trl_no(log_block)) { + fprintf(stderr, +"InnoDB: Log block with header no %lu at lsn %lu %lu has\n" +"InnoDB: trailer no %lu\n", + no, ut_dulint_get_high(scanned_lsn), + ut_dulint_get_low(scanned_lsn), + log_block_get_trl_no(log_block)); + } /* Garbage or an incompletely written log block */ @@ -2241,6 +2324,7 @@ recv_recovery_from_checkpoint_start( dulint archived_lsn; ulint capacity; byte* buf; + byte log_hdr_buf[LOG_FILE_HDR_SIZE]; ulint err; ut_ad((type != LOG_CHECKPOINT) @@ -2288,6 +2372,33 @@ recv_recovery_from_checkpoint_start( checkpoint_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO); archived_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN); + /* Read the first log file header to print a note if this is + a recovery from a restored InnoDB Hot Backup */ + + fil_io(OS_FILE_READ | OS_FILE_LOG, TRUE, max_cp_group->space_id, + 0, 0, LOG_FILE_HDR_SIZE, + log_hdr_buf, max_cp_group); + + if (0 == ut_memcmp(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, + "ibbackup", ut_strlen("ibbackup"))) { + /* This log file was created by ibbackup --restore: print + a note to the user about it */ + + fprintf(stderr, + "InnoDB: The log file was created by ibbackup --restore at\n" + "InnoDB: %s\n", log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP); + + /* Wipe over the label now */ + + ut_memcpy(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, + " ", 4); + /* Write to the log file to wipe over the label */ + fil_io(OS_FILE_WRITE | OS_FILE_LOG, TRUE, + max_cp_group->space_id, + 0, 0, OS_FILE_LOG_BLOCK_SIZE, + log_hdr_buf, max_cp_group); + } + group = UT_LIST_GET_FIRST(log_sys->log_groups); while (group) { @@ -2471,7 +2582,7 @@ recv_recovery_from_checkpoint_finish(void) /* Rollback the uncommitted transactions which have no user session */ if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO) { - trx_rollback_all_without_sess(); + trx_rollback_or_clean_all_without_sess(); } /* Apply the hashed log records to the respective file pages */ @@ -2487,6 +2598,7 @@ recv_recovery_from_checkpoint_finish(void) } if (recv_needed_recovery) { + trx_sys_print_mysql_master_log_pos(); trx_sys_print_mysql_binlog_offset(); } @@ -2614,10 +2726,9 @@ recv_reset_log_files_for_backup( /* We pretend there is a checkpoint at lsn + LOG_BLOCK_HDR_SIZE */ - log_reset_first_header_and_checkpoint(buf, - ut_dulint_add(lsn, LOG_BLOCK_HDR_SIZE)); + log_reset_first_header_and_checkpoint(buf, lsn); - log_block_init(buf + LOG_FILE_HDR_SIZE, lsn); + log_block_init_in_old_format(buf + LOG_FILE_HDR_SIZE, lsn); log_block_set_first_rec_group(buf + LOG_FILE_HDR_SIZE, LOG_BLOCK_HDR_SIZE); sprintf(name, "%sib_logfile%lu", log_dir, 0); @@ -2754,7 +2865,7 @@ ask_again: if (ut_dulint_cmp(recv_sys->parse_start_lsn, start_lsn) < 0) { fprintf(stderr, "InnoDB: Archive log file %s starts from too big a lsn\n", - name); + name); return(TRUE); } @@ -2765,7 +2876,7 @@ ask_again: fprintf(stderr, "InnoDB: Archive log file %s starts from a wrong lsn\n", - name); + name); return(TRUE); } diff --git a/innobase/mtr/mtr0log.c b/innobase/mtr/mtr0log.c index 26f5a5d1cb7..b582afc5710 100644 --- a/innobase/mtr/mtr0log.c +++ b/innobase/mtr/mtr0log.c @@ -290,7 +290,7 @@ mlog_write_string( ut_a(0); } ut_ad(ptr && mtr); - ut_ad(len < UNIV_PAGE_SIZE); + ut_a(len < UNIV_PAGE_SIZE); ut_memcpy(ptr, str, len); @@ -338,9 +338,13 @@ mlog_parse_string( offset = mach_read_from_2(ptr); ptr += 2; + ut_a(offset < UNIV_PAGE_SIZE); + len = mach_read_from_2(ptr); ptr += 2; + ut_a(len + offset < UNIV_PAGE_SIZE); + if (end_ptr < ptr + len) { return(NULL); diff --git a/innobase/mtr/mtr0mtr.c b/innobase/mtr/mtr0mtr.c index 6aa1f3509d4..e9a6e39d98f 100644 --- a/innobase/mtr/mtr0mtr.c +++ b/innobase/mtr/mtr0mtr.c @@ -315,7 +315,7 @@ mtr_log_reserve_and_write( } data_size = dyn_array_get_data_size(mlog); - + /* Open the database log for log_write_low */ mtr->start_lsn = log_reserve_and_open(data_size); diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index ee4045febde..ae3c8a45f62 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -22,6 +22,16 @@ Created 10/21/1995 Heikki Tuuri #endif +/* This specifies the file permissions InnoDB uses when it craetes files in +Unix; the value of os_innodb_umask is initialized in ha_innodb.cc to +my_umask */ + +#ifndef __WIN__ +ulint os_innodb_umask = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; +#else +ulint os_innodb_umask = 0; +#endif + /* If the following is set to TRUE, we do not call os_file_flush in every os_file_write. We can set this TRUE if the doublewrite buffer is used. */ ibool os_do_not_call_flush_at_each_write = FALSE; @@ -32,7 +42,7 @@ OS does not provide an atomic pread or pwrite, or similar */ os_mutex_t os_file_seek_mutexes[OS_FILE_N_SEEK_MUTEXES]; /* In simulated aio, merge at most this many consecutive i/os */ -#define OS_AIO_MERGE_N_CONSECUTIVE 32 +#define OS_AIO_MERGE_N_CONSECUTIVE 64 /* If this flag is TRUE, then we will use the native aio of the OS (provided we compiled Innobase with it in), otherwise we will @@ -40,6 +50,8 @@ use simulated aio we build below with threads */ ibool os_aio_use_native_aio = FALSE; +ibool os_aio_print_debug = FALSE; + /* The aio array slot structure */ typedef struct os_aio_slot_struct os_aio_slot_t; @@ -115,7 +127,12 @@ os_aio_array_t* os_aio_sync_array = NULL; ulint os_aio_n_segments = ULINT_UNDEFINED; +/* If the following is TRUE, read i/o handler threads try to +wait until a batch of new read requests have been posted */ +ibool os_aio_recommend_sleep_for_read_threads = FALSE; + ulint os_n_file_reads = 0; +ulint os_bytes_read_since_printout = 0; ulint os_n_file_writes = 0; ulint os_n_fsyncs = 0; ulint os_n_file_reads_old = 0; @@ -412,8 +429,8 @@ try_again: } if (create_mode == OS_FILE_CREATE) { - file = open(name, create_flag, S_IRUSR | S_IWUSR | S_IRGRP - | S_IWGRP | S_IROTH | S_IWOTH); + file = open(name, create_flag, S_IRUSR | S_IWUSR + | S_IRGRP | S_IWGRP); } else { file = open(name, create_flag); } @@ -548,8 +565,7 @@ try_again: } #endif if (create_mode == OS_FILE_CREATE) { - file = open(name, create_flag, S_IRUSR | S_IWUSR | S_IRGRP - | S_IWGRP | S_IROTH | S_IWOTH); + file = open(name, create_flag, os_innodb_umask); } else { file = open(name, create_flag); } @@ -673,6 +689,7 @@ os_file_set_size( ulint n_bytes; ibool ret; byte* buf; + byte* buf2; ulint i; ut_a(size == (size & 0xFFFFFFFF)); @@ -680,7 +697,10 @@ os_file_set_size( /* We use a very big 8 MB buffer in writing because Linux may be extremely slow in fsync on 1 MB writes */ - buf = ut_malloc(UNIV_PAGE_SIZE * 512); + buf2 = ut_malloc(UNIV_PAGE_SIZE * 513); + + /* Align the buffer for possible raw i/o */ + buf = ut_align(buf2, UNIV_PAGE_SIZE); /* Write buffer full of zeros */ for (i = 0; i < UNIV_PAGE_SIZE * 512; i++) { @@ -702,13 +722,13 @@ os_file_set_size( (ulint)(offset >> 32), n_bytes); if (!ret) { - ut_free(buf); + ut_free(buf2); goto error_handling; } offset += n_bytes; } - ut_free(buf); + ut_free(buf2); ret = os_file_flush(file); @@ -734,6 +754,8 @@ os_file_flush( ut_a(file); + os_n_fsyncs++; + ret = FlushFileBuffers(file); if (ret) { @@ -742,6 +764,10 @@ os_file_flush( os_file_handle_error(file, NULL); + /* It is a fatal error if a file flush does not succeed, because then + the database can get corrupt on disk */ + ut_a(0); + return(FALSE); #else int ret; @@ -764,11 +790,17 @@ os_file_flush( return(TRUE); } + ut_print_timestamp(stderr); + fprintf(stderr, - "InnoDB: Error: the OS said file flush did not succeed\n"); + " InnoDB: Error: the OS said file flush did not succeed\n"); os_file_handle_error(file, NULL); + /* It is a fatal error if a file flush does not succeed, because then + the database can get corrupt on disk */ + ut_a(0); + return(FALSE); #endif } @@ -954,6 +986,7 @@ os_file_read( ut_a((offset & 0xFFFFFFFF) == offset); os_n_file_reads++; + os_bytes_read_since_printout += n; try_again: ut_ad(file); @@ -1062,7 +1095,9 @@ os_file_write( fprintf(stderr, " InnoDB: Error: File pointer positioning to file %s failed at\n" -"InnoDB: offset %lu %lu. Operating system error number %lu.\n", +"InnoDB: offset %lu %lu. Operating system error number %lu.\n" +"InnoDB: Look from section 13.2 at http://www.innodb.com/ibman.html\n" +"InnoDB: what the error number means.\n", name, offset_high, offset, (ulint)GetLastError()); @@ -1093,8 +1128,10 @@ os_file_write( " InnoDB: Error: Write to file %s failed at offset %lu %lu.\n" "InnoDB: %lu bytes should have been written, only %lu were written.\n" "InnoDB: Operating system error number %lu.\n" +"InnoDB: Look from section 13.2 at http://www.innodb.com/ibman.html\n" +"InnoDB: what the error number means.\n" "InnoDB: Check that your OS and file system support files of this size.\n" -"InnoDB: Check also the disk is not full or a disk quota exceeded.\n", +"InnoDB: Check also that the disk is not full or a disk quota exceeded.\n", name, offset_high, offset, n, len, (ulint)GetLastError()); @@ -1120,10 +1157,12 @@ os_file_write( " InnoDB: Error: Write to file %s failed at offset %lu %lu.\n" "InnoDB: %lu bytes should have been written, only %lu were written.\n" "InnoDB: Operating system error number %lu.\n" +"InnoDB: Look from section 13.2 at http://www.innodb.com/ibman.html\n" +"InnoDB: what the error number means or use the perror program of MySQL.\n" "InnoDB: Check that your OS and file system support files of this size.\n" -"InnoDB: Check also the disk is not full or a disk quota exceeded.\n", - name, offset_high, offset, n, ret, (ulint)errno); - +"InnoDB: Check also that the disk is not full or a disk quota exceeded.\n", + name, offset_high, offset, n, (ulint)ret, + (ulint)errno); os_has_said_disk_full = TRUE; } @@ -1623,13 +1662,40 @@ os_aio_simulated_wake_handler_threads(void) /* We do not use simulated aio: do nothing */ return; - } + } + + os_aio_recommend_sleep_for_read_threads = FALSE; for (i = 0; i < os_aio_n_segments; i++) { os_aio_simulated_wake_handler_thread(i); } } +/************************************************************************** +This function can be called if one wants to post a batch of reads and +prefers an i/o-handler thread to handle them all at once later. You must +call os_aio_simulated_wake_handler_threads later to ensure the threads +are not left sleeping! */ + +void +os_aio_simulated_put_read_threads_to_sleep(void) +/*============================================*/ +{ + os_aio_array_t* array; + ulint g; + + os_aio_recommend_sleep_for_read_threads = TRUE; + + for (g = 0; g < os_aio_n_segments; g++) { + os_aio_get_array_and_local_segment(&array, g); + + if (array == os_aio_read_array) { + + os_event_reset(os_aio_segment_wait_events[g]); + } + } +} + /*********************************************************************** Requests an asynchronous i/o operation. */ @@ -1685,7 +1751,6 @@ os_aio( ut_ad(buf); ut_ad(n > 0); ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0); - ut_ad((ulint)buf % OS_FILE_LOG_BLOCK_SIZE == 0) ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0); ut_ad(os_aio_validate()); @@ -2036,18 +2101,14 @@ os_aio_simulated_handle( ulint offs; ulint lowest_offset; byte* combined_buf; + byte* combined_buf2; ibool ret; ulint n; ulint i; - + segment = os_aio_get_array_and_local_segment(&array, global_segment); restart: - /* Give other threads chance to add several i/os to the array - at once */ - - os_thread_yield(); - /* NOTE! We only access constant fields in os_aio_array. Therefore we do not have to acquire the protecting mutex yet */ @@ -2058,6 +2119,15 @@ restart: /* Look through n slots after the segment * n'th slot */ + if (array == os_aio_read_array + && os_aio_recommend_sleep_for_read_threads) { + + /* Give other threads chance to add several i/os to the array + at once. */ + + goto recommended_sleep; + } + os_mutex_enter(array->mutex); /* Check if there is a slot for which the i/o has already been @@ -2068,6 +2138,11 @@ restart: if (slot->reserved && slot->io_already_done) { + if (os_aio_print_debug) { + fprintf(stderr, +"InnoDB: i/o for slot %lu already done, returning\n", i); + } + ret = TRUE; goto slot_io_done; @@ -2149,9 +2224,11 @@ consecutive_loop: /* We can use the buffer of the i/o request */ combined_buf = slot->buf; } else { - combined_buf = ut_malloc(total_len); + combined_buf2 = ut_malloc(total_len + UNIV_PAGE_SIZE); + + ut_a(combined_buf2); - ut_a(combined_buf); + combined_buf = ut_align(combined_buf2, UNIV_PAGE_SIZE); } /* We release the array mutex for the time of the i/o: NOTE that @@ -2174,6 +2251,13 @@ consecutive_loop: srv_io_thread_op_info[global_segment] = (char*) "doing file i/o"; + if (os_aio_print_debug) { + fprintf(stderr, +"InnoDB: doing i/o of type %lu at offset %lu %lu, length %lu\n", + slot->type, slot->offset_high, slot->offset, + total_len); + } + /* Do the i/o with ordinary, synchronous i/o functions: */ if (slot->type == OS_FILE_WRITE) { ret = os_file_write(slot->name, slot->file, combined_buf, @@ -2203,7 +2287,7 @@ consecutive_loop: } if (n_consecutive > 1) { - ut_free(combined_buf); + ut_free(combined_buf2); } os_mutex_enter(array->mutex); @@ -2241,10 +2325,18 @@ wait_for_io: os_mutex_exit(array->mutex); - srv_io_thread_op_info[global_segment] = (char*) "waiting for i/o request"; +recommended_sleep: + srv_io_thread_op_info[global_segment] = + (char*)"waiting for i/o request"; os_event_wait(os_aio_segment_wait_events[global_segment]); + if (os_aio_print_debug) { + fprintf(stderr, +"InnoDB: i/o handler thread for i/o segment %lu wakes up\n", + global_segment); + } + goto restart; } @@ -2305,22 +2397,30 @@ os_aio_validate(void) Prints info of the aio arrays. */ void -os_aio_print(void) -/*==============*/ +os_aio_print( +/*=========*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end)/* in: buffer end */ { os_aio_array_t* array; os_aio_slot_t* slot; ulint n_reserved; time_t current_time; double time_elapsed; + double avg_bytes_read; ulint i; + if (buf_end - buf < 1000) { + + return; + } + for (i = 0; i < srv_n_file_io_threads; i++) { - printf("I/O thread %lu state: %s\n", i, + buf += sprintf(buf, "I/O thread %lu state: %s\n", i, srv_io_thread_op_info[i]); } - printf("Pending normal aio reads:"); + buf += sprintf(buf, "Pending normal aio reads:"); array = os_aio_read_array; loop: @@ -2347,12 +2447,12 @@ loop: ut_a(array->n_reserved == n_reserved); - printf(" %lu", n_reserved); + buf += sprintf(buf, " %lu", n_reserved); os_mutex_exit(array->mutex); if (array == os_aio_read_array) { - printf(", aio writes:"); + buf += sprintf(buf, ", aio writes:"); array = os_aio_write_array; @@ -2360,38 +2460,50 @@ loop: } if (array == os_aio_write_array) { - printf(",\n ibuf aio reads:"); + buf += sprintf(buf, ",\n ibuf aio reads:"); array = os_aio_ibuf_array; goto loop; } if (array == os_aio_ibuf_array) { - printf(", log i/o's:"); + buf += sprintf(buf, ", log i/o's:"); array = os_aio_log_array; goto loop; } if (array == os_aio_log_array) { - printf(", sync i/o's:"); + buf += sprintf(buf, ", sync i/o's:"); array = os_aio_sync_array; goto loop; } - printf("\n"); + buf += sprintf(buf, "\n"); current_time = time(NULL); time_elapsed = difftime(current_time, os_last_printout); - printf("Pending flushes (fsync) log: %lu; buffer pool: %lu\n", + buf += sprintf(buf, + "Pending flushes (fsync) log: %lu; buffer pool: %lu\n", fil_n_pending_log_flushes, fil_n_pending_tablespace_flushes); - printf("%lu OS file reads, %lu OS file writes, %lu OS fsyncs\n", + buf += sprintf(buf, + "%lu OS file reads, %lu OS file writes, %lu OS fsyncs\n", os_n_file_reads, os_n_file_writes, os_n_fsyncs); - printf("%.2f reads/s, %.2f writes/s, %.2f fsyncs/s\n", + + if (os_n_file_reads == os_n_file_reads_old) { + avg_bytes_read = 0.0; + } else { + avg_bytes_read = os_bytes_read_since_printout / + (os_n_file_reads - os_n_file_reads_old); + } + + buf += sprintf(buf, +"%.2f reads/s, %lu avg bytes/read, %.2f writes/s, %.2f fsyncs/s\n", (os_n_file_reads - os_n_file_reads_old) / time_elapsed, + (ulint)avg_bytes_read, (os_n_file_writes - os_n_file_writes_old) / time_elapsed, (os_n_fsyncs - os_n_fsyncs_old) @@ -2400,6 +2512,7 @@ loop: os_n_file_reads_old = os_n_file_reads; os_n_file_writes_old = os_n_file_writes; os_n_fsyncs_old = os_n_fsyncs; + os_bytes_read_since_printout = 0; os_last_printout = current_time; } diff --git a/innobase/os/os0sync.c b/innobase/os/os0sync.c index 2cf5160d055..c1345de0d55 100644 --- a/innobase/os/os0sync.c +++ b/innobase/os/os0sync.c @@ -435,7 +435,7 @@ os_fast_mutex_init( InitializeCriticalSection((LPCRITICAL_SECTION) fast_mutex); #else - pthread_mutex_init(fast_mutex, NULL); + pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST); #endif } diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c index 85beffbcc94..0eaf96f7e51 100644 --- a/innobase/page/page0cur.c +++ b/innobase/page/page0cur.c @@ -403,6 +403,8 @@ page_cur_insert_rec_write_log( byte* log_ptr; ulint i; + ut_a(rec_size < UNIV_PAGE_SIZE); + log_ptr = mlog_open(mtr, 30 + MLOG_BUF_MARGIN); if (log_ptr == NULL) { @@ -491,6 +493,8 @@ page_cur_insert_rec_write_log( mlog_close(mtr, log_ptr); + ut_a(rec_size - i < UNIV_PAGE_SIZE); + if (rec_size - i >= MLOG_BUF_MARGIN) { mlog_catenate_string(mtr, ins_ptr, rec_size - i); } @@ -602,6 +606,9 @@ page_cur_parse_insert_rec( /* Build the inserted record to buf */ + ut_a(mismatch_index < UNIV_PAGE_SIZE); + ut_a(end_seg_len < UNIV_PAGE_SIZE); + ut_memcpy(buf, rec_get_start(cursor_rec), mismatch_index); ut_memcpy(buf + mismatch_index, ptr, end_seg_len); @@ -938,6 +945,8 @@ page_copy_rec_list_end_to_created_page( log_data_len = dyn_array_get_data_size(&(mtr->log)) - log_data_len; + ut_a(log_data_len < 100 * UNIV_PAGE_SIZE); + mach_write_to_4(log_ptr, log_data_len); rec_set_next_offs(insert_rec, PAGE_SUPREMUM); diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c index bf8af45a00a..ed74736c8da 100644 --- a/innobase/page/page0page.c +++ b/innobase/page/page0page.c @@ -17,6 +17,7 @@ Created 2/2/1994 Heikki Tuuri #include "lock0lock.h" #include "fut0lst.h" #include "btr0sea.h" +#include "buf0buf.h" /* A cached template page used in page_create */ page_t* page_template = NULL; @@ -63,6 +64,65 @@ Assuming a page size of 8 kB, a typical index page of a secondary index contains 300 index entries, and the size of the page directory is 50 x 4 bytes = 200 bytes. */ +/******************************************************************* +Looks for the directory slot which owns the given record. */ + +ulint +page_dir_find_owner_slot( +/*=====================*/ + /* out: the directory slot number */ + rec_t* rec) /* in: the physical record */ +{ + ulint i; + ulint steps = 0; + page_t* page; + page_dir_slot_t* slot; + rec_t* original_rec = rec; + char err_buf[1000]; + + ut_ad(page_rec_check(rec)); + + while (rec_get_n_owned(rec) == 0) { + steps++; + rec = page_rec_get_next(rec); + } + + page = buf_frame_align(rec); + + i = page_dir_get_n_slots(page) - 1; + slot = page_dir_get_nth_slot(page, i); + + while (page_dir_slot_get_rec(slot) != rec) { + + if (i == 0) { + fprintf(stderr, + "InnoDB: Probable data corruption on page %lu\n", + buf_frame_get_page_no(page)); + + rec_sprintf(err_buf, 900, original_rec); + + fprintf(stderr, + "InnoDB: Original record %s\n" + "InnoDB: on that page. Steps %lu.\n", err_buf, steps); + + rec_sprintf(err_buf, 900, rec); + + fprintf(stderr, + "InnoDB: Cannot find the dir slot for record %s\n" + "InnoDB: on that page!\n", err_buf); + + buf_page_print(page); + + ut_a(0); + } + + i--; + slot = page_dir_get_nth_slot(page, i); + } + + return(i); +} + /****************************************************************** Used to check the consistency of a directory slot. */ static diff --git a/innobase/rem/rem0cmp.c b/innobase/rem/rem0cmp.c index c27af604d04..c50516dfc8b 100644 --- a/innobase/rem/rem0cmp.c +++ b/innobase/rem/rem0cmp.c @@ -104,7 +104,9 @@ cmp_types_are_equal( if ((type1->mtype == DATA_VARCHAR && type2->mtype == DATA_CHAR) || (type1->mtype == DATA_CHAR && type2->mtype == DATA_VARCHAR) || (type1->mtype == DATA_FIXBINARY && type2->mtype == DATA_BINARY) - || (type1->mtype == DATA_BINARY && type2->mtype == DATA_FIXBINARY)) { + || (type1->mtype == DATA_BINARY && type2->mtype == DATA_FIXBINARY) + || (type1->mtype == DATA_MYSQL && type2->mtype == DATA_VARMYSQL) + || (type1->mtype == DATA_VARMYSQL && type2->mtype == DATA_MYSQL)) { return(TRUE); } @@ -124,14 +126,9 @@ cmp_types_are_equal( return(FALSE); } - if (type1->mtype == DATA_MYSQL - || type1->mtype == DATA_VARMYSQL) { + if (type1->mtype == DATA_INT && type1->len != type2->len) { - if ((type1->prtype & ~DATA_NOT_NULL) - != (type2->prtype & ~DATA_NOT_NULL)) { - - return(FALSE); - } + return(FALSE); } return(TRUE); diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index ed4df08fcf3..2e6dde6db65 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -392,6 +392,19 @@ row_ins_foreign_delete_or_set_null( node = thr->run_node; + ut_a(que_node_get_type(node) == QUE_NODE_UPDATE); + + if (!node->is_delete) { + /* According to SQL-92 an UPDATE with respect to FOREIGN + KEY constraints is not semantically equivalent to a + DELETE + INSERT. Therefore we do not perform any action + here and consequently the child rows would be left + orphaned if we would let the UPDATE happen. Thus we return + an error. */ + + return(DB_ROW_IS_REFERENCED); + } + if (node->cascade_node == NULL) { /* Extend our query graph by creating a child to current update node. The child is used in the cascade or set null @@ -609,7 +622,7 @@ the caller must have a shared latch on dict_foreign_key_check_lock. */ ulint row_ins_check_foreign_constraint( /*=============================*/ - /* out: DB_SUCCESS, DB_LOCK_WAIT, + /* out: DB_SUCCESS, DB_NO_REFERENCED_ROW, or DB_ROW_IS_REFERENCED */ ibool check_ref,/* in: TRUE if we want to check that @@ -627,6 +640,7 @@ row_ins_check_foreign_constraint( dict_table_t* check_table; dict_index_t* check_index; ulint n_fields_cmp; + ibool timeout_expired; rec_t* rec; btr_pcur_t pcur; ibool moved; @@ -635,6 +649,7 @@ row_ins_check_foreign_constraint( ulint i; mtr_t mtr; +run_again: ut_ad(rw_lock_own(&dict_foreign_key_check_lock, RW_LOCK_SHARED)); if (thr_get_trx(thr)->check_foreigns == FALSE) { @@ -682,7 +697,7 @@ row_ins_check_foreign_constraint( if (err != DB_SUCCESS) { - return(err); + goto do_possible_lock_wait; } } @@ -727,6 +742,11 @@ row_ins_check_foreign_constraint( if (!rec_get_deleted_flag(rec)) { /* Found a matching record */ +/* printf( +"FOREIGN: Found matching record from %s %s\n", + check_index->table_name, check_index->name); + rec_print(rec); +*/ if (check_ref) { err = DB_SUCCESS; @@ -779,6 +799,22 @@ next_rec: /* Restore old value */ dtuple_set_n_fields_cmp(entry, n_fields_cmp); +do_possible_lock_wait: + if (err == DB_LOCK_WAIT) { + thr_get_trx(thr)->error_state = err; + + que_thr_stop_for_mysql(thr); + + timeout_expired = srv_suspend_mysql_thread(thr); + + if (!timeout_expired) { + + goto run_again; + } + + err = DB_LOCK_WAIT_TIMEOUT; + } + return(err); } @@ -792,8 +828,7 @@ static ulint row_ins_check_foreign_constraints( /*==============================*/ - /* out: DB_SUCCESS, DB_LOCK_WAIT, or error - code */ + /* out: DB_SUCCESS or error code */ dict_table_t* table, /* in: table */ dict_index_t* index, /* in: index */ dtuple_t* entry, /* in: index entry for index */ diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index d6c8d7ab412..e0737f53213 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -934,6 +934,7 @@ row_update_for_mysql( ut_ad(!prebuilt->sql_stat_start); que_thr_move_to_run_state_for_mysql(thr, trx); + run_again: thr->run_node = node; thr->prev_node = node; @@ -998,7 +999,6 @@ row_update_cascade_for_mysql( trx_t* trx; trx = thr_get_trx(thr); - run_again: thr->run_node = node; thr->prev_node = node; @@ -1131,6 +1131,35 @@ row_mysql_recover_tmp_table( } /************************************************************************* +Locks the data dictionary exclusively for performing a table create +operation. */ + +void +row_mysql_lock_data_dictionary(void) +/*================================*/ +{ + /* Serialize data dictionary operations with dictionary mutex: + no deadlocks or lock waits can occur then in these operations */ + + rw_lock_x_lock(&(dict_foreign_key_check_lock)); + mutex_enter(&(dict_sys->mutex)); +} + +/************************************************************************* +Unlocks the data dictionary exclusively lock. */ + +void +row_mysql_unlock_data_dictionary(void) +/*==================================*/ +{ + /* Serialize data dictionary operations with dictionary mutex: + no deadlocks can occur then in these operations */ + + mutex_exit(&(dict_sys->mutex)); + rw_lock_x_unlock(&(dict_foreign_key_check_lock)); +} + +/************************************************************************* Does a table creation operation for MySQL. If the name of the created table ends to characters INNODB_MONITOR, then this also starts printing of monitor output by the master thread. */ @@ -1150,6 +1179,7 @@ row_create_table_for_mysql( ulint err; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); + ut_ad(mutex_own(&(dict_sys->mutex))); if (srv_created_new_raw || srv_force_recovery) { fprintf(stderr, @@ -1265,19 +1295,13 @@ row_create_table_for_mysql( "to use this feature you must compile InnoDB with\n" "UNIV_MEM_DEBUG defined in univ.i and the server must be\n" "quiet because allocation from a mem heap is not protected\n" - "by any semaphore.\n"); + "by any semaphore.\n"); ut_a(mem_validate()); printf("Memory validated\n"); } - /* Serialize data dictionary operations with dictionary mutex: - no deadlocks can occur then in these operations */ - - rw_lock_x_lock(&(dict_foreign_key_check_lock)); - mutex_enter(&(dict_sys->mutex)); - heap = mem_heap_create(512); trx->dict_operation = TRUE; @@ -1327,9 +1351,6 @@ row_create_table_for_mysql( trx->error_state = DB_SUCCESS; } - mutex_exit(&(dict_sys->mutex)); - rw_lock_x_unlock(&(dict_foreign_key_check_lock)); - que_graph_free((que_t*) que_node_get_parent(thr)); trx->op_info = (char *) ""; @@ -1356,6 +1377,7 @@ row_create_index_for_mysql( ulint keywordlen; ulint err; + ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); trx->op_info = (char *) "creating index"; @@ -1374,12 +1396,6 @@ row_create_index_for_mysql( return(DB_SUCCESS); } - /* Serialize data dictionary operations with dictionary mutex: - no deadlocks can occur then in these operations */ - - rw_lock_x_lock(&(dict_foreign_key_check_lock)); - mutex_enter(&(dict_sys->mutex)); - heap = mem_heap_create(512); trx->dict_operation = TRUE; @@ -1407,9 +1423,6 @@ row_create_index_for_mysql( trx->error_state = DB_SUCCESS; } - mutex_exit(&(dict_sys->mutex)); - rw_lock_x_unlock(&(dict_foreign_key_check_lock)); - que_graph_free((que_t*) que_node_get_parent(thr)); trx->op_info = (char *) ""; @@ -1443,6 +1456,7 @@ row_table_add_foreign_constraints( ulint keywordlen; ulint err; + ut_ad(mutex_own(&(dict_sys->mutex))); ut_a(sql_string); trx->op_info = (char *) "adding foreign keys"; @@ -1461,12 +1475,6 @@ row_table_add_foreign_constraints( return(DB_SUCCESS); } - /* Serialize data dictionary operations with dictionary mutex: - no deadlocks can occur then in these operations */ - - rw_lock_x_lock(&(dict_foreign_key_check_lock)); - mutex_enter(&(dict_sys->mutex)); - trx->dict_operation = TRUE; err = dict_create_foreign_constraints(trx, sql_string, name); @@ -1488,9 +1496,6 @@ row_table_add_foreign_constraints( trx->error_state = DB_SUCCESS; } - mutex_exit(&(dict_sys->mutex)); - rw_lock_x_unlock(&(dict_foreign_key_check_lock)); - return((int) err); } @@ -1922,6 +1927,13 @@ row_drop_table_for_mysql( ut_a(0); } else { dict_table_remove_from_cache(table); + + if (dict_load_table(name) != NULL) { + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: Error: dropping of table %s failed!\n", name); + + } } funct_exit: rw_lock_s_unlock(&(purge_sys->purge_is_running)); @@ -1979,6 +1991,7 @@ loop: if (table->n_mysql_handles_opened > 0) { mutex_exit(&(dict_sys->mutex)); + rw_lock_x_unlock(&(dict_foreign_key_check_lock)); ut_print_timestamp(stderr); fprintf(stderr, @@ -2409,6 +2422,14 @@ row_check_table_for_mysql( index = dict_table_get_next_index(index); } + /* We validate also the whole adaptive hash index for all tables + at every CHECK TABLE */ + + if (!btr_search_validate()) { + + ret = DB_ERROR; + } + prebuilt->trx->op_info = (char *) ""; return(ret); diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c index 1dca017c349..60e057b816e 100644 --- a/innobase/row/row0purge.c +++ b/innobase/row/row0purge.c @@ -511,6 +511,14 @@ row_purge_parse_undo_rec( clust_index = dict_table_get_first_index(node->table); + if (clust_index == NULL) { + /* The table was corrupt in the data dictionary */ + + rw_lock_x_unlock(&(purge_sys->purge_is_running)); + + return(FALSE); + } + ptr = trx_undo_rec_get_row_ref(ptr, clust_index, &(node->ref), node->heap); diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c index 631f238a72d..b84e55ca643 100644 --- a/innobase/row/row0umod.c +++ b/innobase/row/row0umod.c @@ -437,11 +437,12 @@ row_undo_mod_del_unmark_sec( rec_sprintf(err_buf, 900, btr_pcur_get_rec(&pcur)); fprintf(stderr, "InnoDB: record %s\n", err_buf); + trx_print(err_buf, thr_get_trx(thr)); fprintf(stderr, - "InnoDB: Make a detailed bug report and send it\n"); + "%s\nInnoDB: Make a detailed bug report and send it\n", + err_buf); fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n"); - trx_print(thr_get_trx(thr)); } else { btr_cur = btr_pcur_get_btr_cur(&pcur); diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index 1d5319a182b..25c82f39da9 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -129,8 +129,7 @@ static ulint row_upd_check_references_constraints( /*=================================*/ - /* out: DB_SUCCESS, DB_LOCK_WAIT, or an error - code */ + /* out: DB_SUCCESS or an error code */ btr_pcur_t* pcur, /* in: cursor positioned on a record; NOTE: the cursor position is lost in this function! */ dict_table_t* table, /* in: table in question */ @@ -626,7 +625,7 @@ row_upd_index_parse( /******************************************************************* Returns TRUE if ext_vec contains i. */ -UNIV_INLINE +static ibool upd_ext_vec_contains( /*=================*/ @@ -738,6 +737,7 @@ row_upd_build_difference_binary( ulint n_diff; ulint roll_ptr_pos; ulint trx_id_pos; + ibool extern_bit; ulint i; /* This function is used only for a clustered index */ @@ -763,9 +763,10 @@ row_upd_build_difference_binary( goto skip_compare; } + + extern_bit = rec_get_nth_field_extern_bit(rec, i); - if (rec_get_nth_field_extern_bit(rec, i) - != upd_ext_vec_contains(ext_vec, n_ext_vec, i) + if (extern_bit != upd_ext_vec_contains(ext_vec, n_ext_vec, i) || !dfield_data_is_binary_equal(dfield, len, data)) { upd_field = upd_get_nth_field(update, n_diff); @@ -1094,11 +1095,12 @@ row_upd_sec_index_entry( rec_sprintf(err_buf, 900, rec); fprintf(stderr, "InnoDB: record %s\n", err_buf); + trx_print(err_buf, thr_get_trx(thr)); + fprintf(stderr, - "InnoDB: Make a detailed bug report and send it\n"); + "%s\nInnoDB: Make a detailed bug report and send it\n", + err_buf); fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n"); - - trx_print(thr_get_trx(thr)); } else { /* Delete mark the old index record; it can already be delete marked if we return after a lock wait in @@ -1362,7 +1364,7 @@ ulint row_upd_del_mark_clust_rec( /*=======================*/ /* out: DB_SUCCESS if operation successfully - completed, else error code or DB_LOCK_WAIT */ + completed, else error code */ upd_node_t* node, /* in: row update node */ dict_index_t* index, /* in: clustered index */ que_thr_t* thr, /* in: query thread */ @@ -1381,8 +1383,6 @@ row_upd_del_mark_clust_rec( pcur = node->pcur; btr_cur = btr_pcur_get_btr_cur(pcur); - ut_ad(FALSE == rec_get_deleted_flag(btr_pcur_get_rec(pcur))); - /* Store row because we have to build also the secondary index entries */ @@ -1391,11 +1391,11 @@ row_upd_del_mark_clust_rec( /* Mark the clustered index record deleted; we do not have to check locks, because we assume that we have an x-lock on the record */ - err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG, btr_cur, - TRUE, thr, mtr); + err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG, + btr_cur, TRUE, thr, mtr); if (err == DB_SUCCESS && check_ref) { - /* NOTE that the following call loses - the position of pcur ! */ + /* NOTE that the following call loses the position of pcur ! */ + err = row_upd_check_references_constraints(pcur, index->table, index, thr, mtr); if (err != DB_SUCCESS) { diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 39f3566eac8..3efb82eb8eb 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -61,7 +61,7 @@ ulint srv_activity_count = 0; ibool srv_lock_timeout_and_monitor_active = FALSE; ibool srv_error_monitor_active = FALSE; -char* srv_main_thread_op_info = (char *) ""; +char* srv_main_thread_op_info = (char*) ""; /* Server parameters which are read from the initfile */ @@ -238,15 +238,14 @@ ulint srv_n_rows_updated_old = 0; ulint srv_n_rows_deleted_old = 0; ulint srv_n_rows_read_old = 0; -ibool srv_print_innodb_monitor = FALSE; -ibool srv_print_innodb_lock_monitor = FALSE; -ibool srv_print_innodb_tablespace_monitor = FALSE; - /* Set the following to 0 if you want InnoDB to write messages on stderr on startup/shutdown */ ibool srv_print_verbose_log = TRUE; +ibool srv_print_innodb_monitor = FALSE; +ibool srv_print_innodb_lock_monitor = FALSE; +ibool srv_print_innodb_tablespace_monitor = FALSE; ibool srv_print_innodb_table_monitor = FALSE; /* The parameters below are obsolete: */ @@ -278,6 +277,10 @@ i/o handler thread */ char* srv_io_thread_op_info[SRV_MAX_N_IO_THREADS]; +time_t srv_last_monitor_time; + +mutex_t srv_innodb_monitor_mutex; + /* IMPLEMENTATION OF THE SERVER MAIN PROGRAM ========================================= @@ -645,7 +648,7 @@ srv_release_threads( slot = srv_table_get_nth_slot(i); - if ((slot->type == type) && slot->suspended) { + if (slot->in_use && slot->type == type && slot->suspended) { slot->suspended = FALSE; @@ -987,7 +990,6 @@ srv_communication_init( /************************************************************************* Implements the recovery utility. */ -#ifdef NOT_USED static ulint srv_recovery_thread( @@ -1025,7 +1027,7 @@ srv_recovery_thread( return(0); } -#endif + /************************************************************************* Implements the purge utility. */ @@ -1077,7 +1079,6 @@ srv_create_utility_threads(void) /************************************************************************* Implements the communication threads. */ -#ifdef NOT_USED static ulint srv_com_thread( @@ -1125,7 +1126,7 @@ srv_com_thread( return(0); } -#endif + /************************************************************************* Creates the communication threads. */ @@ -1147,7 +1148,6 @@ srv_create_com_threads(void) /************************************************************************* Implements the worker threads. */ -#ifdef NOT_USED static ulint srv_worker_thread( @@ -1190,7 +1190,7 @@ srv_worker_thread( return(0); } -#endif + /************************************************************************* Creates the worker threads. */ @@ -1625,13 +1625,16 @@ srv_init(void) kernel_mutex_temp = mem_alloc(sizeof(mutex_t)); mutex_create(&kernel_mutex); mutex_set_level(&kernel_mutex, SYNC_KERNEL); + + mutex_create(&srv_innodb_monitor_mutex); + mutex_set_level(&srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK); srv_sys->threads = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t)); for (i = 0; i < OS_THREAD_MAX_N; i++) { slot = srv_table_get_nth_slot(i); slot->in_use = FALSE; - slot->type=0; /* Avoid purify errors */ + slot->type=0; /* Avoid purify errors */ slot->event = os_event_create(NULL); ut_a(slot->event); } @@ -1641,6 +1644,7 @@ srv_init(void) for (i = 0; i < OS_THREAD_MAX_N; i++) { slot = srv_mysql_table + i; slot->in_use = FALSE; + slot->type = 0; slot->event = os_event_create(NULL); ut_a(slot->event); } @@ -1900,7 +1904,6 @@ srv_conc_exit_innodb( trx_t* trx) /* in: transaction object associated with the thread */ { - if (srv_thread_concurrency >= 500) { return; @@ -2004,7 +2007,31 @@ srv_table_reserve_slot_for_mysql(void) while (slot->in_use) { i++; - ut_a(i < OS_THREAD_MAX_N); + + if (i >= OS_THREAD_MAX_N) { + + ut_print_timestamp(stderr); + + fprintf(stderr, +" InnoDB: There appear to be %lu MySQL threads currently waiting\n" +"InnoDB: inside InnoDB, which is the upper limit. Cannot continue operation.\n" +"InnoDB: We intentionally generate a seg fault to print a stack trace\n" +"InnoDB: on Linux. But first we print a list of waiting threads.\n", i); + + for (i = 0; i < OS_THREAD_MAX_N; i++) { + + slot = srv_mysql_table + i; + + fprintf(stderr, +"Slot %lu: thread id %lu, type %lu, in use %lu, susp %lu, time %lu\n", + i, (ulint)(slot->id), + slot->type, slot->in_use, + slot->suspended, + (ulint)difftime(ut_time(), slot->suspend_time)); + } + + ut_a(0); + } slot = srv_mysql_table + i; } @@ -2141,104 +2168,113 @@ srv_release_mysql_thread_if_suspended( /* not found */ } -/************************************************************************* -A thread which wakes up threads whose lock wait may have lasted too long. -This also prints the info output by various InnoDB monitors. */ +/********************************************************************** +Sprintfs to a buffer the output of the InnoDB Monitor. */ -#ifndef __WIN__ -void* -#else -ulint -#endif -srv_lock_timeout_and_monitor_thread( -/*================================*/ - /* out: a dummy parameter */ - void* arg) /* in: a dummy parameter required by - os_thread_create */ +void +srv_sprintf_innodb_monitor( +/*=======================*/ + char* buf, /* in/out: buffer which must be at least 4 kB */ + ulint len) /* in: length of the buffer */ { - srv_slot_t* slot; - double time_elapsed; - time_t current_time; - time_t last_monitor_time; - time_t last_table_monitor_time; - ibool some_waits; - double wait_time; - ulint i; - - UT_NOT_USED(arg); - last_monitor_time = time(NULL); - last_table_monitor_time = time(NULL); -loop: - srv_lock_timeout_and_monitor_active = TRUE; + char* buf_end = buf + len - 2000; + double time_elapsed; + time_t current_time; - /* When someone is waiting for a lock, we wake up every second - and check if a timeout has passed for a lock wait */ + mutex_enter(&srv_innodb_monitor_mutex); - os_thread_sleep(1000000); + current_time = time(NULL); - /* In case mutex_exit is not a memory barrier, it is - theoretically possible some threads are left waiting though - the semaphore is already released. Wake up those threads: */ + /* We add 0.001 seconds to time_elapsed to prevent division + by zero if two users happen to call SHOW INNODB STATUS at the same + time */ - sync_arr_wake_threads_if_sema_free(); + time_elapsed = difftime(current_time, srv_last_monitor_time) + + 0.001; - current_time = time(NULL); + srv_last_monitor_time = time(NULL); - time_elapsed = difftime(current_time, last_monitor_time); - - if (time_elapsed > 15) { + ut_a(len >= 4096); - if (srv_print_innodb_monitor) { + buf += sprintf(buf, "\n=====================================\n"); - last_monitor_time = time(NULL); - - printf("=====================================\n"); - ut_print_timestamp(stdout); + ut_sprintf_timestamp(buf); + buf = buf + strlen(buf); - printf(" INNODB MONITOR OUTPUT\n" + buf += sprintf(buf, " INNODB MONITOR OUTPUT\n" "=====================================\n"); - printf("----------\n" + + buf += sprintf(buf, +"Per second values calculated from the last %lu seconds\n", + (ulint)time_elapsed); + + buf += sprintf(buf, "----------\n" "SEMAPHORES\n" "----------\n"); - sync_print(); - printf("------------\n" + sync_print(buf, buf_end); + + buf = buf + strlen(buf); + + buf += sprintf(buf, "------------\n" "TRANSACTIONS\n" "------------\n"); - lock_print_info(); - printf("--------\n" + lock_print_info(buf, buf_end); + buf = buf + strlen(buf); + + buf += sprintf(buf, "--------\n" "FILE I/O\n" "--------\n"); - os_aio_print(); - printf("-------------\n" - "INSERT BUFFER\n" - "-------------\n"); - ibuf_print(); - printf("---\n" + os_aio_print(buf, buf_end); + buf = buf + strlen(buf); + + buf += sprintf(buf, "-------------------------------------\n" + "INSERT BUFFER AND ADAPTIVE HASH INDEX\n" + "-------------------------------------\n"); + ibuf_print(buf, buf_end); + buf = buf + strlen(buf); + + ha_print_info(buf, buf_end, btr_search_sys->hash_index); + buf = buf + strlen(buf); + + buf += sprintf(buf, + "%.2f hash searches/s, %.2f non-hash searches/s\n", + (btr_cur_n_sea - btr_cur_n_sea_old) + / time_elapsed, + (btr_cur_n_non_sea - btr_cur_n_non_sea_old) + / time_elapsed); + btr_cur_n_sea_old = btr_cur_n_sea; + btr_cur_n_non_sea_old = btr_cur_n_non_sea; + + buf += sprintf(buf,"---\n" "LOG\n" "---\n"); - log_print(); - printf("----------------------\n" + log_print(buf, buf_end); + buf = buf + strlen(buf); + + buf += sprintf(buf, "----------------------\n" "BUFFER POOL AND MEMORY\n" "----------------------\n"); - printf( + buf += sprintf(buf, "Total memory allocated %lu; in additional pool allocated %lu\n", ut_total_allocated_memory, mem_pool_get_reserved(mem_comm_pool)); - buf_print_io(); - printf("--------------\n" + buf_print_io(buf, buf_end); + buf = buf + strlen(buf); + + buf += sprintf(buf, "--------------\n" "ROW OPERATIONS\n" "--------------\n"); - printf( + buf += sprintf(buf, "%ld queries inside InnoDB, %ld queries in queue; main thread: %s\n", srv_conc_n_threads, srv_conc_n_waiting_threads, srv_main_thread_op_info); - printf( + buf += sprintf(buf, "Number of rows inserted %lu, updated %lu, deleted %lu, read %lu\n", srv_n_rows_inserted, srv_n_rows_updated, srv_n_rows_deleted, srv_n_rows_read); - printf( + buf += sprintf(buf, "%.2f inserts/s, %.2f updates/s, %.2f deletes/s, %.2f reads/s\n", (srv_n_rows_inserted - srv_n_rows_inserted_old) / time_elapsed, @@ -2254,9 +2290,71 @@ loop: srv_n_rows_deleted_old = srv_n_rows_deleted; srv_n_rows_read_old = srv_n_rows_read; - printf("----------------------------\n" + buf += sprintf(buf, "----------------------------\n" "END OF INNODB MONITOR OUTPUT\n" "============================\n"); + mutex_exit(&srv_innodb_monitor_mutex); +} + +/************************************************************************* +A thread which wakes up threads whose lock wait may have lasted too long. +This also prints the info output by various InnoDB monitors. */ + +#ifndef __WIN__ +void* +#else +ulint +#endif +srv_lock_timeout_and_monitor_thread( +/*================================*/ + /* out: a dummy parameter */ + void* arg) /* in: a dummy parameter required by + os_thread_create */ +{ + srv_slot_t* slot; + double time_elapsed; + time_t current_time; + time_t last_table_monitor_time; + time_t last_monitor_time; + ibool some_waits; + double wait_time; + char* buf; + ulint i; + + UT_NOT_USED(arg); + srv_last_monitor_time = time(NULL); + last_table_monitor_time = time(NULL); + last_monitor_time = time(NULL); +loop: + srv_lock_timeout_and_monitor_active = TRUE; + + /* When someone is waiting for a lock, we wake up every second + and check if a timeout has passed for a lock wait */ + + os_thread_sleep(1000000); + + /* In case mutex_exit is not a memory barrier, it is + theoretically possible some threads are left waiting though + the semaphore is already released. Wake up those threads: */ + + sync_arr_wake_threads_if_sema_free(); + + current_time = time(NULL); + + time_elapsed = difftime(current_time, last_monitor_time); + + if (time_elapsed > 15) { + last_monitor_time = time(NULL); + + if (srv_print_innodb_monitor) { + + buf = mem_alloc(100000); + + srv_sprintf_innodb_monitor(buf, 100000); + + printf("%s", buf); + + mem_free(buf); } if (srv_print_innodb_tablespace_monitor @@ -2491,7 +2589,7 @@ srv_master_thread( os_event_set(srv_sys->operational); loop: - srv_main_thread_op_info = (char *) "reserving kernel mutex"; + srv_main_thread_op_info = (char*) "reserving kernel mutex"; n_ios_very_old = log_sys->n_log_ios + buf_pool->n_pages_read + buf_pool->n_pages_written; @@ -2507,18 +2605,19 @@ loop: for (i = 0; i < 10; i++) { n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read + buf_pool->n_pages_written; - srv_main_thread_op_info = (char *) "sleeping"; + srv_main_thread_op_info = (char*)"sleeping"; os_thread_sleep(1000000); /* ALTER TABLE in MySQL requires on Unix that the table handler can drop tables lazily after there no longer are SELECT queries to them. */ - srv_main_thread_op_info = (char*) "doing background drop tables"; + srv_main_thread_op_info = + (char*)"doing background drop tables"; row_drop_tables_for_mysql_in_background(); - srv_main_thread_op_info = (char*) ""; + srv_main_thread_op_info = (char*)""; if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND) { @@ -2529,8 +2628,9 @@ loop: is issued or the we have specified in my.cnf no flush at transaction commit */ - srv_main_thread_op_info = (char *) "flushing log"; + srv_main_thread_op_info = (char*)"flushing log"; log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP); + log_flush_to_disk(); /* If there were less than 10 i/os during the one second sleep, we assume that there is free @@ -2543,11 +2643,13 @@ loop: + buf_pool->n_pages_written; if (n_pend_ios < 3 && (n_ios - n_ios_old < 10)) { srv_main_thread_op_info = - (char *) "doing insert buffer merge"; + (char*)"doing insert buffer merge"; ibuf_contract_for_n_pages(TRUE, 5); - srv_main_thread_op_info = (char *) "flushing log"; + srv_main_thread_op_info = + (char*)"flushing log"; log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP); + log_flush_to_disk(); } if (srv_fast_shutdown && srv_shutdown_state > 0) { @@ -2583,21 +2685,23 @@ loop: + buf_pool->n_pages_written; if (n_pend_ios < 3 && (n_ios - n_ios_very_old < 200)) { - srv_main_thread_op_info =(char *) "flushing buffer pool pages"; + srv_main_thread_op_info = (char*) "flushing buffer pool pages"; buf_flush_batch(BUF_FLUSH_LIST, 50, ut_dulint_max); - srv_main_thread_op_info = (char *) "flushing log"; + srv_main_thread_op_info = (char*) "flushing log"; log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP); + log_flush_to_disk(); } /* We run a batch of insert buffer merge every 10 seconds, even if the server were active */ - srv_main_thread_op_info = (char *) "doing insert buffer merge"; + srv_main_thread_op_info = (char*)"doing insert buffer merge"; ibuf_contract_for_n_pages(TRUE, 5); - srv_main_thread_op_info = (char *) "flushing log"; + srv_main_thread_op_info = (char*)"flushing log"; log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP); + log_flush_to_disk(); /* We run a full purge every 10 seconds, even if the server were active */ @@ -2613,15 +2717,16 @@ loop: goto background_loop; } - srv_main_thread_op_info = (char *) "purging"; + srv_main_thread_op_info = (char*)"purging"; n_pages_purged = trx_purge(); current_time = time(NULL); if (difftime(current_time, last_flush_time) > 1) { - srv_main_thread_op_info = (char *) "flushing log"; + srv_main_thread_op_info = (char*) "flushing log"; log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP); + log_flush_to_disk(); last_flush_time = current_time; } } @@ -2630,25 +2735,25 @@ background_loop: /* In this loop we run background operations when the server is quiet and we also come here about once in 10 seconds */ - srv_main_thread_op_info = (char*) "doing background drop tables"; + srv_main_thread_op_info = (char*)"doing background drop tables"; n_tables_to_drop = row_drop_tables_for_mysql_in_background(); - srv_main_thread_op_info = (char*) ""; + srv_main_thread_op_info = (char*)""; - srv_main_thread_op_info = (char*) "flushing buffer pool pages"; + srv_main_thread_op_info = (char*)"flushing buffer pool pages"; /* Flush a few oldest pages to make the checkpoint younger */ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 10, ut_dulint_max); - srv_main_thread_op_info = (char*) "making checkpoint"; + srv_main_thread_op_info = (char*)"making checkpoint"; /* Make a new checkpoint about once in 10 seconds */ log_checkpoint(TRUE, FALSE); - srv_main_thread_op_info = (char *) "reserving kernel mutex"; + srv_main_thread_op_info = (char*)"reserving kernel mutex"; mutex_enter(&kernel_mutex); if (srv_activity_count != old_activity_count) { @@ -2661,11 +2766,11 @@ background_loop: /* The server has been quiet for a while: start running background operations */ - srv_main_thread_op_info = (char *) "purging"; + srv_main_thread_op_info = (char*)"purging"; n_pages_purged = trx_purge(); - srv_main_thread_op_info = (char *) "reserving kernel mutex"; + srv_main_thread_op_info = (char*)"reserving kernel mutex"; mutex_enter(&kernel_mutex); if (srv_activity_count != old_activity_count) { @@ -2674,10 +2779,10 @@ background_loop: } mutex_exit(&kernel_mutex); - srv_main_thread_op_info = (char *) "doing insert buffer merge"; + srv_main_thread_op_info = (char*)"doing insert buffer merge"; n_bytes_merged = ibuf_contract_for_n_pages(TRUE, 20); - srv_main_thread_op_info = (char *) "reserving kernel mutex"; + srv_main_thread_op_info = (char*)"reserving kernel mutex"; mutex_enter(&kernel_mutex); if (srv_activity_count != old_activity_count) { @@ -2686,10 +2791,10 @@ background_loop: } mutex_exit(&kernel_mutex); - srv_main_thread_op_info = (char *) "flushing buffer pool pages"; + srv_main_thread_op_info = (char*)"flushing buffer pool pages"; n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100, ut_dulint_max); - srv_main_thread_op_info = (char *) "reserving kernel mutex"; + srv_main_thread_op_info = (char*)"reserving kernel mutex"; mutex_enter(&kernel_mutex); if (srv_activity_count != old_activity_count) { @@ -2698,15 +2803,14 @@ background_loop: } mutex_exit(&kernel_mutex); - srv_main_thread_op_info = - (char *) "waiting for buffer pool flush to end"; + srv_main_thread_op_info = (char*) "waiting for buffer pool flush to end"; buf_flush_wait_batch_end(BUF_FLUSH_LIST); - srv_main_thread_op_info = (char *) "making checkpoint"; + srv_main_thread_op_info = (char*)"making checkpoint"; log_checkpoint(TRUE, FALSE); - srv_main_thread_op_info = (char *) "reserving kernel mutex"; + srv_main_thread_op_info = (char*)"reserving kernel mutex"; mutex_enter(&kernel_mutex); if (srv_activity_count != old_activity_count) { @@ -2716,7 +2820,7 @@ background_loop: mutex_exit(&kernel_mutex); srv_main_thread_op_info = - (char *) "archiving log (if log archive is on)"; + (char*)"archiving log (if log archive is on)"; log_archive_do(FALSE, &n_bytes_archived); @@ -2742,7 +2846,7 @@ background_loop: master thread to wait for more server activity */ suspend_thread: - srv_main_thread_op_info = (char *) "suspending"; + srv_main_thread_op_info = (char*)"suspending"; mutex_enter(&kernel_mutex); @@ -2756,7 +2860,7 @@ suspend_thread: mutex_exit(&kernel_mutex); - srv_main_thread_op_info = (char *) "waiting for server activity"; + srv_main_thread_op_info = (char*)"waiting for server activity"; os_event_wait(event); diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index f5a0c62aaf9..55e734be3bd 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -433,8 +433,7 @@ Normalizes a directory path for Windows: converts slashes to backslashes. */ void srv_normalize_path_for_win( /*=======================*/ - char* str __attribute__((unused))) - /* in/out: null-terminated character string */ + char* str __attribute__((unused))) /* in/out: null-terminated character string */ { #ifdef __WIN__ ulint i; @@ -619,8 +618,7 @@ open_or_create_log_file( if (k == 0 && i == 0) { arch_space_id = 2 * k + 1 + SRV_LOG_SPACE_FIRST_ID; - fil_space_create((char *) "arch_log_space", arch_space_id, - FIL_LOG); + fil_space_create((char*) "arch_log_space", arch_space_id, FIL_LOG); } else { arch_space_id = ULINT_UNDEFINED; } @@ -839,7 +837,6 @@ open_or_create_data_files( /********************************************************************* This thread is used to measure contention of latches. */ -#ifdef NOT_USED static ulint test_measure_cont( @@ -899,7 +896,7 @@ test_measure_cont( "Mutex res. l %lu, p %lu, k %lu s x %lu s s %lu s mut %lu of %lu\n", lcount, pcount, kcount, s_xcount, s_scount, s_mcount, j); - sync_print_wait_info(); +/* sync_print_wait_info(); */ fprintf(stderr, "log i/o %lu n non sea %lu n succ %lu n h fail %lu\n", @@ -909,7 +906,7 @@ test_measure_cont( return(0); } -#endif + /******************************************************************** Starts InnoDB and creates a new database if database files are not found and the user wants. Server parameters are @@ -935,27 +932,44 @@ innobase_start_or_create_for_mysql(void) ulint k; mtr_t mtr; +#ifdef UNIV_DEBUG + fprintf(stderr, +"InnoDB: !!!!!!!!!!!!!! UNIV_DEBUG switched on !!!!!!!!!!!!!!!\n"); +#endif + +#ifdef UNIV_SYNC_DEBUG + fprintf(stderr, +"InnoDB: !!!!!!!!!!!!!! UNIV_SYNC_DEBUG switched on !!!!!!!!!!!!!!!\n"); +#endif + +#ifdef UNIV_SEARCH_DEBUG + fprintf(stderr, +"InnoDB: !!!!!!!!!!!!!! UNIV_SEARCH_DEBUG switched on !!!!!!!!!!!!!!!\n"); +#endif + +#ifdef UNIV_MEM_DEBUG + fprintf(stderr, +"InnoDB: !!!!!!!!!!!!!! UNIV_MEM_DEBUG switched on !!!!!!!!!!!!!!!\n"); +#endif + log_do_write = TRUE; /* yydebug = TRUE; */ srv_is_being_started = TRUE; srv_startup_is_before_trx_rollback_phase = TRUE; - if (0 == ut_strcmp(srv_unix_file_flush_method_str, - (char *) "fdatasync")) { - srv_unix_file_flush_method = SRV_UNIX_FDATASYNC; + if (0 == ut_strcmp(srv_unix_file_flush_method_str, "fdatasync")) { + srv_unix_file_flush_method = SRV_UNIX_FDATASYNC; - } else if (0 == ut_strcmp(srv_unix_file_flush_method_str, - (char *) "O_DSYNC")) { - srv_unix_file_flush_method = SRV_UNIX_O_DSYNC; + } else if (0 == ut_strcmp(srv_unix_file_flush_method_str, "O_DSYNC")) { + srv_unix_file_flush_method = SRV_UNIX_O_DSYNC; } else if (0 == ut_strcmp(srv_unix_file_flush_method_str, - (char *) "littlesync")) { - srv_unix_file_flush_method = SRV_UNIX_LITTLESYNC; + "littlesync")) { + srv_unix_file_flush_method = SRV_UNIX_LITTLESYNC; - } else if (0 == ut_strcmp(srv_unix_file_flush_method_str, - (char *) "nosync")) { - srv_unix_file_flush_method = SRV_UNIX_NOSYNC; + } else if (0 == ut_strcmp(srv_unix_file_flush_method_str, "nosync")) { + srv_unix_file_flush_method = SRV_UNIX_NOSYNC; } else { fprintf(stderr, "InnoDB: Unrecognized value %s for innodb_flush_method\n", @@ -1005,7 +1019,7 @@ innobase_start_or_create_for_mysql(void) os_aio_use_native_aio = FALSE; if (!os_aio_use_native_aio) { - os_aio_init(4 * SRV_N_PENDING_IOS_PER_THREAD + os_aio_init(8 * SRV_N_PENDING_IOS_PER_THREAD * srv_n_file_io_threads, srv_n_file_io_threads, SRV_MAX_N_PENDING_SYNC_IOS); @@ -1350,9 +1364,15 @@ innobase_shutdown_for_mysql(void) "InnoDB: inside InnoDB at shutdown\n", srv_conc_n_threads); } - + + /* + TODO: We should exit the i/o-handler and other utility threads + before freeing all memory. Now this can potentially cause a seg + fault! + */ #ifdef NOT_WORKING_YET - ut_free_all_mem(); -#endif + ut_free_all_mem(); +#endif + return((int) DB_SUCCESS); } diff --git a/innobase/sync/sync0arr.c b/innobase/sync/sync0arr.c index 4487fa72995..36dd8a7d80c 100644 --- a/innobase/sync/sync0arr.c +++ b/innobase/sync/sync0arr.c @@ -441,7 +441,8 @@ static void sync_array_cell_print( /*==================*/ - FILE* file, /* in: file where to print */ + char* buf, /* in: buffer where to print, must be + at least 400 characters */ sync_cell_t* cell) /* in: sync cell */ { mutex_t* mutex; @@ -451,7 +452,7 @@ sync_array_cell_print( type = cell->request_type; - fprintf(file, + buf += sprintf(buf, "--Thread %lu has waited at %s line %lu for %.2f seconds the semaphore:\n", (ulint)cell->thread, cell->file, cell->line, difftime(time(NULL), cell->reservation_time)); @@ -461,54 +462,58 @@ sync_array_cell_print( been freed meanwhile */ mutex = cell->old_wait_mutex; - fprintf(file, + buf += sprintf(buf, "Mutex at %lx created file %s line %lu, lock var %lu\n", (ulint)mutex, mutex->cfile_name, mutex->cline, mutex->lock_word); - fprintf(file, + buf += sprintf(buf, "Last time reserved in file %s line %lu, waiters flag %lu\n", mutex->file_name, mutex->line, mutex->waiters); } else if (type == RW_LOCK_EX || type == RW_LOCK_SHARED) { if (type == RW_LOCK_EX) { - fprintf(file, "X-lock on"); + buf += sprintf(buf, "X-lock on"); } else { - fprintf(file, "S-lock on"); + buf += sprintf(buf, "S-lock on"); } rwlock = cell->old_wait_rw_lock; - fprintf(file, " RW-latch at %lx created in file %s line %lu\n", + buf += sprintf(buf, + " RW-latch at %lx created in file %s line %lu\n", (ulint)rwlock, rwlock->cfile_name, rwlock->cline); if (rwlock->writer != RW_LOCK_NOT_LOCKED) { - fprintf(file, + buf += sprintf(buf, "a writer (thread id %lu) has reserved it in mode", (ulint)rwlock->writer_thread); if (rwlock->writer == RW_LOCK_EX) { - fprintf(file, " exclusive\n"); + buf += sprintf(buf, " exclusive\n"); } else { - fprintf(file, " wait exclusive\n"); + buf += sprintf(buf, " wait exclusive\n"); } } - fprintf(file, "number of readers %lu, waiters flag %lu\n", + buf += sprintf(buf, + "number of readers %lu, waiters flag %lu\n", rwlock->reader_count, rwlock->waiters); - fprintf(file, "Last time read locked in file %s line %lu\n", + buf += sprintf(buf, + "Last time read locked in file %s line %lu\n", rwlock->last_s_file_name, rwlock->last_s_line); - fprintf(file, "Last time write locked in file %s line %lu\n", + buf += sprintf(buf, + "Last time write locked in file %s line %lu\n", rwlock->last_x_file_name, rwlock->last_x_line); } else { ut_error; } if (!cell->waiting) { - fprintf(file, "wait has ended\n"); + buf += sprintf(buf, "wait has ended\n"); } if (cell->event_set) { - fprintf(file, "wait is ending\n"); + buf += sprintf(buf, "wait is ending\n"); } } @@ -610,6 +615,7 @@ sync_array_detect_deadlock( os_thread_id_t thread; ibool ret; rw_lock_debug_t* debug; + char buf[500]; ut_a(arr && start && cell); ut_ad(cell->wait_object); @@ -642,11 +648,12 @@ sync_array_detect_deadlock( ret = sync_array_deadlock_step(arr, start, thread, 0, depth); if (ret) { + sync_array_cell_print(buf, cell); printf( - "Mutex %lx owned by thread %lu file %s line %lu\n", + "Mutex %lx owned by thread %lu file %s line %lu\n%s", (ulint)mutex, mutex->thread_id, - mutex->file_name, mutex->line); - sync_array_cell_print(stdout, cell); + mutex->file_name, mutex->line, + buf); return(TRUE); } } @@ -678,9 +685,9 @@ sync_array_detect_deadlock( debug->pass, depth); if (ret) { - printf("rw-lock %lx ", (ulint) lock); + sync_array_cell_print(buf, cell); + printf("rw-lock %lx %s ", (ulint) lock, buf); rw_lock_debug_print(debug); - sync_array_cell_print(stdout, cell); return(TRUE); } @@ -711,9 +718,9 @@ sync_array_detect_deadlock( debug->pass, depth); if (ret) { - printf("rw-lock %lx ", (ulint) lock); + sync_array_cell_print(buf, cell); + printf("rw-lock %lx %s ", (ulint) lock, buf); rw_lock_debug_print(debug); - sync_array_cell_print(stdout, cell); return(TRUE); } @@ -898,6 +905,7 @@ sync_array_print_long_waits(void) sync_cell_t* cell; ibool old_val; ibool noticed = FALSE; + char buf[500]; ulint i; for (i = 0; i < sync_primary_wait_array->n_cells; i++) { @@ -907,9 +915,10 @@ sync_array_print_long_waits(void) if (cell->wait_object != NULL && difftime(time(NULL), cell->reservation_time) > 240) { + sync_array_cell_print(buf, cell); + fprintf(stderr, - "InnoDB: Warning: a long semaphore wait:\n"); - sync_array_cell_print(stderr, cell); + "InnoDB: Warning: a long semaphore wait:\n%s", buf); noticed = TRUE; } @@ -948,6 +957,8 @@ static void sync_array_output_info( /*===================*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end,/* in: buffer end */ sync_array_t* arr) /* in: wait array; NOTE! caller must own the mutex */ { @@ -955,18 +966,29 @@ sync_array_output_info( ulint count; ulint i; - printf("OS WAIT ARRAY INFO: reservation count %ld, signal count %ld\n", + if (buf_end - buf < 500) { + return; + } + + buf += sprintf(buf, + "OS WAIT ARRAY INFO: reservation count %ld, signal count %ld\n", arr->res_count, arr->sg_count); i = 0; count = 0; while (count < arr->n_reserved) { + if (buf_end - buf < 500) { + return; + } + cell = sync_array_get_nth_cell(arr, i); if (cell->wait_object != NULL) { count++; - sync_array_cell_print(stdout, cell); + sync_array_cell_print(buf, cell); + + buf = buf + strlen(buf); } i++; @@ -979,11 +1001,13 @@ Prints info of the wait array. */ void sync_array_print_info( /*==================*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end,/* in: buffer end */ sync_array_t* arr) /* in: wait array */ { sync_array_enter(arr); - sync_array_output_info(arr); + sync_array_output_info(buf, buf_end, arr); sync_array_exit(arr); } diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c index 144ed263db9..14a2a6f8cc1 100644 --- a/innobase/sync/sync0sync.c +++ b/innobase/sync/sync0sync.c @@ -874,6 +874,7 @@ sync_thread_levels_empty_gen( sync_level_t* slot; rw_lock_t* lock; mutex_t* mutex; + char* buf; ulint i; if (!sync_order_checks_on) { @@ -907,7 +908,9 @@ sync_thread_levels_empty_gen( mutex = slot->latch; mutex_exit(&sync_thread_mutex); - sync_print(); + buf = mem_alloc(20000); + + sync_print(buf, buf + 18000); ut_error; return(FALSE); @@ -1243,14 +1246,21 @@ sync_close(void) Prints wait info of the sync system. */ void -sync_print_wait_info(void) -/*======================*/ +sync_print_wait_info( +/*=================*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end) /* in: buffer end */ { #ifdef UNIV_SYNC_DEBUG printf("Mutex exits %lu, rws exits %lu, rwx exits %lu\n", mutex_exit_count, rw_s_exit_count, rw_x_exit_count); #endif - printf( + if (buf_end - buf < 500) { + + return; + } + + sprintf(buf, "Mutex spin waits %lu, rounds %lu, OS waits %lu\n" "RW-shared spins %lu, OS waits %lu; RW-excl spins %lu, OS waits %lu\n", mutex_spin_wait_count, mutex_spin_round_count, @@ -1263,11 +1273,18 @@ sync_print_wait_info(void) Prints info of the sync system. */ void -sync_print(void) -/*============*/ +sync_print( +/*=======*/ + char* buf, /* in/out: buffer where to print */ + char* buf_end) /* in: buffer end */ { mutex_list_print_info(); + rw_lock_list_print_info(); - sync_array_print_info(sync_primary_wait_array); - sync_print_wait_info(); + + sync_array_print_info(buf, buf_end, sync_primary_wait_array); + + buf = buf + strlen(buf); + + sync_print_wait_info(buf, buf_end); } diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c index 97cc2dbff1a..4c2ee5dc9be 100644 --- a/innobase/trx/trx0roll.c +++ b/innobase/trx/trx0roll.c @@ -160,11 +160,13 @@ trx_rollback_last_sql_stat_for_mysql( } /*********************************************************************** -Rollback uncommitted transactions which have no user session. */ +Rollback or clean up transactions which have no user session. If the +transaction already was committed, then we clean up a possible insert +undo log. If the transaction was not yet committed, then we roll it back. */ void -trx_rollback_all_without_sess(void) -/*===============================*/ +trx_rollback_or_clean_all_without_sess(void) +/*========================================*/ { mem_heap_t* heap; que_fork_t* fork; @@ -217,6 +219,19 @@ loop: trx->sess = trx_dummy_sess; + if (trx->conc_state == TRX_COMMITTED_IN_MEMORY) { + + fprintf(stderr, "InnoDB: Cleaning up trx with id %lu %lu\n", + ut_dulint_get_high(trx->id), + ut_dulint_get_low(trx->id)); + + trx_cleanup_at_db_startup(trx); + + mem_heap_free(heap); + + goto loop; + } + fork = que_fork_create(NULL, NULL, QUE_FORK_RECOVERY, heap); fork->trx = trx; @@ -264,9 +279,17 @@ loop: /* If the transaction was for a dictionary operation, we drop the relevant table, if it still exists */ + fprintf(stderr, +"InnoDB: Dropping table with id %lu %lu in recovery if it exists\n", + ut_dulint_get_high(trx->table_id), + ut_dulint_get_low(trx->table_id)); + table = dict_table_get_on_id_low(trx->table_id, trx); if (table) { + fprintf(stderr, +"InnoDB: Table found: dropping table %s in recovery\n", table->name); + err = row_drop_table_for_mysql(table->name, trx, TRUE); ut_a(err == (int) DB_SUCCESS); diff --git a/innobase/trx/trx0sys.c b/innobase/trx/trx0sys.c index 32a1db48488..675cdf1b7e4 100644 --- a/innobase/trx/trx0sys.c +++ b/innobase/trx/trx0sys.c @@ -26,6 +26,14 @@ Created 3/26/1996 Heikki Tuuri trx_sys_t* trx_sys = NULL; trx_doublewrite_t* trx_doublewrite = NULL; +/* In a MySQL replication slave, in crash recovery we store the master log +file name and position here. We have successfully got the updates to InnoDB +up to this position. If .._pos is -1, it means no crash recovery was needed, +or there was no master log position info inside InnoDB. */ + +char trx_sys_mysql_master_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN]; +ib_longlong trx_sys_mysql_master_log_pos = -1; + /******************************************************************** Determines if a page number is located inside the doublewrite buffer. */ @@ -427,75 +435,62 @@ trx_sys_flush_max_trx_id(void) /********************************************************************* Updates the offset information about the end of the MySQL binlog entry -which corresponds to the transaction just being committed. */ +which corresponds to the transaction just being committed. In a MySQL +replication slave updates the latest master binlog position up to which +replication has proceeded. */ void trx_sys_update_mysql_binlog_offset( /*===============================*/ - trx_t* trx, /* in: transaction being committed */ - mtr_t* mtr) /* in: mtr */ + char* file_name,/* in: MySQL log file name */ + ib_longlong offset, /* in: position in that log file */ + ulint field, /* in: offset of the MySQL log info field in + the trx sys header */ + mtr_t* mtr) /* in: mtr */ { trx_sysf_t* sys_header; - char namebuf[TRX_SYS_MYSQL_LOG_NAME_LEN]; - - ut_ad(trx->mysql_log_file_name); - memset(namebuf, ' ', TRX_SYS_MYSQL_LOG_NAME_LEN - 1); - namebuf[TRX_SYS_MYSQL_LOG_NAME_LEN - 1] = '\0'; + if (ut_strlen(file_name) >= TRX_SYS_MYSQL_LOG_NAME_LEN) { - /* Copy the whole MySQL log file name to the buffer, or only the - last characters, if it does not fit */ + /* We cannot fit the name to the 512 bytes we have reserved */ - if (ut_strlen(trx->mysql_log_file_name) - > TRX_SYS_MYSQL_LOG_NAME_LEN - 1) { - ut_memcpy(namebuf, trx->mysql_log_file_name - + ut_strlen(trx->mysql_log_file_name) - - (TRX_SYS_MYSQL_LOG_NAME_LEN - 1), - TRX_SYS_MYSQL_LOG_NAME_LEN - 1); - } else { - ut_memcpy(namebuf, trx->mysql_log_file_name, - 1 + ut_strlen(trx->mysql_log_file_name)); + return; } - namebuf[TRX_SYS_MYSQL_LOG_NAME_LEN - 1] = '\0'; - sys_header = trx_sysf_get(mtr); - if (mach_read_from_4(sys_header + TRX_SYS_MYSQL_LOG_INFO + if (mach_read_from_4(sys_header + field + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD) != TRX_SYS_MYSQL_LOG_MAGIC_N) { - mlog_write_ulint(sys_header + TRX_SYS_MYSQL_LOG_INFO + mlog_write_ulint(sys_header + field + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD, TRX_SYS_MYSQL_LOG_MAGIC_N, MLOG_4BYTES, mtr); } - if (0 != ut_memcmp(sys_header + TRX_SYS_MYSQL_LOG_INFO - + TRX_SYS_MYSQL_LOG_NAME, - namebuf, TRX_SYS_MYSQL_LOG_NAME_LEN)) { + if (0 != ut_memcmp(sys_header + field + TRX_SYS_MYSQL_LOG_NAME, + file_name, 1 + ut_strlen(file_name))) { - mlog_write_string(sys_header + TRX_SYS_MYSQL_LOG_INFO + mlog_write_string(sys_header + field + TRX_SYS_MYSQL_LOG_NAME, - namebuf, TRX_SYS_MYSQL_LOG_NAME_LEN, mtr); + file_name, 1 + ut_strlen(file_name), mtr); } - if (mach_read_from_4(sys_header + TRX_SYS_MYSQL_LOG_INFO + if (mach_read_from_4(sys_header + field + TRX_SYS_MYSQL_LOG_OFFSET_HIGH) > 0 - || (trx->mysql_log_offset >> 32) > 0) { + || (offset >> 32) > 0) { - mlog_write_ulint(sys_header + TRX_SYS_MYSQL_LOG_INFO + mlog_write_ulint(sys_header + field + TRX_SYS_MYSQL_LOG_OFFSET_HIGH, - (ulint)(trx->mysql_log_offset >> 32), + (ulint)(offset >> 32), MLOG_4BYTES, mtr); } - mlog_write_ulint(sys_header + TRX_SYS_MYSQL_LOG_INFO + mlog_write_ulint(sys_header + field + TRX_SYS_MYSQL_LOG_OFFSET_LOW, - (ulint)(trx->mysql_log_offset & 0xFFFFFFFF), + (ulint)(offset & 0xFFFFFFFF), MLOG_4BYTES, mtr); - - trx->mysql_log_file_name = NULL; } /********************************************************************* @@ -533,6 +528,58 @@ trx_sys_print_mysql_binlog_offset(void) mtr_commit(&mtr); } +/********************************************************************* +Prints to stderr the MySQL master log offset info in the trx system header if +the magic number shows it valid. */ + +void +trx_sys_print_mysql_master_log_pos(void) +/*====================================*/ +{ + trx_sysf_t* sys_header; + mtr_t mtr; + + mtr_start(&mtr); + + sys_header = trx_sysf_get(&mtr); + + if (mach_read_from_4(sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO + + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD) + != TRX_SYS_MYSQL_LOG_MAGIC_N) { + + mtr_commit(&mtr); + + return; + } + + fprintf(stderr, +"InnoDB: In a MySQL replication slave the last master binlog file\n" +"InnoDB: position %lu %lu, file name %s\n", + mach_read_from_4(sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO + + TRX_SYS_MYSQL_LOG_OFFSET_HIGH), + mach_read_from_4(sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO + + TRX_SYS_MYSQL_LOG_OFFSET_LOW), + sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO + + TRX_SYS_MYSQL_LOG_NAME); + /* Copy the master log position info to global variables we can + use in ha_innobase.cc to initialize glob_mi to right values */ + + ut_memcpy(trx_sys_mysql_master_log_name, + sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO + + TRX_SYS_MYSQL_LOG_NAME, + TRX_SYS_MYSQL_LOG_NAME_LEN); + + trx_sys_mysql_master_log_pos = + (((ib_longlong)mach_read_from_4( + sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO + + TRX_SYS_MYSQL_LOG_OFFSET_HIGH)) + << 32) + + (ib_longlong) + mach_read_from_4(sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO + + TRX_SYS_MYSQL_LOG_OFFSET_LOW); + mtr_commit(&mtr); +} + /******************************************************************** Looks for a free slot for a rollback segment in the trx system file copy. */ @@ -660,7 +707,7 @@ trx_sys_init_at_db_start(void) if (UT_LIST_GET_LEN(trx_sys->trx_list) > 0) { fprintf(stderr, - "InnoDB: %lu uncommitted transaction(s) which must be rolled back\n", + "InnoDB: %lu transaction(s) which must be rolled back or cleaned up\n", UT_LIST_GET_LEN(trx_sys->trx_list)); fprintf(stderr, "InnoDB: Trx id counter is %lu %lu\n", diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index 87b82cbee3a..8d84967a49d 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -26,9 +26,11 @@ Created 3/26/1996 Heikki Tuuri /* Copy of the prototype for innobase_mysql_print_thd: this -copy must be equal to the one in mysql/sql/ha_innobase.cc ! */ +copy MUST be equal to the one in mysql/sql/ha_innobase.cc ! */ -void innobase_mysql_print_thd(void* thd); +void innobase_mysql_print_thd( + char* buf, + void* thd); /* Dummy session used currently in MySQL interface */ sess_t* trx_dummy_sess = NULL; @@ -83,6 +85,8 @@ trx_create( trx->mysql_log_file_name = NULL; trx->mysql_log_offset = 0; + trx->mysql_master_log_file_name = ""; + trx->mysql_master_log_pos = 0; trx->ignore_duplicates_in_insert = FALSE; @@ -363,16 +367,31 @@ trx_lists_init_at_db_start(void) trx = trx_create(NULL); + trx->id = undo->trx_id; + + trx->insert_undo = undo; + trx->rseg = rseg; + if (undo->state != TRX_UNDO_ACTIVE) { trx->conc_state = TRX_COMMITTED_IN_MEMORY; + + /* We give a dummy value for the trx no; + this should have no relevance since purge + is not interested in committed transaction + numbers, unless they are in the history + list, in which case it looks the number + from the disk based undo log structure */ + + trx->no = trx->id; } else { trx->conc_state = TRX_ACTIVE; - } - trx->id = undo->trx_id; - trx->insert_undo = undo; - trx->rseg = rseg; + /* A running transaction always has the number + field inited to ut_dulint_max */ + + trx->no = ut_dulint_max; + } if (undo->dict_operation) { trx->dict_operation = undo->dict_operation; @@ -397,14 +416,25 @@ trx_lists_init_at_db_start(void) if (NULL == trx) { trx = trx_create(NULL); + trx->id = undo->trx_id; + if (undo->state != TRX_UNDO_ACTIVE) { trx->conc_state = TRX_COMMITTED_IN_MEMORY; + /* We give a dummy value for the trx + number */ + + trx->no = trx->id; } else { trx->conc_state = TRX_ACTIVE; + + /* A running transaction always has + the number field inited to + ut_dulint_max */ + + trx->no = ut_dulint_max; } - trx->id = undo->trx_id; trx->rseg = rseg; trx_list_insert_ordered(trx); @@ -583,7 +613,7 @@ trx_commit_off_kernel( if (undo) { mutex_enter(&kernel_mutex); #ifdef notdefined - /* ########## There is a bug here: purge and rollback + /* !!!!!!!!! There is a bug here: purge and rollback need the whole stack of old record versions even if no consistent read would need them!! This is because they decide on the basis of the old versions when we can @@ -627,12 +657,25 @@ trx_commit_off_kernel( mutex_exit(&(rseg->mutex)); /* Update the latest MySQL binlog name and offset info - in trx sys header if MySQL binlogging is on */ + in trx sys header if MySQL binlogging is on or the database + server is a MySQL replication slave */ if (trx->mysql_log_file_name) { - trx_sys_update_mysql_binlog_offset(trx, &mtr); + trx_sys_update_mysql_binlog_offset( + trx->mysql_log_file_name, + trx->mysql_log_offset, + TRX_SYS_MYSQL_LOG_INFO, &mtr); + trx->mysql_log_file_name = NULL; } - + + if (trx->mysql_master_log_file_name[0] != '\0') { + /* This database server is a MySQL replication slave */ + trx_sys_update_mysql_binlog_offset( + trx->mysql_master_log_file_name, + trx->mysql_master_log_pos, + TRX_SYS_MYSQL_MASTER_LOG_INFO, &mtr); + } + /* If we did not take the shortcut, the following call commits the mini-transaction, making the whole transaction committed in the file-based world at this log sequence number; @@ -707,12 +750,12 @@ trx_commit_off_kernel( /*-------------------------------------*/ - /* Most MySQL users run with srv_flush.. set to FALSE: */ + /* Most MySQL users run with srv_flush_.. set to FALSE: */ if (srv_flush_log_at_trx_commit) { log_flush_up_to(lsn, LOG_WAIT_ONE_GROUP); - } + } /*-------------------------------------*/ @@ -730,6 +773,29 @@ trx_commit_off_kernel( UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx); } +/******************************************************************** +Cleans up a transaction at database startup. The cleanup is needed if +the transaction already got to the middle of a commit when the database +crashed, andf we cannot roll it back. */ + +void +trx_cleanup_at_db_startup( +/*======================*/ + trx_t* trx) /* in: transaction */ +{ + if (trx->insert_undo != NULL) { + + trx_undo_insert_cleanup(trx); + } + + trx->conc_state = TRX_NOT_STARTED; + trx->rseg = NULL; + trx->undo_no = ut_dulint_zero; + trx->last_sql_stat_start.least_undo_no = ut_dulint_zero; + + UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx); +} + /************************************************************************ Assigns a read view for a consistent read query. All the consistent reads within the same transaction will get the same read view, which is created @@ -1395,54 +1461,63 @@ own the kernel mutex. */ void trx_print( /*======*/ + char* buf, /* in/out: buffer where to print, must be at least + 500 bytes */ trx_t* trx) /* in: transaction */ { - printf("TRANSACTION %lu %lu, OS thread id %lu", + buf += sprintf(buf, "TRANSACTION %lu %lu, OS thread id %lu", ut_dulint_get_high(trx->id), ut_dulint_get_low(trx->id), (ulint)trx->mysql_thread_id); if (ut_strlen(trx->op_info) > 0) { - printf(" %s", trx->op_info); + buf += sprintf(buf, " %s", trx->op_info); } if (trx->type != TRX_USER) { - printf(" purge trx"); + buf += sprintf(buf, " purge trx"); } switch (trx->conc_state) { - case TRX_NOT_STARTED: printf(", not started"); break; - case TRX_ACTIVE: printf(", active"); break; - case TRX_COMMITTED_IN_MEMORY: printf(", committed in memory"); + case TRX_NOT_STARTED: buf += sprintf(buf, + ", not started"); break; + case TRX_ACTIVE: buf += sprintf(buf, + ", active"); break; + case TRX_COMMITTED_IN_MEMORY: buf += sprintf(buf, + ", committed in memory"); break; - default: printf(" state %lu", trx->conc_state); + default: buf += sprintf(buf, " state %lu", trx->conc_state); } switch (trx->que_state) { - case TRX_QUE_RUNNING: printf(", runs or sleeps"); break; - case TRX_QUE_LOCK_WAIT: printf(", lock wait"); break; - case TRX_QUE_ROLLING_BACK: printf(", rolling back"); break; - case TRX_QUE_COMMITTING: printf(", committing"); break; - default: printf(" que state %lu", trx->que_state); + case TRX_QUE_RUNNING: buf += sprintf(buf, + ", runs or sleeps"); break; + case TRX_QUE_LOCK_WAIT: buf += sprintf(buf, + ", lock wait"); break; + case TRX_QUE_ROLLING_BACK: buf += sprintf(buf, + ", rolling back"); break; + case TRX_QUE_COMMITTING: buf += sprintf(buf, + ", committing"); break; + default: buf += sprintf(buf, " que state %lu", trx->que_state); } if (0 < UT_LIST_GET_LEN(trx->trx_locks)) { - printf(", has %lu lock struct(s)", + buf += sprintf(buf, ", has %lu lock struct(s)", UT_LIST_GET_LEN(trx->trx_locks)); } if (trx->has_search_latch) { - printf(", holds adaptive hash latch"); + buf += sprintf(buf, ", holds adaptive hash latch"); } if (ut_dulint_cmp(trx->undo_no, ut_dulint_zero) != 0) { - printf(", undo log entries %lu", + buf += sprintf(buf, ", undo log entries %lu", ut_dulint_get_low(trx->undo_no)); } - printf("\n"); + buf += sprintf(buf, "\n"); if (trx->mysql_thd != NULL) { - innobase_mysql_print_thd(trx->mysql_thd); + innobase_mysql_print_thd(buf, trx->mysql_thd); } } diff --git a/innobase/trx/trx0undo.c b/innobase/trx/trx0undo.c index aae31f3726b..6303c5bbcdd 100644 --- a/innobase/trx/trx0undo.c +++ b/innobase/trx/trx0undo.c @@ -1147,7 +1147,7 @@ trx_undo_mem_create_at_db_start( /* If the log segment is being freed, the page list is inconsistent! */ if (state == TRX_UNDO_TO_FREE) { - return(undo); + goto add_to_list; } last_addr = flst_get_last(seg_header + TRX_UNDO_PAGE_LIST, mtr); @@ -1166,7 +1166,7 @@ trx_undo_mem_create_at_db_start( undo->top_offset = rec - last_page; undo->top_undo_no = trx_undo_rec_get_undo_no(rec); } - +add_to_list: if (type == TRX_UNDO_INSERT) { if (state != TRX_UNDO_CACHED) { UT_LIST_ADD_LAST(undo_list, rseg->insert_undo_list, diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c index a1320e8b5bc..2a7643551ad 100644 --- a/innobase/ut/ut0mem.c +++ b/innobase/ut/ut0mem.c @@ -38,6 +38,8 @@ os_fast_mutex_t ut_list_mutex; /* this protects the list */ ibool ut_mem_block_list_inited = FALSE; +ulint* ut_mem_null_ptr = NULL; + /************************************************************************** Initializes the mem block list at database startup. */ static @@ -83,12 +85,16 @@ ut_malloc_low( "InnoDB: Check if you should increase the swap file or\n" "InnoDB: ulimits of your operating system.\n" "InnoDB: On FreeBSD check you have compiled the OS with\n" - "InnoDB: a big enough maximum process size.\n", + "InnoDB: a big enough maximum process size.\n" + "InnoDB: We now intentionally generate a seg fault so that\n" + "InnoDB: on Linux we get a stack trace.\n", n, ut_total_allocated_memory, errno); os_fast_mutex_unlock(&ut_list_mutex); - exit(1); + /* Make an intentional seg fault so that we get a stack + trace */ + printf("%lu\n", *ut_mem_null_ptr); } if (set_to_zero) { diff --git a/innobase/ut/ut0ut.c b/innobase/ut/ut0ut.c index cd21491dcf1..c164afa0573 100644 --- a/innobase/ut/ut0ut.c +++ b/innobase/ut/ut0ut.c @@ -111,6 +111,49 @@ ut_print_timestamp( } /************************************************************** +Sprintfs a timestamp to a buffer. */ + +void +ut_sprintf_timestamp( +/*=================*/ + char* buf) /* in: buffer where to sprintf */ +{ +#ifdef __WIN__ + SYSTEMTIME cal_tm; + + GetLocalTime(&cal_tm); + + sprintf(buf, "%02d%02d%02d %2d:%02d:%02d", + (int)cal_tm.wYear % 100, + (int)cal_tm.wMonth, + (int)cal_tm.wDay, + (int)cal_tm.wHour, + (int)cal_tm.wMinute, + (int)cal_tm.wSecond); +#else + struct tm cal_tm; + struct tm* cal_tm_ptr; + time_t tm; + + time(&tm); + +#ifdef HAVE_LOCALTIME_R + localtime_r(&tm, &cal_tm); + cal_tm_ptr = &cal_tm; +#else + cal_tm_ptr = localtime(&tm); +#endif + sprintf(buf, "%02d%02d%02d %2d:%02d:%02d", + cal_tm_ptr->tm_year % 100, + cal_tm_ptr->tm_mon + 1, + cal_tm_ptr->tm_mday, + cal_tm_ptr->tm_hour, + cal_tm_ptr->tm_min, + cal_tm_ptr->tm_sec); +#endif +} + +/************************************************************** Returns current year, month, day. */ void @@ -258,3 +301,26 @@ ut_ulint_sort(ulint* arr, ulint* aux_arr, ulint low, ulint high) UT_SORT_FUNCTION_BODY(ut_ulint_sort, arr, aux_arr, low, high, ut_ulint_cmp); } + +/***************************************************************** +Calculates fast the number rounded up to the nearest power of 2. */ + +ulint +ut_2_power_up( +/*==========*/ + /* out: first power of 2 which is >= n */ + ulint n) /* in: number != 0 */ +{ + ulint res; + + res = 1; + + ut_ad(n > 0); + + while (res < n) { + res = res * 2; + } + + return(res); +} + diff --git a/isam/create.c b/isam/create.c index 1fc2f3b97be..4c23f3edd11 100644 --- a/isam/create.c +++ b/isam/create.c @@ -294,13 +294,13 @@ int nisam_create(const char *name,uint keys,N_KEYDEF *keyinfo, goto err; /* Enlarge files */ - if (my_chsize(file,(ulong) share.base.keystart,MYF(0))) + if (my_chsize(file, (ulong) share.base.keystart, 0, MYF(0))) goto err; if (! (flags & HA_DONT_TOUCH_DATA)) { #ifdef USE_RELOC - if (my_chsize(dfile,share.base.min_pack_length*reloc,MYF(0))) + if (my_chsize(dfile, share.base.min_pack_length*reloc, 0, MYF(0))) goto err; #endif errpos=1; diff --git a/isam/isamchk.c b/isam/isamchk.c index ea3055534ca..35b4e881962 100644 --- a/isam/isamchk.c +++ b/isam/isamchk.c @@ -1552,7 +1552,7 @@ my_string name; { VOID(fputs(" \r",stdout)); VOID(fflush(stdout)); } - if (my_chsize(share->kfile,share->state.key_file_length,MYF(0))) + if (my_chsize(share->kfile, share->state.key_file_length, 0, MYF(0))) { print_warning("Can't change size of indexfile, error: %d",my_errno); goto err; @@ -2514,10 +2514,10 @@ my_string name; skr=share->base.reloc*share->base.min_pack_length; #endif if (skr != sort_info.filelength) - if (my_chsize(info->dfile,skr,MYF(0))) + if (my_chsize(info->dfile, skr, 0, MYF(0))) print_warning("Can't change size of datafile, error: %d",my_errno); } - if (my_chsize(share->kfile,share->state.key_file_length,MYF(0))) + if (my_chsize(share->kfile, share->state.key_file_length, 0, MYF(0))) print_warning("Can't change size of indexfile, error: %d",my_errno); if (!(testflag & T_SILENT)) diff --git a/isam/pack_isam.c b/isam/pack_isam.c index a08f710c89b..08cae65ef2c 100644 --- a/isam/pack_isam.c +++ b/isam/pack_isam.c @@ -284,9 +284,10 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright (C) 1994-2000 TcX AB & Monty Program KB & Detron HB."); - puts("This is not free software. You must have a licence to use this program"); - puts("This software comes with ABSOLUTELY NO WARRANTY\n"); + puts("Copyright (C) 2002 MySQL AB"); + puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,"); + puts("and you are welcome to modify and redistribute it under the GPL license\n"); + puts("Pack a ISAM-table to take much smaller space"); puts("Keys are not updated, so you must run isamchk -rq on any table"); puts("that has keys after you have compressed it"); @@ -1958,7 +1959,7 @@ static void save_state(N_INFO *isam_file,MRG_INFO *mrg,my_off_t new_length, isam_file->update|=(HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); isam_file->this_uniq=crc; /* Save crc here */ share->changed=1; /* Force write of header */ - VOID(my_chsize(share->kfile,share->state.key_file_length, + VOID(my_chsize(share->kfile, share->state.key_file_length, 0, MYF(0))); if (share->state.keys != share->base.keys) isamchk_neaded=1; diff --git a/libmysql/manager.c b/libmysql/manager.c index a38c7fe1cd7..22b109caea8 100644 --- a/libmysql/manager.c +++ b/libmysql/manager.c @@ -90,6 +90,7 @@ MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con, char msg_buf[MAX_MYSQL_MANAGER_MSG]; int msg_len; Vio* vio; + my_bool not_used; if (!host) host="localhost"; @@ -110,7 +111,7 @@ MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con, strmov(con->last_error,"Cannot create network I/O object"); goto err; } - vio_blocking(vio,TRUE); + vio_blocking(vio, TRUE, ¬_used); my_net_init(&con->net,vio); bzero((char*) &sock_addr,sizeof(sock_addr)); sock_addr.sin_family = AF_INET; diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index d461c46d604..8922b8326d3 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -459,17 +459,18 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups) /* Setup log files */ if (opt_log) - open_log(&mysql_log, glob_hostname, opt_logname, ".log", LOG_NORMAL); + open_log(&mysql_log, glob_hostname, opt_logname, ".log", NullS, + LOG_NORMAL); if (opt_update_log) { open_log(&mysql_update_log, glob_hostname, opt_update_logname, "", - LOG_NEW); + NullS, LOG_NEW); using_update_log=1; } if (opt_slow_log) open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log", - LOG_NORMAL); + NullS, LOG_NORMAL); if (ha_init()) { sql_print_error("Can't init databases"); @@ -532,9 +533,8 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups) strmov(strcend(tmp,'.'),"-bin"); opt_bin_logname=my_strdup(tmp,MYF(MY_WME)); } - mysql_bin_log.set_index_file_name(opt_binlog_index_name); open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin", - LOG_BIN); + opt_binlog_index_name, LOG_BIN); using_update_log=1; } diff --git a/myisam/mi_cache.c b/myisam/mi_cache.c index d392a9cc916..462e48b3532 100644 --- a/myisam/mi_cache.c +++ b/myisam/mi_cache.c @@ -72,8 +72,8 @@ int _mi_read_cache(IO_CACHE *info, byte *buff, my_off_t pos, uint length, in_buff_length=0; if (flag & READING_NEXT || info->share) { - if (pos != (info->pos_in_file + (uint) (info->read_end - - info->request_pos))) + if (pos != (info->pos_in_file + + (uint) (info->read_end - info->request_pos))) { info->pos_in_file=pos; /* Force start here */ info->read_pos=info->read_end=info->request_pos; /* Everything used */ diff --git a/myisam/mi_check.c b/myisam/mi_check.c index b3fc0d4a296..0ae700df8c2 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -1257,7 +1257,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, { VOID(fputs(" \r",stdout)); VOID(fflush(stdout)); } - if (my_chsize(share->kfile,info->state->key_file_length,MYF(0))) + if (my_chsize(share->kfile,info->state->key_file_length,0,MYF(0))) { mi_check_print_warning(param, "Can't change size of indexfile, error: %d", @@ -2026,7 +2026,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, skr=share->base.reloc*share->base.min_pack_length; #endif if (skr != sort_info.filelength && !info->s->base.raid_type) - if (my_chsize(info->dfile,skr,MYF(0))) + if (my_chsize(info->dfile,skr,0,MYF(0))) mi_check_print_warning(param, "Can't change size of datafile, error: %d", my_errno); @@ -2034,7 +2034,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, if (param->testflag & T_CALC_CHECKSUM) share->state.checksum=param->glob_crc; - if (my_chsize(share->kfile,info->state->key_file_length,MYF(0))) + if (my_chsize(share->kfile,info->state->key_file_length,0,MYF(0))) mi_check_print_warning(param, "Can't change size of indexfile, error: %d", my_errno); @@ -2411,7 +2411,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, skr=share->base.reloc*share->base.min_pack_length; #endif if (skr != sort_info.filelength && !info->s->base.raid_type) - if (my_chsize(info->dfile,skr,MYF(0))) + if (my_chsize(info->dfile,skr,0,MYF(0))) mi_check_print_warning(param, "Can't change size of datafile, error: %d", my_errno); @@ -2419,7 +2419,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, if (param->testflag & T_CALC_CHECKSUM) share->state.checksum=param->glob_crc; - if (my_chsize(share->kfile,info->state->key_file_length,MYF(0))) + if (my_chsize(share->kfile,info->state->key_file_length,0,MYF(0))) mi_check_print_warning(param, "Can't change size of indexfile, error: %d", my_errno); diff --git a/myisam/mi_create.c b/myisam/mi_create.c index c87607ee5b6..2202587702b 100644 --- a/myisam/mi_create.c +++ b/myisam/mi_create.c @@ -616,13 +616,13 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, #endif /* Enlarge files */ - if (my_chsize(file,(ulong) share.base.keystart,MYF(0))) + if (my_chsize(file,(ulong) share.base.keystart,0,MYF(0))) goto err; if (! (flags & HA_DONT_TOUCH_DATA)) { #ifdef USE_RELOC - if (my_chsize(dfile,share.base.min_pack_length*ci->reloc_rows,MYF(0))) + if (my_chsize(dfile,share.base.min_pack_length*ci->reloc_rows,0,MYF(0))) goto err; #endif errpos=2; diff --git a/myisam/mi_delete_all.c b/myisam/mi_delete_all.c index 82cf9e7a406..58f885b63f0 100644 --- a/myisam/mi_delete_all.c +++ b/myisam/mi_delete_all.c @@ -50,7 +50,7 @@ int mi_delete_all_rows(MI_INFO *info) myisam_log_command(MI_LOG_DELETE_ALL,info,(byte*) 0,0,0); VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE)); - if (my_chsize(info->dfile, 0, MYF(MY_WME))) + if (my_chsize(info->dfile, 0, 0, MYF(MY_WME))) goto err; allow_break(); /* Allow SIGHUP & SIGINT */ DBUG_RETURN(0); diff --git a/myisam/myisampack.c b/myisam/myisampack.c index 14fde9aa8b3..cf0448a9062 100644 --- a/myisam/myisampack.c +++ b/myisam/myisampack.c @@ -2046,7 +2046,7 @@ static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length, share->changed=1; /* Force write of header */ share->state.open_count=0; share->global_changed=0; - VOID(my_chsize(share->kfile,share->state.state.key_file_length, + VOID(my_chsize(share->kfile, share->state.state.key_file_length, 0, MYF(0))); if (share->base.keys) isamchk_neaded=1; diff --git a/myisammrg/myrg_rnext.c b/myisammrg/myrg_rnext.c index 20c73877b77..6d657b5926c 100644 --- a/myisammrg/myrg_rnext.c +++ b/myisammrg/myrg_rnext.c @@ -26,7 +26,7 @@ int myrg_rnext(MYRG_INFO *info, byte *buf, int inx) MI_INFO *mi; if (!info->current_table) - return HA_ERR_KEY_NOT_FOUND; + return (HA_ERR_KEY_NOT_FOUND); /* at first, do rnext for the table found before */ if ((err=mi_rnext(info->current_table->table,NULL,inx))) diff --git a/myisammrg/myrg_rprev.c b/myisammrg/myrg_rprev.c index e6d0283ccb3..c21ca06dacd 100644 --- a/myisammrg/myrg_rprev.c +++ b/myisammrg/myrg_rprev.c @@ -26,7 +26,7 @@ int myrg_rprev(MYRG_INFO *info, byte *buf, int inx) MI_INFO *mi; if (!info->current_table) - return HA_ERR_KEY_NOT_FOUND; + return (HA_ERR_KEY_NOT_FOUND); /* at first, do rprev for the table found before */ if ((err=mi_rprev(info->current_table->table,NULL,inx))) diff --git a/mysql-test/include/master-slave.inc b/mysql-test/include/master-slave.inc index 23392690239..474b1357e9e 100644 --- a/mysql-test/include/master-slave.inc +++ b/mysql-test/include/master-slave.inc @@ -7,6 +7,7 @@ connection slave; !slave stop; @r/slave-stopped.result show status like 'Slave_running'; connection master; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; connection slave; reset slave; @@ -14,3 +15,6 @@ reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; slave start; @r/slave-running.result show status like 'Slave_running'; + +# Set the default connection to 'master' +connection master; diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 66bc7f5069b..85cdc11eda9 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -234,6 +234,10 @@ while test $# -gt 0; do --skip-rpl) NO_SLAVE=1 ;; --skip-test=*) SKIP_TEST=`$ECHO "$1" | $SED -e "s;--skip-test=;;"`;; --do-test=*) DO_TEST=`$ECHO "$1" | $SED -e "s;--do-test=;;"`;; + --warnings | --log-warnings) + EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --log-warnings" + EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --log-warnings" + ;; --wait-timeout=*) START_WAIT_TIMEOUT=`$ECHO "$1" | $SED -e "s;--wait-timeout=;;"` STOP_WAIT_TIMEOUT=$START_WAIT_TIMEOUT;; @@ -456,10 +460,6 @@ XTERM=`which xterm` #++ # Function Definitions #-- -wait_for_server_start () -{ - $MYSQLADMIN --no-defaults -u $DBUSER --silent -O connect_timeout=10 -w2 --host=$hostname --port=$1 ping >/dev/null 2>&1 -} prompt_user () { @@ -845,7 +845,7 @@ start_slave() master_info="--master-user=root \ --master-connect-retry=1 \ --master-host=127.0.0.1 \ - --master-password= \ + --master-password="" \ --master-port=$MASTER_MYPORT \ --server-id=$slave_server_id --rpl-recovery-rank=$slave_rpl_rank" else diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index a1eff07f4d5..b27cbb46210 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -19,25 +19,27 @@ insert into t1 values (0,"mysql a"); insert into t1 values (0,"r1manic"); insert into t1 values (0,"r1man"); drop table t1; -create table t1 (a int not null auto_increment, primary key (a), t timestamp, c char(10) default "hello"); -insert into t1 values (default,default,default), (default,default,default), (4,0,"a"),(default,default,default); -select a,t>0,c from t1; -a t>0 c -1 1 hello -2 1 hello -4 0 a -5 1 hello +create table t1 (a int not null auto_increment, primary key (a), t timestamp, c char(10) default "hello", i int); +insert into t1 values (default,default,default,default), (default,default,default,default), (4,0,"a",5),(default,default,default,default); +select a,t>0,c,i from t1; +a t>0 c i +1 1 hello NULL +2 1 hello NULL +4 0 a 5 +5 1 hello NULL truncate table t1; insert into t1 set a=default,t=default,c=default; -insert into t1 set a=default,t=default,c=default; -insert into t1 set a=4,t=0,c="a"; -insert into t1 set a=default,t=default,c=default; -select a,t>0,c from t1; -a t>0 c -1 1 hello -2 1 hello -4 0 a -5 1 hello +insert into t1 set a=default,t=default,c=default,i=default; +insert into t1 set a=4,t=0,c="a",i=5; +insert into t1 set a=5,t=0,c="a",i=null; +insert into t1 set a=default,t=default,c=default,i=default; +select a,t>0,c,i from t1; +a t>0 c i +1 1 hello NULL +2 1 hello NULL +4 0 a 5 +5 0 a NULL +6 1 hello NULL drop table t1; drop database if exists foo; create database foo; diff --git a/mysql-test/r/rpl000001.result b/mysql-test/r/rpl000001.result index 2c36df65ca9..2dc21e86152 100644 --- a/mysql-test/r/rpl000001.result +++ b/mysql-test/r/rpl000001.result @@ -1,10 +1,10 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; slave start; -use test; -drop table if exists t1,t3; +drop table if exists t1,t2,t3; create table t1 (word char(20) not null); load data infile '../../std_data/words.dat' into table t1; load data local infile 'MYSQL_TEST_DIR/std_data/words.dat' into table t1; @@ -30,11 +30,12 @@ abandoned abandoning abandonment abandons +slave stop; set password for root@"localhost" = password('foo'); +slave start; set password for root@"localhost" = password(''); create table t3(n int); insert into t3 values(1),(2); -use test; select * from t3; n 1 @@ -46,7 +47,6 @@ drop table t1,t3; reset master; slave stop; reset slave; -drop table if exists t1,t2; create table t1(n int); select get_lock("hold_slave",10); get_lock("hold_slave",10) @@ -58,8 +58,8 @@ release_lock("hold_slave") unlock tables; create table t2(id int); insert into t2 values(connection_id()); -create temporary table t1_temp(n int); -insert into t1_temp select get_lock('crash_lock%20C', 1) from t2; +create temporary table t3(n int); +insert into t3 select get_lock('crash_lock%20C', 1) from t2; update t1 set n = n + get_lock('crash_lock%20C', 2); select (@id := id) - id from t2; (@id := id) - id @@ -75,17 +75,15 @@ count(*) drop table t1; create table t1 (n int); insert into t1 values(3456); -use mysql; -insert into user (Host, User, Password) +insert into mysql.user (Host, User, Password) VALUES ("10.10.10.%", "blafasel2", password("blafasel2")); select select_priv,user from mysql.user where user = 'blafasel2'; select_priv user N blafasel2 -update user set Select_priv = "Y" where User="blafasel2"; +update mysql.user set Select_priv = "Y" where User="blafasel2"; select select_priv,user from mysql.user where user = 'blafasel2'; select_priv user Y blafasel2 -use test; select n from t1; n 3456 diff --git a/mysql-test/r/rpl000002.result b/mysql-test/r/rpl000002.result index 88228321897..4c2b3bdfde6 100644 --- a/mysql-test/r/rpl000002.result +++ b/mysql-test/r/rpl000002.result @@ -1,14 +1,13 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; slave start; -use test; drop table if exists t1; create table t1 (n int auto_increment primary key); set insert_id = 2000; insert into t1 values (NULL),(NULL),(NULL); -use test; select * from t1; n 2000 @@ -16,7 +15,7 @@ n 2002 show slave hosts; Server_id Host Port Rpl_recovery_rank Master_id -2 127.0.0.1 $SLAVE_MYPORT 2 1 +2 127.0.0.1 9999 2 1 drop table t1; slave stop; drop table if exists t2; diff --git a/mysql-test/r/rpl000003.result b/mysql-test/r/rpl000003.result index eb64d1855b1..b123b3d98c5 100644 --- a/mysql-test/r/rpl000003.result +++ b/mysql-test/r/rpl000003.result @@ -1,4 +1,5 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/r/rpl000004.result b/mysql-test/r/rpl000004.result index e5dee880f73..82b208d0b58 100644 --- a/mysql-test/r/rpl000004.result +++ b/mysql-test/r/rpl000004.result @@ -1,9 +1,9 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; slave start; -use test; set SQL_LOG_BIN=0; drop table if exists t1; create table t1 (word char(20) not null, index(word)); @@ -12,7 +12,6 @@ drop table if exists t2; create table t2 (word char(20) not null); load data infile '../../std_data/words.dat' into table t2; create table t3 (word char(20) not null primary key); -use test; drop table if exists t1; load table t1 from master; drop table if exists t2; diff --git a/mysql-test/r/rpl000005.result b/mysql-test/r/rpl000005.result index 0c91f984db1..3e9028bf2cf 100644 --- a/mysql-test/r/rpl000005.result +++ b/mysql-test/r/rpl000005.result @@ -1,4 +1,5 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/r/rpl000006.result b/mysql-test/r/rpl000006.result index f4e965236af..e7fc5151ac4 100644 --- a/mysql-test/r/rpl000006.result +++ b/mysql-test/r/rpl000006.result @@ -1,4 +1,5 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/r/rpl000007.result b/mysql-test/r/rpl000007.result index 7b2b9939228..c2823bf1203 100644 --- a/mysql-test/r/rpl000007.result +++ b/mysql-test/r/rpl000007.result @@ -1,13 +1,12 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; slave start; -use test; drop table if exists foo; create table foo (n int); insert into foo values(4); -use test; drop table if exists foo; create table foo (s char(20)); load data infile '../../std_data/words.dat' into table foo; diff --git a/mysql-test/r/rpl000008.result b/mysql-test/r/rpl000008.result index 5ca156fecf0..a0230d55702 100644 --- a/mysql-test/r/rpl000008.result +++ b/mysql-test/r/rpl000008.result @@ -1,4 +1,5 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/r/rpl000009.result b/mysql-test/r/rpl000009.result index 5246dadc06b..afd566c366c 100644 --- a/mysql-test/r/rpl000009.result +++ b/mysql-test/r/rpl000009.result @@ -1,4 +1,5 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/r/rpl000010.result b/mysql-test/r/rpl000010.result index 95792a72a6d..49538ed148e 100644 --- a/mysql-test/r/rpl000010.result +++ b/mysql-test/r/rpl000010.result @@ -1,4 +1,5 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/r/rpl000011.result b/mysql-test/r/rpl000011.result index 1a46f479677..5d22c29bdba 100644 --- a/mysql-test/r/rpl000011.result +++ b/mysql-test/r/rpl000011.result @@ -1,9 +1,9 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; slave start; -use test; drop table if exists t1; create table t1 (n int); insert into t1 values(1); diff --git a/mysql-test/r/rpl000012.result b/mysql-test/r/rpl000012.result index c7f3ab8f578..45de6502bbd 100644 --- a/mysql-test/r/rpl000012.result +++ b/mysql-test/r/rpl000012.result @@ -1,4 +1,5 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/r/rpl000013.result b/mysql-test/r/rpl000013.result index 5e4b4159e3a..9e802da59c5 100644 --- a/mysql-test/r/rpl000013.result +++ b/mysql-test/r/rpl000013.result @@ -1,4 +1,5 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/r/rpl000014.result b/mysql-test/r/rpl000014.result index c9926c92a4f..8e0dfc3a117 100644 --- a/mysql-test/r/rpl000014.result +++ b/mysql-test/r/rpl000014.result @@ -1,4 +1,5 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; @@ -8,7 +9,7 @@ File Position Binlog_do_db Binlog_ignore_db master-bin.001 79 show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.001 79 slave-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 128 +127.0.0.1 root MASTER_PORT 1 master-bin.001 79 slave-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 124 change master to master_log_pos=73; slave stop; change master to master_log_pos=73; diff --git a/mysql-test/r/rpl_alter.result b/mysql-test/r/rpl_alter.result index 2e42177c140..1dc73c6524a 100644 --- a/mysql-test/r/rpl_alter.result +++ b/mysql-test/r/rpl_alter.result @@ -1,9 +1,9 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; slave start; -use test; drop database if exists d1; create database d1; create table d1.t1 ( n int); diff --git a/mysql-test/r/rpl_compat.result b/mysql-test/r/rpl_compat.result deleted file mode 100644 index 5e497791771..00000000000 --- a/mysql-test/r/rpl_compat.result +++ /dev/null @@ -1,77 +0,0 @@ -slave stop; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -slave start; -use test; -drop table if exists t1,t3; -create table t1 (word char(20) not null); -load data infile '../../std_data/words.dat' into table t1; -select * from t1; -word -Aarhus -Aaron -Ababa -aback -abaft -abandon -abandoned -abandoning -abandonment -abandons -set password for root@"localhost" = password('foo'); -set password for root@"localhost" = password(''); -create table t3(n int); -insert into t3 values(1),(2); -use test; -select * from t3; -n -1 -2 -select sum(length(word)) from t1; -sum(length(word)) -71 -drop table t1,t3; -reset master; -slave stop; -reset slave; -create table t1(n int); -insert into t1 values (1),(2),(3); -create table t2(id int); -insert into t2 values(connection_id()); -create temporary table t1_temp(n int); -insert into t1_temp select get_lock('crash_lock%20C', 1) from t2; - update t1 set n = n + get_lock('crash_lock%20C', 2); -select (@id := id) - id from t2; -(@id := id) - id -0 -kill @id; -drop table t2; -Server shutdown in progress -slave start; -set sql_slave_skip_counter=1; -slave start; -select count(*) from t1; -count(*) -3 -drop table t1; -create table t1 (n int); -insert into t1 values(3456); -use mysql; -insert into user (Host, User, Password) -VALUES ("10.10.10.%", "blafasel2", password("blafasel2")); -select select_priv,user from mysql.user where user = 'blafasel2'; -select_priv user -N blafasel2 -update user set Select_priv = "Y" where User="blafasel2"; -select select_priv,user from mysql.user where user = 'blafasel2'; -select_priv user -Y blafasel2 -use test; -select n from t1; -n -3456 -select select_priv,user from mysql.user where user = 'blafasel2'; -select_priv user -Y blafasel2 -drop table t1; diff --git a/mysql-test/r/rpl_empty_master_crash.result b/mysql-test/r/rpl_empty_master_crash.result index 6ae5d15031b..66e28b32312 100644 --- a/mysql-test/r/rpl_empty_master_crash.result +++ b/mysql-test/r/rpl_empty_master_crash.result @@ -1,9 +1,9 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; slave start; -use test; drop table if exists t1; show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space diff --git a/mysql-test/r/rpl_get_lock.result b/mysql-test/r/rpl_get_lock.result index cfbf4351f32..a8e602be03f 100644 --- a/mysql-test/r/rpl_get_lock.result +++ b/mysql-test/r/rpl_get_lock.result @@ -1,4 +1,5 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result index f5885085dee..8948460e1bd 100644 --- a/mysql-test/r/rpl_log.result +++ b/mysql-test/r/rpl_log.result @@ -1,4 +1,5 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; @@ -75,7 +76,7 @@ slave-bin.002 115 Query 1 62 use test; insert into t1 values (1) slave-bin.002 175 Query 1 122 use test; drop table t1 show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.002 170 slave-relay-bin.002 916 master-bin.002 Yes Yes 0 0 170 924 +127.0.0.1 root MASTER_PORT 1 master-bin.002 170 slave-relay-bin.002 916 master-bin.002 Yes Yes 0 0 170 920 show new master for slave with master_log_file='master-bin.001' and master_log_pos=4 and master_server_id=1; Log_name Log_pos diff --git a/mysql-test/r/rpl_magic.result b/mysql-test/r/rpl_magic.result index b30d40d04eb..743bef4a053 100644 --- a/mysql-test/r/rpl_magic.result +++ b/mysql-test/r/rpl_magic.result @@ -1,4 +1,5 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/r/rpl_mystery22.result b/mysql-test/r/rpl_mystery22.result index e798d774380..5dd665fe9d5 100644 --- a/mysql-test/r/rpl_mystery22.result +++ b/mysql-test/r/rpl_mystery22.result @@ -1,5 +1,5 @@ -drop table if exists t1; slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/r/rpl_skip_error.result b/mysql-test/r/rpl_skip_error.result index 9fe92292178..946d64ad7c5 100644 --- a/mysql-test/r/rpl_skip_error.result +++ b/mysql-test/r/rpl_skip_error.result @@ -1,4 +1,5 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/r/rpl_sporadic_master.result b/mysql-test/r/rpl_sporadic_master.result index ca74904889b..52c9cc41ed5 100644 --- a/mysql-test/r/rpl_sporadic_master.result +++ b/mysql-test/r/rpl_sporadic_master.result @@ -1,4 +1,5 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test index 85798ec57f6..2c912d94c70 100644 --- a/mysql-test/t/insert.test +++ b/mysql-test/t/insert.test @@ -27,15 +27,16 @@ drop table t1; # Test insert syntax # -create table t1 (a int not null auto_increment, primary key (a), t timestamp, c char(10) default "hello"); -insert into t1 values (default,default,default), (default,default,default), (4,0,"a"),(default,default,default); -select a,t>0,c from t1; +create table t1 (a int not null auto_increment, primary key (a), t timestamp, c char(10) default "hello", i int); +insert into t1 values (default,default,default,default), (default,default,default,default), (4,0,"a",5),(default,default,default,default); +select a,t>0,c,i from t1; truncate table t1; insert into t1 set a=default,t=default,c=default; -insert into t1 set a=default,t=default,c=default; -insert into t1 set a=4,t=0,c="a"; -insert into t1 set a=default,t=default,c=default; -select a,t>0,c from t1; +insert into t1 set a=default,t=default,c=default,i=default; +insert into t1 set a=4,t=0,c="a",i=5; +insert into t1 set a=5,t=0,c="a",i=null; +insert into t1 set a=default,t=default,c=default,i=default; +select a,t>0,c,i from t1; drop table t1; # diff --git a/mysql-test/t/rpl000001.test b/mysql-test/t/rpl000001.test index 6d46124d238..fb4255f27b3 100644 --- a/mysql-test/t/rpl000001.test +++ b/mysql-test/t/rpl000001.test @@ -1,21 +1,34 @@ -eval_result; source include/master-slave.inc; -connection master; -use test; -drop table if exists t1,t3; +drop table if exists t1,t2,t3; create table t1 (word char(20) not null); load data infile '../../std_data/words.dat' into table t1; --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR eval load data local infile '$MYSQL_TEST_DIR/std_data/words.dat' into table t1; select * from t1; + +# +# Test slave with wrong password +# +save_master_pos; +connection slave; +sync_with_master; +slave stop; +connection master; set password for root@"localhost" = password('foo'); +connection slave; +slave start; +connection master; +# Give slave time to do at last one failed connect retry +sleep 2; set password for root@"localhost" = password(''); +# Give slave time to connect (will retry every second) +sleep 2; + create table t3(n int); insert into t3 values(1),(2); save_master_pos; connection slave; sync_with_master; -use test; select * from t3; select sum(length(word)) from t1; connection master; @@ -32,7 +45,6 @@ slave stop; reset slave; connection master; -drop table if exists t1,t2; create table t1(n int); #we want the log to exceed 16K to test deal with the log that is bigger than #IO_SIZE @@ -45,12 +57,12 @@ while ($1) } enable_query_log; -#try to cause a large relay log lag on the slave +# Try to cause a large relay log lag on the slave connection slave; select get_lock("hold_slave",10); slave start; #hope this is long enough for I/O thread to fetch over 16K relay log data -sleep 1; +sleep 3; select release_lock("hold_slave"); unlock tables; @@ -59,24 +71,24 @@ create table t2(id int); insert into t2 values(connection_id()); save_master_pos; - connection master1; -#avoid generating result -create temporary table t1_temp(n int); -insert into t1_temp select get_lock('crash_lock%20C', 1) from t2; +# Avoid generating result +create temporary table t3(n int); +insert into t3 select get_lock('crash_lock%20C', 1) from t2; connection master; send update t1 set n = n + get_lock('crash_lock%20C', 2); connection master1; -sleep 2; +sleep 3; select (@id := id) - id from t2; kill @id; +# We don't drop t3 as this is a temporary table drop table t2; connection master; --error 1053; reap; connection slave; -sync_with_master ; +sync_with_master; #give the slave a chance to exit wait_for_slave_to_stop; @@ -92,13 +104,11 @@ connection master1; drop table t1; create table t1 (n int); insert into t1 values(3456); -use mysql; -insert into user (Host, User, Password) +insert into mysql.user (Host, User, Password) VALUES ("10.10.10.%", "blafasel2", password("blafasel2")); select select_priv,user from mysql.user where user = 'blafasel2'; -update user set Select_priv = "Y" where User="blafasel2"; +update mysql.user set Select_priv = "Y" where User="blafasel2"; select select_priv,user from mysql.user where user = 'blafasel2'; -use test; save_master_pos; connection slave; sync_with_master; @@ -109,5 +119,3 @@ drop table t1; save_master_pos; connection slave; sync_with_master; - - diff --git a/mysql-test/t/rpl000002.test b/mysql-test/t/rpl000002.test index 420ae27a337..caf0b4ef6d8 100644 --- a/mysql-test/t/rpl000002.test +++ b/mysql-test/t/rpl000002.test @@ -1,17 +1,14 @@ source include/master-slave.inc; -eval_result; -connection master; -use test; drop table if exists t1; create table t1 (n int auto_increment primary key); set insert_id = 2000; insert into t1 values (NULL),(NULL),(NULL); save_master_pos; connection slave; -use test; sync_with_master; select * from t1; connection master; +--replace_result $SLAVE_MYPORT 9999 show slave hosts; drop table t1; save_master_pos; diff --git a/mysql-test/t/rpl000003.test b/mysql-test/t/rpl000003.test index c4b120d31b0..f994ed94371 100644 --- a/mysql-test/t/rpl000003.test +++ b/mysql-test/t/rpl000003.test @@ -1,5 +1,4 @@ source include/master-slave.inc; -connection master; drop table if exists t1; create table t1(n int primary key); !insert into t1 values (1),(2),(2); diff --git a/mysql-test/t/rpl000004.test b/mysql-test/t/rpl000004.test index 5b2c41293a2..705e0d51b7b 100644 --- a/mysql-test/t/rpl000004.test +++ b/mysql-test/t/rpl000004.test @@ -1,6 +1,4 @@ source include/master-slave.inc; -connection master; -use test; set SQL_LOG_BIN=0; drop table if exists t1; create table t1 (word char(20) not null, index(word)); @@ -10,7 +8,6 @@ create table t2 (word char(20) not null); load data infile '../../std_data/words.dat' into table t2; create table t3 (word char(20) not null primary key); connection slave; -use test; drop table if exists t1; load table t1 from master; drop table if exists t2; diff --git a/mysql-test/t/rpl000005.test b/mysql-test/t/rpl000005.test index 92d954a6182..1cfea242b69 100644 --- a/mysql-test/t/rpl000005.test +++ b/mysql-test/t/rpl000005.test @@ -1,5 +1,4 @@ source include/master-slave.inc; -connection master; drop table if exists t1; CREATE TABLE t1 (name varchar(64), age smallint(3)); INSERT INTO t1 SET name='Andy', age=31; diff --git a/mysql-test/t/rpl000006.test b/mysql-test/t/rpl000006.test index 495f34bd5e7..ad8622c2a81 100644 --- a/mysql-test/t/rpl000006.test +++ b/mysql-test/t/rpl000006.test @@ -2,7 +2,6 @@ # Test forced timestamp # source include/master-slave.inc; -connection master; # Don't log table creating to the slave as we want to test LOAD TABLE set SQL_LOG_BIN=0,timestamp=200006; diff --git a/mysql-test/t/rpl000007.test b/mysql-test/t/rpl000007.test index 4425a5725e8..8ff1e1782cc 100644 --- a/mysql-test/t/rpl000007.test +++ b/mysql-test/t/rpl000007.test @@ -2,12 +2,10 @@ #the ones on bar source include/master-slave.inc; connection slave; -use test; drop table if exists foo; create table foo (n int); insert into foo values(4); connection master; -use test; drop table if exists foo; create table foo (s char(20)); load data infile '../../std_data/words.dat' into table foo; diff --git a/mysql-test/t/rpl000009.test b/mysql-test/t/rpl000009.test index d45fe0870ff..3d0827718ec 100644 --- a/mysql-test/t/rpl000009.test +++ b/mysql-test/t/rpl000009.test @@ -2,7 +2,6 @@ # the ones in database bar source include/master-slave.inc; -connection master; drop database if exists foo; create database foo; drop database if exists bar; diff --git a/mysql-test/t/rpl000011.test b/mysql-test/t/rpl000011.test index 7d99222b3c7..d75937e3f81 100644 --- a/mysql-test/t/rpl000011.test +++ b/mysql-test/t/rpl000011.test @@ -1,6 +1,4 @@ source include/master-slave.inc; -connection master; -use test; drop table if exists t1; create table t1 (n int); insert into t1 values(1); diff --git a/mysql-test/t/rpl000013.test b/mysql-test/t/rpl000013.test index a190d5324ae..14619796e01 100644 --- a/mysql-test/t/rpl000013.test +++ b/mysql-test/t/rpl000013.test @@ -1,5 +1,4 @@ source include/master-slave.inc; -connection master; save_master_pos; connection slave; sync_with_master; diff --git a/mysql-test/t/rpl000014.test b/mysql-test/t/rpl000014.test index df15fa6e600..0b75314ee6a 100644 --- a/mysql-test/t/rpl000014.test +++ b/mysql-test/t/rpl000014.test @@ -1,5 +1,4 @@ source include/master-slave.inc; -connection master; show master status; save_master_pos; connection slave; diff --git a/mysql-test/t/rpl_alter.test b/mysql-test/t/rpl_alter.test index a65605f703e..710dd2d09d6 100644 --- a/mysql-test/t/rpl_alter.test +++ b/mysql-test/t/rpl_alter.test @@ -1,6 +1,4 @@ source include/master-slave.inc; -connection master; -use test; drop database if exists d1; create database d1; create table d1.t1 ( n int); diff --git a/mysql-test/t/rpl_compat.test b/mysql-test/t/rpl_compat.test deleted file mode 100644 index 9c67cce1680..00000000000 --- a/mysql-test/t/rpl_compat.test +++ /dev/null @@ -1,86 +0,0 @@ -eval_result; -source include/master-slave.inc; -connection master; -require_version 3.23; -use test; -drop table if exists t1,t3; -create table t1 (word char(20) not null); -load data infile '../../std_data/words.dat' into table t1; -select * from t1; -set password for root@"localhost" = password('foo'); -set password for root@"localhost" = password(''); -create table t3(n int); -insert into t3 values(1),(2); -save_master_pos; -connection slave; -sync_with_master; -use test; -select * from t3; -select sum(length(word)) from t1; -connection master; -drop table t1,t3; -save_master_pos; -connection slave; -sync_with_master; - -#test handling of aborted connection in the middle of update -connection master; -reset master; -connection slave; -slave stop; -reset slave; - -connection master; -create table t1(n int); -insert into t1 values (1),(2),(3); -create table t2(id int); -insert into t2 values(connection_id()); -save_master_pos; - -connection master1; -#avoid generating result -create temporary table t1_temp(n int); -insert into t1_temp select get_lock('crash_lock%20C', 1) from t2; - -connection master; -send update t1 set n = n + get_lock('crash_lock%20C', 2); -connection master1; -sleep 2; -select (@id := id) - id from t2; -kill @id; -drop table t2; -connection master; ---error 1053; -reap; -connection slave; -slave start; -sync_with_master ; -#now slave will hit an error -wait_for_slave_to_stop; - -set global sql_slave_skip_counter=1; -slave start; -select count(*) from t1; -connection master1; -drop table t1; -create table t1 (n int); -insert into t1 values(3456); -use mysql; -insert into user (Host, User, Password) - VALUES ("10.10.10.%", "blafasel2", password("blafasel2")); -select select_priv,user from mysql.user where user = 'blafasel2'; -update user set Select_priv = "Y" where User="blafasel2"; -select select_priv,user from mysql.user where user = 'blafasel2'; -use test; -save_master_pos; -connection slave; -sync_with_master; -select n from t1; -select select_priv,user from mysql.user where user = 'blafasel2'; -connection master1; -drop table t1; -save_master_pos; -connection slave; -sync_with_master; - - diff --git a/mysql-test/t/rpl_empty_master_crash.test b/mysql-test/t/rpl_empty_master_crash.test index 158b59169ee..7923a29dcf1 100644 --- a/mysql-test/t/rpl_empty_master_crash.test +++ b/mysql-test/t/rpl_empty_master_crash.test @@ -1,6 +1,4 @@ source include/master-slave.inc; -connection master; -use test; drop table if exists t1; show slave status; --error 1218 diff --git a/mysql-test/t/rpl_get_lock.test b/mysql-test/t/rpl_get_lock.test index 1d98eb16bb0..e93268e6074 100644 --- a/mysql-test/t/rpl_get_lock.test +++ b/mysql-test/t/rpl_get_lock.test @@ -1,5 +1,5 @@ source include/master-slave.inc; -connection master; + create table t1(n int); insert into t1 values(get_lock("lock",2)); dirty_close master; diff --git a/mysql-test/t/rpl_magic.test b/mysql-test/t/rpl_magic.test index 376edc301d7..c93add93d9d 100644 --- a/mysql-test/t/rpl_magic.test +++ b/mysql-test/t/rpl_magic.test @@ -1,7 +1,6 @@ source include/master-slave.inc; #first, make sure the slave has had enough time to register -connection master; save_master_pos; connection slave; sync_with_master; diff --git a/mysql-test/t/rpl_mystery22.test b/mysql-test/t/rpl_mystery22.test index e987074697b..371c5ba21ed 100644 --- a/mysql-test/t/rpl_mystery22.test +++ b/mysql-test/t/rpl_mystery22.test @@ -1,8 +1,7 @@ # test case to make slave thread get ahead by 22 bytes -drop table if exists t1; source include/master-slave.inc; -connection master; + # first, cause a duplicate key problem on the slave create table t1(n int auto_increment primary key); save_master_pos; diff --git a/mysql-test/t/rpl_skip_error.test b/mysql-test/t/rpl_skip_error.test index 3303b45c1ca..d43c59ef024 100644 --- a/mysql-test/t/rpl_skip_error.test +++ b/mysql-test/t/rpl_skip_error.test @@ -1,6 +1,6 @@ source include/master-slave.inc; -connection master; drop table if exists t1; + create table t1 (n int not null primary key); save_master_pos; connection slave; diff --git a/mysql-test/t/rpl_sporadic_master.test b/mysql-test/t/rpl_sporadic_master.test index 0487f868436..2e86b53067c 100644 --- a/mysql-test/t/rpl_sporadic_master.test +++ b/mysql-test/t/rpl_sporadic_master.test @@ -2,8 +2,8 @@ # COM_BINLOG_DUMP and additionally limits the number of events per dump source include/master-slave.inc; -connection master; drop table if exists t1,t2; + create table t2(n int); create table t1(n int not null auto_increment primary key); insert into t1 values (NULL),(NULL); diff --git a/mysys/Makefile.am b/mysys/Makefile.am index 3ca07b7b80b..646bedf9603 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -21,7 +21,10 @@ INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include -I.. -I$(srcdir) pkglib_LIBRARIES = libmysys.a LDADD = libmysys.a ../dbug/libdbug.a \ ../strings/libmystrings.a -noinst_HEADERS = mysys_priv.h my_static.h +noinst_HEADERS = mysys_priv.h my_static.h \ + my_os2cond.c my_os2dirsrch.c my_os2dirsrch.h \ + my_os2dlfcn.c my_os2file64.c my_os2mutex.c \ + my_os2thread.c my_os2tls.c libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\ mf_path.c mf_loadpath.c\ my_open.c my_create.c my_dup.c my_seek.c my_read.c \ diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index b6e721cbd57..a4bf09ef7a7 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -123,7 +123,8 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, uint min_cache; my_off_t end_of_file= ~(my_off_t) 0; DBUG_ENTER("init_io_cache"); - DBUG_PRINT("enter",("type: %d pos: %ld",(int) type, (ulong) seek_offset)); + DBUG_PRINT("enter",("cache: %lx type: %d pos: %ld", + (ulong) info, (int) type, (ulong) seek_offset)); info->file= file; info->type=type; @@ -264,8 +265,9 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type, pbool clear_cache) { DBUG_ENTER("reinit_io_cache"); - DBUG_PRINT("enter",("type: %d seek_offset: %lu clear_cache: %d", - type, (ulong) seek_offset, (int) clear_cache)); + DBUG_PRINT("enter",("cache: %lx type: %d seek_offset: %lu clear_cache: %d", + (ulong) info, type, (ulong) seek_offset, + (int) clear_cache)); /* One can't do reinit with the following types */ DBUG_ASSERT(type != READ_NET && info->type != READ_NET && @@ -283,11 +285,15 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type, { info->read_end=info->write_pos; info->end_of_file=my_b_tell(info); + info->seek_not_done=1; } else if (type == WRITE_CACHE) { if (info->type == READ_CACHE) + { info->write_end=info->write_buffer+info->buffer_length; + info->seek_not_done=1; + } info->end_of_file = ~(my_off_t) 0; } pos=info->request_pos+(seek_offset-info->pos_in_file); diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c index b19ca391672..21979b99285 100644 --- a/mysys/mf_iocache2.c +++ b/mysys/mf_iocache2.c @@ -212,6 +212,20 @@ uint my_b_gets(IO_CACHE *info, char *to, uint max_length) } +my_off_t my_b_filelength(IO_CACHE *info) +{ + if (info->type == WRITE_CACHE) + { + return my_b_tell(info); + } + else + { + info->seek_not_done=0; + return my_seek(info->file,0L,MY_SEEK_END,MYF(0)); + } +} + + /* Simple printf version. Supports '%s', '%d', '%u', "%ld" and "%lu" Used for logging in MySQL diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c index 54129f12897..06e8f159f4a 100644 --- a/mysys/my_chsize.c +++ b/mysys/my_chsize.c @@ -25,17 +25,19 @@ my_chsize() fd File descriptor new_length New file size + filler If we don't have truncate, fill up all bytes after + new_length with this character MyFlags Flags DESCRIPTION - my_chsize() truncates file if shorter, else expand with zero. + my_chsize() truncates file if shorter, else fill with the filler character RETURN VALUE 0 Ok 1 Error */ -int my_chsize(File fd, my_off_t newlength, myf MyFlags) +int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags) { DBUG_ENTER("my_chsize"); DBUG_PRINT("my",("fd: %d length: %lu MyFlags: %d",fd,(ulong) newlength, @@ -81,7 +83,7 @@ int my_chsize(File fd, my_off_t newlength, myf MyFlags) } #endif /* Full file with 0 until it's as big as requested */ - bzero(buff,IO_SIZE); + bfill(buff, IO_SIZE, filler); while (newlength-oldsize > IO_SIZE) { if (my_write(fd,(byte*) buff,IO_SIZE,MYF(MY_NABP))) diff --git a/mysys/my_os2file64.c b/mysys/my_os2file64.c index b7ee40d292e..2f41d344e32 100644 --- a/mysys/my_os2file64.c +++ b/mysys/my_os2file64.c @@ -22,6 +22,7 @@ void _OS2errno( APIRET rc); longlong _lseek64( int fd, longlong offset, int seektype); int _lock64( int fd, int locktype, my_off_t start, my_off_t length, myf MyFlags); +int _sopen64( const char *name, int oflag, int shflag, int mask); // // this class is used to define a global c++ variable, that @@ -191,8 +192,17 @@ inline _SetFileLocksL(HFILE hFile, ULONG timeout, ULONG flags) { - if (_DosSetFileLocksL) - return _DosSetFileLocksL( hFile, pflUnlock, pflLock, timeout, flags); + if (_DosSetFileLocksL) { + APIRET rc; + rc = _DosSetFileLocksL( hFile, pflUnlock, pflLock, timeout, flags); + + // on FAT/HPFS/LAN a INVALID_PARAMETER is returned, seems that + // only JFS can handle >2GB ranges. + if (rc != 87) + return rc; + + // got INVALID_PARAMETER, fallback to standard call + } FILELOCK flUnlock = { pflUnlock->lOffset, pflUnlock->lRange }; FILELOCK flLock = { pflLock->lOffset, pflLock->lRange }; @@ -254,7 +264,7 @@ int _lock64( int fd, int locktype, my_off_t start, return(-1); } -int _sopen( const char *name, int oflag, int shflag, int mask) +int sopen( const char *name, int oflag, int shflag, int mask) { int fail_errno; APIRET rc = 0; diff --git a/mysys/my_os2thread.c b/mysys/my_os2thread.c index 017ba7f316b..89a3311c10b 100644 --- a/mysys/my_os2thread.c +++ b/mysys/my_os2thread.c @@ -53,6 +53,7 @@ void win_pthread_init(void) static pthread_handler_decl(pthread_start,param) { + DBUG_ENTER("pthread_start"); pthread_handler func=((struct pthread_map *) param)->func; void *func_param=((struct pthread_map *) param)->param; my_thread_init(); /* Will always succeed in windows */ @@ -60,8 +61,10 @@ static pthread_handler_decl(pthread_start,param) win_pthread_self=((struct pthread_map *) param)->pthreadself; pthread_mutex_unlock(&THR_LOCK_thread); free((char*) param); /* Free param from create */ - pthread_exit((void*) (*func)(func_param)); - return 0; /* Safety */ + //pthread_exit((void*) (*func)(func_param)); + (*func)(func_param); + DBUG_RETURN(0); + //return 0; /* Safety */ } diff --git a/mysys/raid.cc b/mysys/raid.cc index 6196e1f1aa6..d6359dc0f93 100644 --- a/mysys/raid.cc +++ b/mysys/raid.cc @@ -75,7 +75,7 @@ #endif #include "mysys_priv.h" -#include "my_dir.h" +#include <my_dir.h> #include <m_string.h> #include <assert.h> @@ -281,7 +281,7 @@ extern "C" { DBUG_RETURN(my_close(fd, MyFlags)); } - int my_raid_chsize(File fd, my_off_t newlength, myf MyFlags) + int my_raid_chsize(File fd, my_off_t newlength, int filler, myf MyFlags) { DBUG_ENTER("my_raid_chsize"); DBUG_PRINT("enter",("Fd: %d newlength: %u MyFlags: %d", @@ -289,10 +289,10 @@ extern "C" { if (is_raid(fd)) { RaidFd *raid= (*dynamic_element(&RaidFd::_raid_map,fd,RaidFd**)); - DBUG_RETURN(raid->Chsize(fd, newlength, MyFlags)); + DBUG_RETURN(raid->Chsize(fd, newlength, filler, MyFlags)); } else - DBUG_RETURN(my_chsize(fd, newlength, MyFlags)); + DBUG_RETURN(my_chsize(fd, newlength, filler, MyFlags)); } int my_raid_rename(const char *from, const char *to, @@ -738,7 +738,7 @@ Tell(myf MyFlags) } int RaidFd:: -Chsize(File fd, my_off_t newlength, myf MyFlags) +Chsize(File fd, my_off_t newlength, int filler, myf MyFlags) { DBUG_ENTER("RaidFd::Chsize"); DBUG_PRINT("enter",("Fd: %d, newlength: %d, MyFlags: %d", @@ -752,17 +752,16 @@ Chsize(File fd, my_off_t newlength, myf MyFlags) if ( i < _this_block ) newpos = my_chsize(_fd_vector[i], _this_block * _raid_chunksize + (_rounds + 1) * - _raid_chunksize, - MyFlags); + _raid_chunksize, filler, MyFlags); else if ( i == _this_block ) newpos = my_chsize(_fd_vector[i], _this_block * _raid_chunksize + _rounds * _raid_chunksize + (newlength % _raid_chunksize), - MyFlags); + filler, MyFlags); else // this means: i > _this_block newpos = my_chsize(_fd_vector[i], _this_block * _raid_chunksize + _rounds * - _raid_chunksize, MyFlags); + _raid_chunksize, filler, MyFlags); if (newpos) DBUG_RETURN(1); } diff --git a/os2/BldLevel.RES b/os2/BldLevel.RES Binary files differnew file mode 100644 index 00000000000..302d9fc875e --- /dev/null +++ b/os2/BldLevel.RES diff --git a/os2/BldLevel.cmd b/os2/BldLevel.cmd index 2bc85a06abb..d98d8c9dfb9 100644 --- a/os2/BldLevel.cmd +++ b/os2/BldLevel.cmd @@ -4,7 +4,7 @@ REM I'm using resources for BLDLEVEL info, because VA4 linker has the bad REM feature of using versionstring content for padding files. REM To set fixpak level: -P"fixpak level" -SET MYSQL_VERSION=3.23.42 -SET MYSQL_BUILD=1 +SET MYSQL_VERSION=3.23.50 +SET MYSQL_BUILD=B1 BldLevelInf -V%MYSQL_VERSION% -N"MySQL AB, Yuri Dario" -D"MySQL %MYSQL_VERSION% for OS/2 - Build %MYSQL_BUILD%" -Len BldLevel.rc diff --git a/os2/BldLevel.rc b/os2/BldLevel.rc index fe266a25c3c..ac028379892 100644 --- a/os2/BldLevel.rc +++ b/os2/BldLevel.rc @@ -1 +1 @@ -RCDATA 1 { "@#MySQL AB, Yuri Dario:3.23.42#@##1## 10 Sep 2001 11:57:17 paperino::en::::@@MySQL 3.23.42 for OS/2 - Build 1" } +RCDATA 1 { "@#MySQL AB, Yuri Dario:3.23.50#@##1## 24 Jun 2002 22:42:20 paperino::en::::@@MySQL 3.23.50 for OS/2 - Build B1" } diff --git a/os2/ChangeLog.os2 b/os2/ChangeLog.os2 index 8f2604c0453..7957906ad7d 100644 --- a/os2/ChangeLog.os2 +++ b/os2/ChangeLog.os2 @@ -1,4 +1,25 @@ + +2002/05/02 + - now libinit is automatically called on client dll startup + +2002/01/27 + - fixed console output for get_password + +2002/01/20 + - back-ported fix for fulltext indexes (wrong report by myisamchk) + +2001/11/21 + - MySQL 3.32.42 build 3 released. + +2001/11/19 + - got GNU Readline to compile with VAC++, now console has a working + history. + +2001/11/10 + - fixed file locking on non-JFS disks; DosSetFileLocksL does not + support ranges > 2GB on non-JFS disks. + 2001/09/16 - fixed creation directory of temporary files - enabled cached list file for deleting temp open files @@ -30,4 +51,3 @@ 2001/05/19 - new TLS code, fixed parser crashes and many other problems. - fixed pthread_cond_timedwait, now handle manager expires - diff --git a/os2/Makefile.am b/os2/Makefile.am index 7e626e45cf8..9feab6d1b2c 100644 --- a/os2/Makefile.am +++ b/os2/Makefile.am @@ -16,14 +16,13 @@ ## Process this file with automake to create Makefile.in -EXTRA_DIST = BldLevel.cmd BldLevel.rc BldLevelInf.cmd ChangeLog.os2 \ - MySQL-All.icc MySQL-Client.icc MySQL-Client.irs \ - MySQL-Lib.icc MySQL-Opt.icc MySQL-ReadLine.icc \ - MySQL-Source.icc MySQL-Sql.icc MySQL-Util.icc MySQL-Util.irs \ - MySQL-binlog.icc MySQL-binlog.irs MySQL-sql.irs ReadMe.txt \ - build-all.cmd build-all.log mysql-inf.wis mysql.base \ - mysql.ih mysql.wis mysqlalt.wis readme.os2 rint.cmd rint.obj \ - rint.s +EXTRA_DIST = BldLevel.RES BldLevel.cmd BldLevel.rc \ + BldLevelInf.cmd ChangeLog.os2 MySQL-Client.icc \ + MySQL-Opt.icc MySQL-Source.icc MySQL-Sql.icc \ + MySQL-Sql.irs MySQL-Util.icc MySQL-Util.irs \ + ReadMe.txt build-all.cmd mysql-inf.wis \ + mysql.wis mysqlalt.wis rint.cmd rint.obj rint.s +SUBDIRS = include # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/os2/MySQL-All.icc b/os2/MySQL-All.icc deleted file mode 100644 index 1bd8a1dd89f..00000000000 --- a/os2/MySQL-All.icc +++ /dev/null @@ -1,13 +0,0 @@ - -// create directories -for dir in "..\\bin", "..\\lib", "..\\obj", "..\\obj\\zlib", "..\\obj\\readline" { - run "if not exist "dir" mkdir "dir -} - -// build sequence -run "vacbld MySQL-Lib.icc -showprogress=10 -showwarning" -run "vacbld MySQL-Client.icc -showprogress=10 -showwarning" -run "vacbld MySQL-Sql.icc -showprogress=10 -showwarning" - -// need only for utilities and test applications -run "vacbld MySQL-Util.icc -showprogress=10 -showwarning" diff --git a/os2/MySQL-Client.icc b/os2/MySQL-Client.icc index 7a41567f983..bc614c1c723 100644 --- a/os2/MySQL-Client.icc +++ b/os2/MySQL-Client.icc @@ -43,11 +43,13 @@ option ProjectOptions = MySQLOptions // target source files source type('cpp') "..\\client\\mysql.cc" source BldLevelInfo + option define("HAVE_STRING_H", ), define("HAVE_CONFIG_H", ) + { + source GnuReadline + } } } - option file(genobject, "..\\OBJ\\READLINE\\") - { target "..\\bin\\mysqladmin.exe" { // optimized precompiled headers @@ -59,7 +61,6 @@ option ProjectOptions = MySQLOptions source type('cpp') "..\\client\\mysqladmin.c" source BldLevelInfo } - } target "..\\bin\\mysqldump.exe" { diff --git a/os2/MySQL-Client.irs b/os2/MySQL-Client.irs deleted file mode 100644 index 4b5a9e3475a..00000000000 --- a/os2/MySQL-Client.irs +++ /dev/null @@ -1,2335 +0,0 @@ -31 Run Specifications: Version 1.1 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -39 E:\rd\mysql\vacpp-3.23.40\bin\mysql.exe -1 -0 -0 -5 Local -0 -44 E:\rd\mysql\vacpp-3.23.40\bin\mysqladmin.exe -1 -0 -0 -5 Local -0 -43 E:\rd\mysql\vacpp-3.23.40\bin\mysqldump.exe -1 -0 -0 -5 Local -0 -43 E:\rd\mysql\vacpp-3.23.40\bin\mysqlshow.exe -1 -0 -0 -5 Local -0 -45 E:\rd\mysql\vacpp-3.23.40\bin\mysqlimport.exe -1 -0 -0 -5 Local -0 -43 E:\rd\mysql\vacpp-3.23.40\bin\mysqltest.exe -1 -0 -0 -5 Local -0 diff --git a/os2/MySQL-Lib.icc b/os2/MySQL-Lib.icc deleted file mode 100644 index 51f55ed8302..00000000000 --- a/os2/MySQL-Lib.icc +++ /dev/null @@ -1,72 +0,0 @@ -// disable code inlining when building static libs -InlineCode = "no" - -// include common options -include "MySQL-Opt.icc" -include "MySQL-Source.icc" - -option ProjectOptions = MySQLOptions -{ - - option file(genobject, "..\\OBJ\\ZLIB\\") - { - target "..\\lib\\common.lib" - { - // optimized precompiled headers - option macros('global', 'yes') - { - source type('cpp') client_pch //, 'sql_string.h' - } - // target source files - source zlib - if debug_build { - source type('cpp') dbug - } - source type('cpp') heap - //source type('cpp') merge - source type('cpp') my_sys - source type('cpp') my_sys_cli - source type('cpp') my_sys_sql - source type('cpp') strings - } - } - -/* - option file(genobject, "..\\OBJ\\READLINE\\") - { - target "..\\lib\\readline.lib" - { - // optimized precompiled headers - option macros('global', 'yes') - { - source type('cpp') client_pch //, 'sql_string.h' - } - // target source files - source readline - } - } -*/ - - target "..\\lib\\myisam.lib" - { - // optimized precompiled headers - option macros('global', 'yes') - { - source type('cpp') client_pch //, 'sql_string.h' - } - // target source files - source type('cpp') myisam - } - - target "..\\lib\\isam.lib" - { - // optimized precompiled headers - option macros('global', 'yes') - { - source type('cpp') client_pch //, 'sql_string.h' - } - // target source files - source type('cpp') isam - } - -} diff --git a/os2/MySQL-Opt.icc b/os2/MySQL-Opt.icc index 7045f111d9b..56e89057862 100644 --- a/os2/MySQL-Opt.icc +++ b/os2/MySQL-Opt.icc @@ -1,6 +1,9 @@ // set to 1 to enable debug code debug_build = 0 +// set to zlib relative directory name +zlib_dir = '../../zlib-1.1.4' + // common options option BaseOptions = link(defaultlibsname, "tcpip32.lib") , link(libsearchpath, "..\\lib\\") @@ -9,6 +12,7 @@ option BaseOptions = link(defaultlibsname, "tcpip32.lib") , link(padding, no) , link(linkwithmultithreadlib, "yes") , link(linkwithsharedlib, "no") + , link(stack, 131072, 131072) , gen(initauto, "yes") , define("__MT__", ) , define("HAVE_BSD_SIGNALS", ) @@ -19,11 +23,12 @@ option BaseOptions = link(defaultlibsname, "tcpip32.lib") , define("USE_TLS", ) , lang(signedchars, yes) , incl(searchpath, "..") + , incl(searchpath, "include") , incl(searchpath, "..\\include") , incl(searchpath, "..\\my_sys") , incl(searchpath, "..\\regex") , incl(searchpath, "..\\sql") - , incl(searchpath, "..\\..\\zlib-1.1.3") + , incl(searchpath, zlib_dir) , incl(searchpath, "..\\..\\ufc") , incl(searchpath, "..\\os2") diff --git a/os2/MySQL-ReadLine.icc b/os2/MySQL-ReadLine.icc deleted file mode 100644 index 3f63b0815e6..00000000000 --- a/os2/MySQL-ReadLine.icc +++ /dev/null @@ -1,27 +0,0 @@ -// disable code inlining when building static libs -InlineCode = "no" - -// include common options -include "MySQL-Opt.icc" -include "MySQL-Source.icc" - -option ProjectOptions = MySQLOptions -{ - - - - option file(genobject, "..\\OBJ\\READLINE\\") - { - target "..\\lib\\readline.lib" - { - // optimized precompiled headers - option macros('global', 'yes') - { - source type('cpp') client_pch //, 'sql_string.h' - } - // target source files - source readline - } - } - -} diff --git a/os2/MySQL-Source.icc b/os2/MySQL-Source.icc index 134a64dc9b0..f4ac881c90e 100644 --- a/os2/MySQL-Source.icc +++ b/os2/MySQL-Source.icc @@ -30,7 +30,7 @@ group server_global_pch = 'm_string.h', 'm_ctype.h', 'myisam.h', 'myisampack.h', '.\myisam\myisamdef.h', 'sql_string.h', 'item.h', 'unireg.h', - 'field.h', 'sql_lex.h', 'sql_list.h', + 'field.h', 'sql_lex.h', 'sql_list.h', 'sql_repl.h', 'md5.h', 'sql_acl.h', 'slave.h', 'ha_myisam.h', 'procedure.h', 'sql_select.h', 'errmsg.h', 't_ctype.h', 'direct.h', @@ -57,12 +57,20 @@ group mysqlclientlib = "..\\libmysql\\violite.c" group zlib = - "..\\..\\zlib-1.1.3\\compress.c", "..\\..\\zlib-1.1.3\\crc32.c", - "..\\..\\zlib-1.1.3\\deflate.c", "..\\..\\zlib-1.1.3\\gzio.c", "..\\..\\zlib-1.1.3\\infblock.c", - "..\\..\\zlib-1.1.3\\infcodes.c", "..\\..\\zlib-1.1.3\\inffast.c", - "..\\..\\zlib-1.1.3\\inflate.c", "..\\..\\zlib-1.1.3\\inftrees.c", - "..\\..\\zlib-1.1.3\\infutil.c", "..\\..\\zlib-1.1.3\\trees.c", "..\\..\\zlib-1.1.3\\uncompr.c", - "..\\..\\zlib-1.1.3\\zutil.c", "..\\..\\zlib-1.1.3\\adler32.c" + zlib_dir "/compress.c", + zlib_dir "/crc32.c", + zlib_dir "/deflate.c", + zlib_dir "/gzio.c", + zlib_dir "/infblock.c", + zlib_dir "/infcodes.c", + zlib_dir "/inffast.c", + zlib_dir "/inflate.c", + zlib_dir "/inftrees.c", + zlib_dir "/infutil.c", + zlib_dir "/trees.c", + zlib_dir "/uncompr.c", + zlib_dir "/zutil.c", + zlib_dir "/adler32.c" group ufc = "..\\..\\ufc\\crypt.c", @@ -118,6 +126,7 @@ group sql = "..\\sql\\sql_class.cc", "..\\sql\\sql_crypt.cc", "..\\sql\\sql_db.cc", + "..\\sql\\sql_do.cc", "..\\sql\\sql_delete.cc", "..\\sql\\sql_insert.cc", "..\\sql\\sql_lex.cc", @@ -308,24 +317,32 @@ group strings = group dbug = "..\\dbug\\dbug.c", "..\\dbug\\factorial.c", "..\\dbug\\sanity.c" - group readline = "..\\readline\\bind.c", "..\\readline\\callback.c", - "..\\readline\\complete.c", "..\\readline\\display.c", - //"..\\readline\\emacs_keymap.c", - "..\\readline\\funmap.c", "..\\readline\\histexpand.c", - "..\\readline\\histfile.c", "..\\readline\\history.c", - "..\\readline\\histsearch.c", "..\\readline\\input.c", - "..\\readline\\isearch.c", "..\\readline\\keymaps.c", - "..\\readline\\kill.c", "..\\readline\\macro.c", - "..\\readline\\nls.c", "..\\readline\\parens.c", - "..\\readline\\readline.c", "..\\readline\\rltty.c", - "..\\readline\\search.c", "..\\readline\\shell.c", - "..\\readline\\signals.c", "..\\readline\\terminal.c", - "..\\readline\\tilde.c", "..\\readline\\undo.c", - "..\\readline\\util.c", - //"..\\readline\\vi_keymap.c", - "..\\readline\\vi_mode.c", "..\\readline\\xmalloc.c" - group regex = "..\\regex\\regcomp.c", "..\\regex\\regerror.c", "..\\regex\\regexec.c", "..\\regex\\regfree.c", "..\\regex\\reginit.c" group BldLevelInfo = 'os2\BldLevel.rc' + + group GnuReadline = + "..\\readline\\bind.c", + "..\\readline\\callback.c", + "..\\readline\\complete.c", + "..\\readline\\display.c", + "..\\readline\\funmap.c", + "..\\readline\\histexpand.c", "..\\readline\\histfile.c", + "..\\readline\\history.c", "..\\readline\\histsearch.c", + "..\\readline\\input.c", "..\\readline\\isearch.c", + "..\\readline\\keymaps.c", + "..\\readline\\kill.c", + "..\\readline\\macro.c", + "..\\readline\\nls.c", "..\\readline\\parens.c", + "..\\readline\\readline.c", + "..\\readline\\rltty.c", + "..\\readline\\search.c", + "..\\readline\\shell.c", + "..\\readline\\signals.c", + "..\\readline\\terminal.c", + "..\\readline\\tilde.c", + "..\\readline\\undo.c", + "..\\readline\\util.c", + "..\\readline\\vi_mode.c", + "..\\readline\\xmalloc.c" diff --git a/os2/MySQL-binlog.irs b/os2/MySQL-Sql.irs index 8d094544f1c..b651a678c91 100644 --- a/os2/MySQL-binlog.irs +++ b/os2/MySQL-Sql.irs @@ -1,5 +1,5 @@ 31 Run Specifications: Version 1.1 -45 E:\rd\mysql\vacpp-3.23.40\bin\mysqlbinlog.exe +40 E:\rd\MySQL\vacpp-3.23.50\bin\mysqld.exe 1 0 0 diff --git a/os2/MySQL-Util.icc b/os2/MySQL-Util.icc index 5a7ae2959b9..36fd499e520 100644 --- a/os2/MySQL-Util.icc +++ b/os2/MySQL-Util.icc @@ -153,6 +153,7 @@ option ProjectOptions = MySQLOptions } } */ + target "..\\bin\\test\\insert_test.exe" { // optimized precompiled headers @@ -179,4 +180,4 @@ option ProjectOptions = MySQLOptions } run after sources('..\bin\gen_lex_hash.exe') targets('..\sql\lex_hash.h') - '..\bin\gen_lex_has.exe > ..\sql\lex_hash.h' + 'cd ..\bin & ..\bin\gen_lex_hash.exe > ..\sql\lex_hash.h' diff --git a/os2/MySQL-Util.irs b/os2/MySQL-Util.irs index 01a1f62a483..183aa13ba27 100644 --- a/os2/MySQL-Util.irs +++ b/os2/MySQL-Util.irs @@ -1,3065 +1,3269 @@ 31 Run Specifications: Version 1.1 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamchk.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -43 E:\rd\mysql\vacpp-3.23.40\bin\myisamlog.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -44 E:\rd\mysql\vacpp-3.23.40\bin\myisampack.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -47 E:\rd\mysql\vacpp-3.23.40\bin\test\is_test1.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -47 E:\rd\mysql\vacpp-3.23.40\bin\test\is_test2.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -47 E:\rd\mysql\vacpp-3.23.40\bin\test\mi_test1.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -47 E:\rd\mysql\vacpp-3.23.40\bin\test\mi_test2.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -46 E:\rd\mysql\vacpp-3.23.40\bin\test\ft_eval.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -47 E:\rd\mysql\vacpp-3.23.40\bin\test\ft_test1.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -51 E:\rd\mysql\vacpp-3.23.40\bin\test\test_charset.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -47 E:\rd\mysql\vacpp-3.23.40\bin\test\hp_test1.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -47 E:\rd\mysql\vacpp-3.23.40\bin\test\hp_test2.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -47 E:\rd\mysql\vacpp-3.23.40\bin\test\thr_lock.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -50 E:\rd\mysql\vacpp-3.23.40\bin\test\insert_test.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -50 E:\rd\mysql\vacpp-3.23.40\bin\test\select_test.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe 1 0 0 5 Local 0 -50 E:\rd\mysql\vacpp-3.23.40\bin\test\thread_test.exe +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamchk.exe +1 +0 +0 +5 Local +0 +43 E:\rd\MySQL\vacpp-3.23.50\bin\myisamlog.exe +1 +0 +0 +5 Local +0 +44 E:\rd\MySQL\vacpp-3.23.50\bin\myisampack.exe +1 +0 +0 +5 Local +0 +47 E:\rd\MySQL\vacpp-3.23.50\bin\test\comp_err.exe +1 +0 +0 +5 Local +0 +46 E:\rd\MySQL\vacpp-3.23.50\bin\gen_lex_hash.exe +1 +0 +0 +5 Local +0 +47 E:\rd\MySQL\vacpp-3.23.50\bin\test\is_test1.exe +1 +0 +0 +5 Local +0 +47 E:\rd\MySQL\vacpp-3.23.50\bin\test\is_test2.exe +1 +0 +0 +5 Local +0 +47 E:\rd\MySQL\vacpp-3.23.50\bin\test\mi_test1.exe +1 +0 +0 +5 Local +0 +47 E:\rd\MySQL\vacpp-3.23.50\bin\test\mi_test2.exe +1 +0 +0 +5 Local +0 +46 E:\rd\MySQL\vacpp-3.23.50\bin\test\ft_eval.exe +1 +0 +0 +5 Local +0 +47 E:\rd\MySQL\vacpp-3.23.50\bin\test\ft_test1.exe +1 +0 +0 +5 Local +0 +51 E:\rd\MySQL\vacpp-3.23.50\bin\test\test_charset.exe +1 +0 +0 +5 Local +0 +47 E:\rd\MySQL\vacpp-3.23.50\bin\test\hp_test1.exe +1 +0 +0 +5 Local +0 +47 E:\rd\MySQL\vacpp-3.23.50\bin\test\hp_test2.exe +1 +0 +0 +5 Local +0 +50 E:\rd\MySQL\vacpp-3.23.50\bin\test\insert_test.exe +1 +0 +0 +5 Local +0 +50 E:\rd\MySQL\vacpp-3.23.50\bin\test\select_test.exe +1 +0 +0 +5 Local +0 +50 E:\rd\MySQL\vacpp-3.23.50\bin\test\thread_test.exe 1 0 0 diff --git a/os2/MySQL-binlog.icc b/os2/MySQL-binlog.icc deleted file mode 100644 index d441198f5e0..00000000000 --- a/os2/MySQL-binlog.icc +++ /dev/null @@ -1,68 +0,0 @@ -// disable code inlining when building static libs -InlineCode = "no" - -// include common options -include "MySQL-Opt.icc" -include "MySQL-Source.icc" - -option ProjectOptions = MySQLOptions - , define( "MYSQL_SERVER", "") - , link(defaultlibsname, "common.lib") - , link(defaultlibsname, "myisam.lib") - , link(defaultlibsname, "isam.lib") - , link(defaultlibsname, "mysql.lib") -{ - option define( "MYSQL_SERVER", "") - { - target "..\\bin\\mysqlbinlog.exe" - { - // optimized precompiled headers - option macros('global', 'yes') - { - source type('cpp') 'os2.h' - source type('cpp') 'errno.h', 'nerrno.h' - source type('cpp') 'config-os2.h', 'mysql_com.h' -/* - source type('cpp') - 'global.h', 'my_base.h', 'config-os2.h', - 'my_dir.h', 'my_sys.h', 'mysql.h', - 'my_bitmap.h', 'violite.h', - 'mysql_priv.h', - 'm_string.h' -*/ - } - // target source files - source type('cpp') - "..\\sql\\mysqlbinlog.cc" - option macros('global', 'yes') - { - source type('cpp') 'sys/stat.h' - } - source type('cpp') "..\\sql\\mini_client.cc" - option macros('global', 'yes') - { - source type('cpp') 'os2.h' - source type('cpp') 'math.h' - source type('cpp') 'stdio.h' - source type('cpp') 'stdlib.h' - source type('cpp') 'stddef.h' - source type('cpp') 'limits.h' - source type('cpp') 'sys/types.h' - source type('cpp') 'sys/time.h' - source type('cpp') 'types.h' - source type('cpp') 'stdarg.h' - source type('cpp') 'string.h' - } - source type('cpp') "..\\sql\\net_serv.cc", - "..\\sql\\mini_client_errors.c" - option macros('global', 'yes') - { - source type('cpp') 'assert.h' - } - source type('cpp') "..\\sql\\violite.c", - "..\\sql\\password.c" - //"..\\sql\\thr_malloc.cc" - } - } - -} diff --git a/os2/MySQL-sql.irs b/os2/MySQL-sql.irs deleted file mode 100644 index dc0b016d8d4..00000000000 --- a/os2/MySQL-sql.irs +++ /dev/null @@ -1,13 +0,0 @@ -31 Run Specifications: Version 1.1 -40 E:\rd\mysql\vacpp-3.23.40\bin\mysqld.exe -1 -0 -0 -5 Local -0 -40 E:\rd\mysql\vacpp-3.23.40\bin\mysqld.exe -1 -0 -0 -5 Local -0 diff --git a/os2/ReadMe.txt b/os2/ReadMe.txt index 1a8158df4bf..073c65290c0 100644 --- a/os2/ReadMe.txt +++ b/os2/ReadMe.txt @@ -6,7 +6,6 @@ Welcome to the latest port of MySQL for OS/2 and eComStation. Modules included in this build: - protocol data compression - - transaction support - perl BDB/BDI support (not in this package) - Library and header files for C/CPP developers included @@ -24,7 +23,7 @@ some files may be in the public domain. The latest information about MySQL can be found at: http://www.mysql.com To get the latest information about this port please subscribe to our -newsgroup/mailinglist mysql2 at www.egroups.com. +newsgroup/mailinglist mysql2 at groups.yahoo.com. To see what MySQL can do, take a look at the features section in the manual. For future plans see the TODO appendix in the manual. @@ -58,7 +57,7 @@ Prerequisite: OS/2 Warp Server for e-Business, eComStation 1.0 (prev 1/2 OK) - TCPIP 4.x installed (requires 32-bit tcpip stack) -- WarpIN installer 0.9.14 (ftp://ftp.os2.org/xworkplace/warpin-0-9-14.exe) +- WarpIN installer 0.9.16 (ftp://ftp.os2.org/xworkplace/warpin-0-9-16.exe) Note: probably some fixpak level is required on both Warp3&Warp4 to support >2GB file sizes. @@ -67,7 +66,7 @@ Save the installation archives into a temporary folder and double click on the main package; otherwise you can drop the mysql package in your WarpIN object or type - WARPIN MYSQL-3-23-??-BLD1.WPI + WARPIN MYSQL-3-23-??-B1.WPI from the command line. The configuration file for MySQL is named my.cnf and it is placed into @@ -75,9 +74,9 @@ your %ETC% directory. Usually it located into the boot driver under x:\MPTN\ETC -If the installation detect an existing configuration file, this will be -renamed to my.cnf.bak; your current settings aren't migrated to current -installation. This file is not deleted by uninstall process. +If the installation detect an existing configuration file, it will not be +overwritten, keeping you settings; see x:\...\mysql\data\my.cnf.sample +for new settings. This file is not deleted by uninstall process. Startup options for MySQL daemon could be added there. As default, client connections uses data compression: if you don't like it, @@ -93,6 +92,19 @@ default into mysql\bin together with client applications. Copy it to your x:\OS2\DLL or another directory in your LIBPATH to run command line utilities from every place. +See documentation for manuals installation. + + +New features +------------ +With build 4, the sql daemon supports a new option + + --preload-client-dll + +that enables preloading of mysql.dll and mysqlu.dll directly by the +server. This way, client programs doesn't need to have the dll's in +the current libpath. + Documentation ------------- @@ -102,7 +114,7 @@ INF documentation (requires OS/2 view or NewView). The PDF documentation is found in - MYSQL-3-23-42-PDF.WPI + MYSQL-3-23-??-PDF.WPI and the INF documentation is found in @@ -115,6 +127,9 @@ The INF documentation could contain errors because of semi-automatic translation from texi original. Also it is not updated as the latest PDF manual (sorry, but conversion from texi to ipf requires quite a lot of work). +To install the manuals, their WPI must be placed in the same directory +of the main WPI package: once the main package installation is started, +new install options will be available (inf or pdf manual). Support @@ -136,6 +151,7 @@ Since this software is ported for free, donations are welcome! You can get also an extended support, which is not free and subject to custom rates. Ask in the mailing list for details. +At least, a post card is welcome! Know problems @@ -161,8 +177,20 @@ All questions that are specific to the OS2/eComStation version should be posted to this list! Please remember to include all relevant information that may help solve your problem. + Building MySQL (VAC++ 4) ------------------------ +Place zlib-1.1.4 at the same level of mysql-3.23.50 +Place ufc lib at the same level of mysql-3.23.50 + +Add the following files: + include\config-os2.h + include\mysql_version.h + mysys\my_os2*.* +Get the following files from Windows source distribution: + strings\ctype_extra_sources.c + libmysql\dll.c + Apply file and patches found in the src\ directory (if exists). Create the following subdirectories diff --git a/os2/build-all.cmd b/os2/build-all.cmd index 9cb9ef6ea44..23558946c79 100644 --- a/os2/build-all.cmd +++ b/os2/build-all.cmd @@ -5,7 +5,6 @@ mkdir ..\lib mkdir ..\obj mkdir ..\obj\zlib -vacbld MySQL-Lib.icc -showprogress=10 -showwarning >> build-all.log vacbld MySQL-Client.icc -showprogress=10 -showwarning >> build-all.log vacbld MySQL-Sql.icc -showprogress=10 -showwarning >> build-all.log vacbld MySQL-Util.icc -showprogress=10 -showwarning >> build-all.log diff --git a/os2/build-all.log b/os2/build-all.log deleted file mode 100644 index a5a64db316f..00000000000 --- a/os2/build-all.log +++ /dev/null @@ -1,39 +0,0 @@ -Item 237 of 47475 (0%) ... source file ..\mysys\list.c -Item 4357 of 29226 (15%) ... source region "extern int _Optlink _spawnve(int, const char *, const char ..." -Item 10021 of 16290 (62%) ... initializer [0x7319920] for uchar to_upper_latin1[] -Item 11487 of 15248 (75%) ... kernel-provided extension source file \rd\mysql\zlib-1.1.3\crc32.c -Item 12920 of 15380 (84%) ... body of function [0x6dca980] int my_strcoll_czech(const uchar *, const uchar *) -Item 13952 of 16411 (85%) ... output object file E:\rd\mysql\vacpp-3.23.33\os2\ft_search.obj -Item 14083 of 16542 (85%) ... publish library or executable marker -Item 1278 of 16668 (8%) ... source region "typedef STARTDATA *PSTARTDATA;" -Item 6013 of 8617 (70%) ... kernel-provided extension source file \rd\mysql\zlib-1.1.3\trees.c -Item 6962 of 8581 (81%) ... initializer [0x229bf00] for const char @485 (static target)[23] "Failed in mysql_init()" -Item 7519 of 9019 (83%) ... initializer [0x2337bc0] for const char @630 (static target)[20] "No query specified -" -Item 8502 of 10001 (85%) ... publish library or executable marker -Item 182 of 49201 (0%) ... source file ..\myisam\mi_statrec.c -Item 2136 of 46089 (5%) ... source region "class Item_sum_udf_float :public Item_udf_sum { public: Item_sum_udf_float ..." -Item 11112 of 25912 (43%) ... source region "extern uint _nisam_get_key(N_KEYDEF *keyinfo ..." -Item 13919 of 24304 (57%) ... initializer [0x1ec6f10] for const short yypgoto[] -Item 15179 of 23800 (64%) ... kernel-provided extension source file \rd\mysql\zlib-1.1.3\trees.c -Item 17342 of 24056 (72%) ... initializer [0x29d1180] for __vftType __vft10Field_date5Field[46] -Item 17912 of 24406 (73%) ... body of function [0x1d1df40] void Item_func_case::print(String *) -Item 18247 of 24721 (74%) ... template instantiation (0x2b9dd20) of declaration of class I_List<thread_info> (2b9dc20) -Item 18775 of 25165 (75%) ... initializer [0x2c45600] for __vftType __vft18Item_func_get_lock4Item[34] -Item 19066 of 25369 (75%) ... initializer [0x2c800d0] for const char @2105 (static target)[22] "parser stack overflow" -Item 19395 of 25535 (76%) ... body of function [0x171eef0] db_type ha_checktype(db_type) -Item 19682 of 25654 (77%) ... body of function [0x17f1860] void kill_mysql() -Item 20070 of 25717 (78%) ... body of function [0x183e570] Item *create_func_date_format(Item *, Item *) -Item 20541 of 25764 (80%) ... body of function [0x1802b40] uint acl_get(const char *, const char *, const char *, const char *, const char *) -Item 21017 of 25874 (81%) ... body of function [0x2c55180] String *field_str::get_max_arg(String *) -Item 21406 of 25988 (82%) ... initializer [0x372d950] for const char @2567 (static target)[7] "%s(%d)" -Item 22411 of 25867 (87%) ... body of function [0x161b160] Item_func_udf_int::Item_func_udf_int(udf_func *) -Item 23345 of 25805 (90%) ... initializer [0x3447840] for const char @2709 (static target)[27] "waiting for handler insert" -Item 23783 of 26226 (91%) ... initializer [0x39a95b0] for const char @2766 (static target)[25] "Creating delayed handler" -Item 24887 of 27330 (91%) ... body of function [0x2b075a0] Item_load_file::~Item_load_file() -Item 25018 of 27461 (91%) ... body of function [0x2cf5e50] Item_sum::Item_sum() -Item 25267 of 27710 (91%) ... body of function [0x1c93d80] bool select_export::send_data(List<Item> &) -Item 25484 of 27927 (91%) ... body of function [0x116e840] Item *create_func_ascii(Item *) -Item 3212 of 9073 (35%) ... source region "extern int _mi_cmp_static_record(MI_INFO *info,const byte ..." -Item 7171 of 8564 (84%) ... code csect _test_handle from library E:\bin\IBMCPP40\LIB\CPPRMS40.LIB -Item 8345 of 9738 (86%) ... target E:\rd\mysql\vacpp-3.23.33\os2\..\bin\test\testhash.exe diff --git a/os2/include/Makefile.am b/os2/include/Makefile.am new file mode 100644 index 00000000000..b0478e7c470 --- /dev/null +++ b/os2/include/Makefile.am @@ -0,0 +1,23 @@ +# Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +# +# 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; either version 2 of the License, or +# (at your option) any later version. +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to create Makefile.in + +EXTRA_DIST = config.h pwd.h sgtty.h termio.h +SUBDIRS = sys + +# Don't update the files from bitkeeper +%::SCCS/s.% diff --git a/os2/include/config.h b/os2/include/config.h new file mode 100644 index 00000000000..bb1e3d9bb0f --- /dev/null +++ b/os2/include/config.h @@ -0,0 +1,13 @@ +#include <config-os2.h>
+#include <types.h>
+
+#undef HAVE_POSIX_SIGNALS
+#undef HAVE_BSD_SIGNALS
+#define TERMIO_TTY_DRIVER
+
+#define ScreenCols() 80
+#define ScreenRows() 25
+
+#define tputs(a,b,c) puts(a)
+#define kbhit _kbhit
+//#define _read_kbd(a, b, c) _kbhit()
diff --git a/os2/include/pwd.h b/os2/include/pwd.h new file mode 100644 index 00000000000..ec283586db2 --- /dev/null +++ b/os2/include/pwd.h @@ -0,0 +1 @@ +/* dummy */
diff --git a/os2/include/sgtty.h b/os2/include/sgtty.h new file mode 100644 index 00000000000..ec283586db2 --- /dev/null +++ b/os2/include/sgtty.h @@ -0,0 +1 @@ +/* dummy */
diff --git a/os2/include/sys/Makefile.am b/os2/include/sys/Makefile.am new file mode 100644 index 00000000000..b68f968aafe --- /dev/null +++ b/os2/include/sys/Makefile.am @@ -0,0 +1,22 @@ +# Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +# +# 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; either version 2 of the License, or +# (at your option) any later version. +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to create Makefile.in + +EXTRA_DIST = file.h + +# Don't update the files from bitkeeper +%::SCCS/s.% diff --git a/os2/include/sys/file.h b/os2/include/sys/file.h new file mode 100644 index 00000000000..ec283586db2 --- /dev/null +++ b/os2/include/sys/file.h @@ -0,0 +1 @@ +/* dummy */
diff --git a/os2/include/termio.h b/os2/include/termio.h new file mode 100644 index 00000000000..cad88caccf9 --- /dev/null +++ b/os2/include/termio.h @@ -0,0 +1,156 @@ +/* sys/termio.h (emx+gcc) */
+
+#ifndef _SYS_TERMIO_H
+#define _SYS_TERMIO_H
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/* Request codes */
+
+#if !defined (TCGETA)
+#define TCGETA 1
+#define TCSETA 2
+#define TCSETAW 3
+#define TCSETAF 4
+#define TCFLSH 5
+#define TCSBRK 6
+#define TCXONC 7
+#endif
+
+/* c_cc indexes */
+
+#if !defined (VINTR) /* Symbols common to termio.h and termios.h */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VEOL 5
+#define VMIN 6
+#define VTIME 7
+#endif
+
+#define NCC 8 /* Number of the above */
+
+/* c_iflag, emx ignores most of the following bits */
+
+#if !defined (IGNBRK) /* Symbols common to termio.h and termios.h */
+#define IGNBRK 0x0001
+#define BRKINT 0x0002
+#define IGNPAR 0x0004
+#define PARMRK 0x0008
+#define INPCK 0x0010
+#define ISTRIP 0x0020
+#define INLCR 0x0040
+#define IGNCR 0x0080
+#define ICRNL 0x0100
+#define IUCLC 0x0200
+#define IXON 0x0400
+#define IXANY 0x0800
+#define IXOFF 0x1000
+#define IDELETE 0x8000 /* Extension (emx) */
+#endif
+
+/* c_oflag, emx ignores all of the following bits */
+
+#if !defined (OPOST) /* Symbols common to termio.h and termios.h */
+#define OPOST 0x0001
+#endif
+#define OLCUC 0x0002
+#define ONLCR 0x0004
+#define OCRNL 0x0008
+#define ONOCR 0x0010
+#define ONLRET 0x0020
+#define OFILL 0x0040
+#define OFDEL 0x0080
+#define NLDLY 0x0100 /* Mask */
+#define NL0 0x0000
+#define NL1 0x0100
+#define CRDLY 0x0600 /* Mask */
+#define CR0 0x0000
+#define CR1 0x0200
+#define CR2 0x0400
+#define CR3 0x0600
+#define TABDLY 0x1800 /* Mask */
+#define TAB0 0x0000
+#define TAB1 0x0800
+#define TAB2 0x1000
+#define TAB3 0x1800
+#define BSDLY 0x2000 /* Mask */
+#define BS0 0x0000
+#define BS1 0x2000
+#define VTDLY 0x4000 /* Mask */
+#define VT0 0x0000
+#define VT1 0x4000
+#define FFDLY 0x8000 /* Mask */
+#define FF0 0x0000
+#define FF1 0x8000
+
+/* c_cflag, emx ignores all of the following bits */
+
+#if !defined (CBAUD)
+#define CBAUD 0x000f /* Mask */
+#endif
+#if !defined (B0) /* Symbols common to termio.h and termios.h */
+#define B0 0x0000
+#define B50 0x0001
+#define B75 0x0002
+#define B110 0x0003
+#define B134 0x0004
+#define B150 0x0005
+#define B200 0x0006
+#define B300 0x0007
+#define B600 0x0008
+#define B1200 0x0009
+#define B1800 0x000a
+#define B2400 0x000b
+#define B4800 0x000c
+#define B9600 0x000d
+#define B19200 0x000e
+#define B38400 0x000f
+#define CSIZE 0x0030 /* Mask */
+#define CS5 0x0000
+#define CS6 0x0010
+#define CS7 0x0020
+#define CS8 0x0030
+#define CSTOPB 0x0040
+#define CREAD 0x0080
+#define PARENB 0x0100
+#define PARODD 0x0200
+#define HUPCL 0x0400
+#define CLOCAL 0x0800
+#define LOBLK 0x1000
+#endif
+
+/* c_lflag, emx ignores some of the following bits */
+
+#if !defined (ISIG) /* Symbols common to termio.h and termios.h */
+#define ISIG 0x0001
+#define ICANON 0x0002
+#define XCASE 0x0004
+#define ECHO 0x0008
+#define ECHOE 0x0010
+#define ECHOK 0x0020
+#define ECHONL 0x0040
+#define NOFLSH 0x0080
+#define IDEFAULT 0x8000 /* Extension (emx) */
+#endif
+
+
+struct termio
+{
+ unsigned int c_iflag;
+ unsigned int c_oflag;
+ unsigned int c_cflag;
+ unsigned int c_lflag;
+ unsigned int c_line;
+ unsigned char c_cc[NCC];
+};
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* not _SYS_TERMIO_H */
diff --git a/os2/mysql.base b/os2/mysql.base deleted file mode 100644 index 4f0886e0697..00000000000 --- a/os2/mysql.base +++ /dev/null @@ -1,127 +0,0 @@ -#include "mysql.ih" - -<WARPIN VERSION <$WARPIN_VERSION>> -<HEAD> - -<PCK INDEX=1 - PACKAGEID="TCX Datakonsult AB\MySQL for OS/2\SQL Database Engine\<$MySQL\Ver>" - TARGET="?:\usr\local\mysql" BASE - TITLE="SQL Database Engine" - EXECUTE="$(1)\bootstrap.cmd [bootstrap]" - CONFIG.SYS="SET EMXOPT=-h1024 | UNIQUE(-h)" - CREATEOBJECT="WPFolder|MySQL <$MySQL.Ver>|<WP_DESKTOP>|OBJECTID=<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_FOLDER>" - CREATEOBJECT="WPProgram|Console|<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_FOLDER>|EXENAME=$(1)\bin\mysql.exe;STARTUPDIR=$(1)\bin;ICONFILE=$(1)\bin\icons\mysql-client.ico;OBJECTID=<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_CONSOLE>;" - CREATEOBJECT="WPProgram|Start server|<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_FOLDER>|EXENAME=$(1)\bin\mysqld.exe;ICONFILE=$(1)\bin\icons\mysql-startserver.ico;OBJECTID=<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_START>;" - CREATEOBJECT="WPProgram|Shutdown server|<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_FOLDER>|EXENAME=$(1)\bin\mysqladmin.exe;STARTUPDIR=$(1)\bin;PARAMETERS=-u root shutdown;ICONFILE=$(1)\bin\icons\mysql-shutdownserver.ico;OBJECTID=<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_SHUTDOWN>;" - CREATEOBJECT="WPProgram|Readme first|<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_FOLDER>|EXENAME=e.exe;PARAMETERS=$(1)\readme.os2;OBJECTID=<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_README>;" - SELECT - >This package will install MySQL for OS/2 SQL engine -</PCK> - -<PCK INDEX=2 - PACKAGEID="TCX Datakonsult AB\MySQL for OS/2\Developement Kit\<$MySQL\Ver>" - TARGET="?:\usr\local\mysql" - TITLE="Developement Kit" - SELECT - >This package will install MySQL for OS/2 sdk -</PCK> - -<PCK INDEX=3 - PACKAGEID="TCX Datakonsult AB\MySQL for OS/2\PDF manual\<$MySQL\Ver>" - TARGET="?:\usr\local\mysql" - TITLE="PDF manual" - EXTERNAL="mysql-3-23-28-gamma-pdf.wpi" - CREATEOBJECT="WPShadow|PDF Manual|<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_FOLDER>|SHADOWID=$(1)\docs\manual.pdf" - SELECT - >This package will install MySQL for OS/2 documentation -</PCK> - -<PCK INDEX=4 - PACKAGEID="TCX Datakonsult AB\MySQL for OS/2\INF manual\<$MySQL\Ver>" - TARGET="?:\usr\local\mysql" - TITLE="INF manual" - EXTERNAL="mysql-3-23-28-gamma-inf.wpi" - CREATEOBJECT="WPProgram|MySQL Manual|<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_FOLDER>|EXENAME=view.exe;PARAMETERS=$(1)\docs\manual.inf;ICONFILE=$(1)\bin\icons\mysql-manual.ico;OBJECTID=<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_INFMANUAL>;" - SELECT - >This package will install MySQL for OS/2 documentation -</PCK> - -<PCK INDEX=5 - PACKAGEID="TCX Datakonsult AB\MySQL for OS/2\Test suite\<$MySQL\Ver>" - TARGET="?:\usr\local\mysql" - TITLE="Test suite" - EXTERNAL="mysql-<$MySQL-Ver>-test.wpi" - CREATEOBJECT="WPProgram|Run MySQL Test Suite|<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_FOLDER>|EXENAME=$(5)\mysql-test\mysql-test.cmd;PARAMETERS=$(1)\docs\manual.inf;ICONFILE=$(1)\bin\icons\mysql-manual.ico;OBJECTID=<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_TESTSUITE>;" - SELECT - >This package will install MySQL for OS/2 test suite -</PCK> - -</HEAD> - -<!-- Here come the different pages. They are linked by - the <NEXTBUTTON> tags, which must have a target. - Each page must have a TYPE= attribute, which tells - WarpIn what will be visible on that page. --> - -<BODY> - -<!-- page1: introduction ->> -<PAGE INDEX=1 TYPE=README> -<TEXT> -</TEXT> -<NEXTBUTTON TARGET=2>~Next</NEXTBUTTON> -<README FORMAT=HTML> - -<P>Welcome to the latest port of MySQL for <B>OS/2 and eComStation</B>. - -<P>You are about to install <B>MySQL <$MySQL.Ver></B> - -<BR> -<BR> -<P>Select "Next" to continue. - -<P>Select "Cancel" to abort installation. -</README> -</PAGE> - -<!-- show readme.os2 --> -<PAGE INDEX=2 TYPE=README> -<NEXTBUTTON TARGET=3>~Next</NEXTBUTTON> -<TEXT> -</TEXT> -<README FORMAT=PLAIN EXTRACTFROMPCK="1">readme.os2</README> -</PAGE> - -<!-- show GPL license --> -<PAGE INDEX=3 TYPE=README> -<NEXTBUTTON TARGET=4>~I agree</NEXTBUTTON> -<TEXT> -By pressing the "I agree" button, you agree to all terms and conditions to the below licence agreement. -</TEXT> -<README FORMAT=HTML EXTRACTFROMPCK="1">license.htm</README> -</PAGE> - - -<!-- The TYPE=CONTAINER will list the packages which can be installed. --> - -<PAGE INDEX=4 TYPE=CONTAINER> -<NEXTBUTTON TARGET=5>~Next</NEXTBUTTON> -<TEXT> -Please select the packages which are to be installed. You may change the target paths for the packages. -</TEXT> -</PAGE> - -<!-- Here's another TYPE=TEXT page before we install. - The special target "0" indicates that after this page we - should start installation. - Note that the TYPE=INSTALL page (which we had in Alpha #3) - is no longer supported. --> - -<PAGE INDEX=5 TYPE=TEXT> -<NEXTBUTTON TARGET=0>I~nstall</NEXTBUTTON> -<TEXT> -Press "Install" to begin installing this archive.</TEXT> -</PAGE> - -</BODY> -</WARPIN> diff --git a/os2/mysql.ih b/os2/mysql.ih deleted file mode 100644 index 71978c4135a..00000000000 --- a/os2/mysql.ih +++ /dev/null @@ -1,7 +0,0 @@ -#define WARPIN_VERSION "0.9.12" -#define MySQL.Major 3 -#define MySQL.Minor 23 -#define MySQL.Rev 40 -#define MySQL\VER 3\23\40 -#define MySQL.VER 3.23.40 -#define MySQL-VER 3-23-40 diff --git a/os2/readme.os2 b/os2/readme.os2 deleted file mode 100644 index 9936dd15369..00000000000 --- a/os2/readme.os2 +++ /dev/null @@ -1,190 +0,0 @@ -MySQL 3.23.40 for OS/2 Warp build 1 -==================================================== - -Contents --------- -Welcome to the latest port of MySQL for OS/2 and eComStation. - -Modules included in this build: - - protocol data compression - - transaction support - - perl BDB/BDI support (not in this package) - - Library and header files for C/CPP developers included - -This package has been built using IBM VAC++ 4.0 - -The MySQL server is distributed under the GPL license. Please refer to -the file COPYING for the license information. - -The MySQL client library is distributed under the LGPL license. -Please refer to the file COPYING for the license information. - -Most of the MySQL clients are distributed under the GPL license, but -some files may be in the public domain. - -The latest information about MySQL can be found at: http://www.mysql.com - -To get the latest information about this port please subscribe to our -newsgroup/mailinglist mysql2 at www.egroups.com. - -To see what MySQL can do, take a look at the features section in the -manual. For future plans see the TODO appendix in the manual. - -New features/bug fixes history is in the news appendix in the manual. - -For the currently known bugs/misfeatures (known errors) see the bugs -appendix in the manual. The OS/2 section contains notes that are -specific to the MySQL OS/2 and eComStation version. - -Please note that MySQL is a constantly moving target. New builds for -Linux are made available every week. This port may therefore be a few -minor versions after the latest Linux/Win32 builds but its generally -more stable than the "latest and greates" port. - -MySQL is brought to you by: TcX DataKonsult AB & MySQL Finland AB - -This port is brought to you by: - -Yuri Dario <mc6530@mclink.it>, development, porting -Timo Maier <tam@gmx.de>, documentation, testing -John M Alfredsson <jma@jmast.se>, documentation, testing - - -Installation ------------- -Prerequisite: - -- OS/2 Warp 3 with FP ?? or later, - OS/2 Warp 4 with FP ?? or later, - OS/2 Warp Server for e-Business, - eComStation 1.0 (prev 1/2 OK) -- TCPIP 4.x installed (requires 32-bit tcpip stack) -- WarpIN installer 0.9.12 (ftp://ftp.os2.org/xworkplace/warpin-0-9-12.zip) - -Note: probably some fixpak level is required on both Warp3&Warp4 to - support >2GB file sizes. - -Save the installation archives into a temporary folder and double click -on the main package; otherwise you can drop the mysql package in your -WarpIN object or type - - WARPIN MYSQL-3-23-??-B1.WPI - -from the command line. -The configuration file for MySQL is named my.cnf and it is placed into -your %ETC% directory. Usually it located into the boot driver under - - x:\MPTN\ETC - -If the installation detect an existing configuration file, this will be -renamed to my.cnf.bak; your current settings aren't migrated to current -installation. This file is not deleted by uninstall process. -Startup options for MySQL daemon could be added there. - -As default, client connections uses data compression: if you don't like it, -remove the following from your %ETC%\my.cnf - - [client] - compress - -The server switches automatically compression mode on client request. - -SMP systems: while my developement system is a SMP one, and here MySQL seems -to run fine with two processors enabled, keep in mind that both EMX runtime -and current thread model are not SMP safe. - -This release comes with DLL client library MYSQL.DLL: it is installed by -default into mysql\bin together with client applications. Copy it to your -x:\OS2\DLL or another directory in your LIBPATH to run command line -utilities from every place. - - -Documentation -------------- -Documentation is provided in separate files. You can use either -the PDF documentation (requires Adobe Acrobat Reader) or the -INF documentation (requires OS/2 view or NewView). - -The PDF documentation is found in MYSQL-3-23-28-PDF.WPI and -the INF documentation is found in MYSQL-3-23-28-INF.WPI - -The latest documentation can always be downloaded from -http://www.mysql.com. However this documentation may -no fully apply to this port. -The INF documentation could contain errors because of semi-automatic -translation from texi original. - -Support -------- -Since MySQL is a OpenSource freeware product there are no -formal support options available. - -Please subscribe to mysql2 at www.egroups.com to get in contact -with other users using this port. - -http://www.egroups.com/group/mysql2 - -This newsgroup/mailinglist is the official "home" of this port. - - -Know problems -------------- -alter_table.test and show_check are failing, reporting a different status -message: actually seems only a different text, no bugs in table checking. - - -Apache/2 + PHP --------------- -To avoid problems with different socket when you use PHP and Apache -webserver, get the PHP4 module from the Apache Server for OS/2 homepage -http://silk.apana.org.au/apache/ - - -Developing MySQL ----------------- -If you want to help us develop MySQL for OS2/eComStation please join -the mysql2 mailinglist at www.egroups.com and ask for help to set up -your environment! - -All questions that are specific to the OS2/eComStation version should -be posted to this list! Please remember to include all relevant -information that may help solve your problem. - - -Building MySQL (EMX) --------------------- -NOTE: these instructions are outdated - -db-3.2.x: before compiling MySQL, you need to setup Berkeley DB. Untar -the distribution, enter dist directory and run - -attrib -r * /s -sh -c s_config - -to create proper aclocal macros and configure headers. - -In the src directory you will find patches used to build this release -of MySQL. -You can run 'sh -c config.status' to create current makefiles without -running autoconf & configure. - -apply previous patches (if not already included) -sh -c autoconf (upgrade scripts) -sh -c configure.os2 (config system) -edit config.status: - s%@MYSQL_UNIX_ADDR@%\\socket\\MySQL%g - s%@LN_CP_F@%cp.exe%g - replace -O2 -m486 with -mpentiumpro -sh -c config.status (upgrade makefiles again) -edit libmysql\Makefile - remove all occurences of -Zexe - replace libmysqlclient with libmysql (case sensitive search) -edit client\Makefile - replace libmysqlclient with libmysql (case sensitive search) -make - -After config.status, you have to edit include\mysql_version.h and correct -the socket definition (\\socket\\MySQL is correct). -If you go with configure, you have to change LN_CP_F macro from 'ln -s' to -'cp' and correct all makefiles (sh -c config.status will do it). - diff --git a/os2/rint.obj b/os2/rint.obj Binary files differindex 41c766c6661..1231f093327 100644 --- a/os2/rint.obj +++ b/os2/rint.obj diff --git a/sql/field.h b/sql/field.h index 785f55657ad..956c77e5024 100644 --- a/sql/field.h +++ b/sql/field.h @@ -73,6 +73,9 @@ public: virtual void set_default() { memcpy(ptr, ptr + table->rec_buff_length, pack_length()); + if (null_ptr) + *null_ptr= ((*null_ptr & (uchar) ~null_bit) | + null_ptr[table->rec_buff_length] & null_bit); } virtual bool binary() const { return 1; } virtual bool zero_pack() const { return 1; } @@ -93,12 +96,12 @@ public: virtual int key_cmp(const byte *str, uint length) { return cmp(ptr,(char*) str); } virtual uint decimals() const { return 0; } - virtual void sql_type(String &str) const =0; /* Caller beware: sql_type can change str.Ptr, so check ptr() to see if it changed if you are using your own buffer in str and restore it with set() if needed */ + virtual void sql_type(String &str) const =0; virtual uint size_of() const =0; // For new field inline bool is_null(uint row_offset=0) { return null_ptr ? (null_ptr[row_offset] & null_bit ? 1 : 0) : table->null_row; } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index e85965de60c..c82b4faf3f5 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -27,6 +27,7 @@ #endif #include "mysql_priv.h" +#include "slave.h" #ifdef HAVE_INNOBASE_DB #include <m_ctype.h> #include <assert.h> @@ -53,10 +54,12 @@ typedef byte mysql_byte; /* Include necessary InnoDB headers */ extern "C" { #include "../innobase/include/univ.i" +#include "../innobase/include/os0file.h" #include "../innobase/include/srv0start.h" #include "../innobase/include/srv0srv.h" #include "../innobase/include/trx0roll.h" #include "../innobase/include/trx0trx.h" +#include "../innobase/include/trx0sys.h" #include "../innobase/include/row0ins.h" #include "../innobase/include/row0mysql.h" #include "../innobase/include/row0sel.h" @@ -188,7 +191,8 @@ int convert_error_code_to_mysql( /*========================*/ /* out: MySQL error code */ - int error) /* in: InnoDB error code */ + int error, /* in: InnoDB error code */ + THD* thd) /* in: user thread handle or NULL */ { if (error == DB_SUCCESS) { @@ -207,11 +211,27 @@ convert_error_code_to_mysql( return(HA_ERR_NO_ACTIVE_RECORD); } else if (error == (int) DB_DEADLOCK) { + /* Since we roll back the whole transaction, we must + tell it also to MySQL so that MySQL knows to empty the + cached binlog for this transaction */ + + if (thd) { + ha_rollback(thd); + } return(HA_ERR_LOCK_DEADLOCK); } else if (error == (int) DB_LOCK_WAIT_TIMEOUT) { + /* Since we roll back the whole transaction, we must + tell it also to MySQL so that MySQL knows to empty the + cached binlog for this transaction */ + + + if (thd) { + ha_rollback(thd); + } + return(HA_ERR_LOCK_WAIT_TIMEOUT); } else if (error == (int) DB_NO_REFERENCED_ROW) { @@ -242,8 +262,6 @@ convert_error_code_to_mysql( return(HA_ERR_TO_BIG_ROW); } else { - DBUG_ASSERT(0); - return(-1); // Unknown error } } @@ -257,35 +275,48 @@ the prototype for this function! */ void innobase_mysql_print_thd( /*=====================*/ + char* buf, /* in/out: buffer where to print, must be at least + 300 bytes */ void* input_thd)/* in: pointer to a MySQL THD object */ { THD* thd; thd = (THD*) input_thd; - printf("MySQL thread id %lu, query id %lu", - thd->thread_id, thd->query_id); - if (thd->host) { - printf(" %s", thd->host); + /* We can't use value of sprintf() as this is not portable */ + buf+= my_sprintf(buf, + (buf, "MySQL thread id %lu, query id %lu", + thd->thread_id, thd->query_id)); + if (thd->host) + { + *buf++=' '; + buf=strnmov(buf, thd->host, 30); } - if (thd->ip) { - printf(" %s", thd->ip); + if (thd->ip) + { + *buf++=' '; + buf=strnmov(buf, thd->ip, 20); } - if (thd->user) { - printf(" %s", thd->user); + if (thd->user) + { + *buf++=' '; + buf=strnmov(buf, thd->user, 20); } - if (thd->proc_info) { - printf(" %s", thd->proc_info); + if (thd->proc_info) + { + *buf++=' '; + buf=strnmov(buf, thd->proc_info, 50); } - if (thd->query) { - printf("\n%-.100s", thd->query); + if (thd->query) + { + *buf++=' '; + buf=strnmov(buf, thd->query, 150); } - - printf("\n"); + *buf='\n'; } } @@ -302,6 +333,8 @@ check_trx_exists( { trx_t* trx; + ut_a(thd == current_thd); + trx = (trx_t*) thd->transaction.all.innobase_tid; if (trx == NULL) { @@ -321,7 +354,23 @@ check_trx_exists( thd->transaction.stmt.innobase_tid = (void*)&innodb_dummy_stmt_trx_handle; } else { - ut_a(trx->magic_n == TRX_MAGIC_N); + if (trx->magic_n != TRX_MAGIC_N) { + mem_analyze_corruption((byte*)trx); + + ut_a(0); + } + } + + if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) { + trx->check_foreigns = FALSE; + } else { + trx->check_foreigns = TRUE; + } + + if (thd->options & OPTION_RELAXED_UNIQUE_CHECKS) { + trx->check_unique_secondary = FALSE; + } else { + trx->check_unique_secondary = TRUE; } return(trx); @@ -340,7 +389,7 @@ ha_innobase::update_thd( { row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; trx_t* trx; - + trx = check_trx_exists(thd); if (prebuilt->trx != trx) { @@ -361,13 +410,15 @@ innobase_init(void) /*===============*/ /* out: TRUE if error */ { - static char current_lib[3]; // Set if using current lib + static char current_dir[3]; // Set if using current lib int err; bool ret; char *default_path; DBUG_ENTER("innobase_init"); + os_innodb_umask = (ulint)my_umask; + /* When using the embedded server, the datadirectory is not in the current directory. @@ -377,10 +428,10 @@ innobase_init(void) else { /* It's better to use current lib, to keep path's short */ - current_lib[0] = FN_CURLIB; - current_lib[1] = FN_LIBCHAR; - current_lib[2] = 0; - default_path=current_lib; + current_dir[0] = FN_CURLIB; + current_dir[1] = FN_LIBCHAR; + current_dir[2] = 0; + default_path=current_dir; } if (specialflag & SPECIAL_NO_PRIOR) { @@ -441,11 +492,12 @@ innobase_init(void) srv_log_archive_on = (ulint) innobase_log_archive; srv_log_buffer_size = (ulint) innobase_log_buffer_size; - srv_flush_log_at_trx_commit = (ibool) innobase_flush_log_at_trx_commit; + srv_flush_log_at_trx_commit = (ulint) innobase_flush_log_at_trx_commit; srv_use_native_aio = 0; srv_pool_size = (ulint) innobase_buffer_pool_size; + srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size; srv_n_file_io_threads = (ulint) innobase_file_io_threads; @@ -477,6 +529,22 @@ innobase_init(void) (void) hash_init(&innobase_open_tables,32,0,0, (hash_get_key) innobase_get_key,0,0); pthread_mutex_init(&innobase_mutex,MY_MUTEX_INIT_FAST); + + /* If this is a replication slave and we needed to do a crash recovery, + set the master binlog position to what InnoDB internally knew about + how far we got transactions durable inside InnoDB. There is a + problem here: if the user used also MyISAM tables, InnoDB might not + know the right position for them. + + THIS DOES NOT WORK CURRENTLY because replication seems to initialize + glob_mi also after innobase_init. */ + +/* if (trx_sys_mysql_master_log_pos != -1) { + ut_memcpy(glob_mi.log_file_name, trx_sys_mysql_master_log_name, + 1 + ut_strlen(trx_sys_mysql_master_log_name)); + glob_mi.pos = trx_sys_mysql_master_log_pos; + } +*/ DBUG_RETURN(0); } @@ -536,6 +604,30 @@ innobase_get_free_space(void) /********************************************************************* Commits a transaction in an InnoDB database. */ +void +innobase_commit_low( +/*================*/ + trx_t* trx) /* in: transaction handle */ +{ + if (current_thd->slave_thread) + { + /* Update the replication position info inside InnoDB */ +#ifdef NEED_TO_BE_FIXED + trx->mysql_relay_log_file_name= active_mi->rli.log_file_name; + trx->mysql_relay_log_pos= active_mi->rli.relay_log_pos; +#endif + trx->mysql_master_log_file_name= active_mi->rli.master_log_name; + trx->mysql_master_log_pos= ((ib_longlong) + (active_mi->rli.master_log_pos + + active_mi->rli.event_len + + active_mi->rli.pending)); + } + trx_commit_for_mysql(trx); +} + +/********************************************************************* +Commits a transaction in an InnoDB database. */ + int innobase_commit( /*============*/ @@ -555,8 +647,7 @@ innobase_commit( trx = check_trx_exists(thd); if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) { - - trx_commit_for_mysql(trx); + innobase_commit_low(trx); } /* Release possible statement level resources */ @@ -596,6 +687,8 @@ innobase_report_binlog_offset_and_commit( trx = (trx_t*)trx_handle; + ut_a(trx != NULL); + trx->mysql_log_file_name = log_file_name; trx->mysql_log_offset = (ib_longlong)end_offset; @@ -636,7 +729,7 @@ innobase_rollback( trx_mark_sql_stat_end(trx); - DBUG_RETURN(convert_error_code_to_mysql(error)); + DBUG_RETURN(convert_error_code_to_mysql(error, NULL)); } /********************************************************************* @@ -798,7 +891,6 @@ ha_innobase::open( ib_table = dict_table_get_and_increment_handle_count( norm_name, NULL); - if (NULL == ib_table) { sql_print_error("InnoDB error:\n\ @@ -855,6 +947,9 @@ have moved .frm files to another database?", auto_inc_counter_for_this_stat = 0; + block_size = 16 * 1024; /* Index block size in InnoDB: used by MySQL + in query optimization */ + /* Init table lock structure */ thr_lock_data_init(&share->lock,&lock,(void*) 0); @@ -1134,7 +1229,7 @@ ha_innobase::store_key_val_for_row( keys to see if they are equal */ bzero(buff, (ref_length- (uint) (buff - buff_start))); - return ref_length; + DBUG_RETURN(ref_length); } /****************************************************************** @@ -1312,6 +1407,9 @@ ha_innobase::write_row( DBUG_ENTER("ha_innobase::write_row"); + ut_a(prebuilt->trx == + (trx_t*) current_thd->transaction.all.innobase_tid); + statistic_increment(ha_write_count, &LOCK_status); if (table->time_stamp) { @@ -1379,7 +1477,8 @@ ha_innobase::write_row( if (error != DB_SUCCESS) { - error = convert_error_code_to_mysql(error); + error = convert_error_code_to_mysql(error, + user_thd); goto func_exit; } @@ -1395,7 +1494,7 @@ ha_innobase::write_row( srv_conc_exit_innodb(prebuilt->trx); error = convert_error_code_to_mysql( - error); + error, user_thd); goto func_exit; } } @@ -1426,7 +1525,8 @@ ha_innobase::write_row( if (error != DB_SUCCESS) { - error = convert_error_code_to_mysql(error); + error = convert_error_code_to_mysql(error, + user_thd); goto func_exit; } @@ -1466,7 +1566,7 @@ ha_innobase::write_row( prebuilt->trx->ignore_duplicates_in_insert = FALSE; - error = convert_error_code_to_mysql(error); + error = convert_error_code_to_mysql(error, user_thd); /* Tell InnoDB server that there might be work for utility threads: */ @@ -1650,6 +1750,9 @@ ha_innobase::update_row( DBUG_ENTER("ha_innobase::update_row"); + ut_a(prebuilt->trx == + (trx_t*) current_thd->transaction.all.innobase_tid); + if (table->time_stamp) { update_timestamp(new_row + table->time_stamp - 1); } @@ -1683,7 +1786,7 @@ ha_innobase::update_row( srv_conc_exit_innodb(prebuilt->trx); - error = convert_error_code_to_mysql(error); + error = convert_error_code_to_mysql(error, user_thd); /* Tell InnoDB server that there might be work for utility threads: */ @@ -1707,6 +1810,9 @@ ha_innobase::delete_row( DBUG_ENTER("ha_innobase::delete_row"); + ut_a(prebuilt->trx == + (trx_t*) current_thd->transaction.all.innobase_tid); + if (last_query_id != user_thd->query_id) { prebuilt->sql_stat_start = TRUE; last_query_id = user_thd->query_id; @@ -1728,7 +1834,7 @@ ha_innobase::delete_row( srv_conc_exit_innodb(prebuilt->trx); - error = convert_error_code_to_mysql(error); + error = convert_error_code_to_mysql(error, user_thd); /* Tell the InnoDB server that there might be work for utility threads: */ @@ -1820,6 +1926,10 @@ ha_innobase::index_read( ulint ret; DBUG_ENTER("index_read"); + + ut_a(prebuilt->trx == + (trx_t*) current_thd->transaction.all.innobase_tid); + statistic_increment(ha_read_key_count, &LOCK_status); if (last_query_id != user_thd->query_id) { @@ -1886,7 +1996,7 @@ ha_innobase::index_read( error = HA_ERR_KEY_NOT_FOUND; table->status = STATUS_NOT_FOUND; } else { - error = convert_error_code_to_mysql(ret); + error = convert_error_code_to_mysql(ret, user_thd); table->status = STATUS_NOT_FOUND; } @@ -1924,7 +2034,6 @@ ha_innobase::change_active_index( { row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; KEY* key=0; - statistic_increment(ha_read_key_count, &LOCK_status); DBUG_ENTER("change_active_index"); @@ -2009,6 +2118,9 @@ ha_innobase::general_fetch( DBUG_ENTER("general_fetch"); + ut_a(prebuilt->trx == + (trx_t*) current_thd->transaction.all.innobase_tid); + srv_conc_enter_innodb(prebuilt->trx); ret = row_search_for_mysql((byte*)buf, 0, prebuilt, match_mode, @@ -2027,7 +2139,7 @@ ha_innobase::general_fetch( error = HA_ERR_END_OF_FILE; table->status = STATUS_NOT_FOUND; } else { - error = convert_error_code_to_mysql(ret); + error = convert_error_code_to_mysql(ret, user_thd); table->status = STATUS_NOT_FOUND; } @@ -2220,6 +2332,9 @@ ha_innobase::rnd_pos( statistic_increment(ha_read_rnd_count, &LOCK_status); + ut_a(prebuilt->trx == + (trx_t*) current_thd->transaction.all.innobase_tid); + if (prebuilt->clust_index_was_generated) { /* No primary key was defined for the table and we generated the clustered index from the row id: the @@ -2262,6 +2377,9 @@ ha_innobase::position( row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; uint len; + ut_a(prebuilt->trx == + (trx_t*) current_thd->transaction.all.innobase_tid); + if (prebuilt->clust_index_was_generated) { /* No primary key was defined for the table and we generated the clustered index from row id: the @@ -2334,7 +2452,7 @@ create_table_def( error = row_create_table_for_mysql(table, trx); - error = convert_error_code_to_mysql(error); + error = convert_error_code_to_mysql(error, NULL); DBUG_RETURN(error); } @@ -2392,7 +2510,7 @@ create_index( error = row_create_index_for_mysql(index, trx); - error = convert_error_code_to_mysql(error); + error = convert_error_code_to_mysql(error, NULL); DBUG_RETURN(error); } @@ -2418,7 +2536,7 @@ create_clustered_index_when_no_primary( 0, DICT_CLUSTERED, 0); error = row_create_index_for_mysql(index, trx); - error = convert_error_code_to_mysql(error); + error = convert_error_code_to_mysql(error, NULL); return(error); } @@ -2444,22 +2562,41 @@ ha_innobase::create( uint i; char name2[FN_REFLEN]; char norm_name[FN_REFLEN]; + THD *thd= current_thd; DBUG_ENTER("ha_innobase::create"); + DBUG_ASSERT(thd != NULL); + trx = trx_allocate_for_mysql(); + if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) { + trx->check_foreigns = FALSE; + } + + if (thd->options & OPTION_RELAXED_UNIQUE_CHECKS) { + trx->check_unique_secondary = FALSE; + } + + fn_format(name2, name, "", "",2); // Remove the .frm extension normalize_table_name(norm_name, name2); - /* Create the table definition in InnoDB */ + /* Latch the InnoDB data dictionary exclusive so that no deadlocks + or lock waits can happen in it during a table create operation. + (Drop table etc. do this latching in row0mysql.c.) */ + + row_mysql_lock_data_dictionary(); + + /* Create the table definition in InnoDB */ error = create_table_def(trx, form, norm_name); if (error) { + innobase_commit_low(trx); - trx_commit_for_mysql(trx); + row_mysql_unlock_data_dictionary(); trx_free_for_mysql(trx); @@ -2487,7 +2624,9 @@ ha_innobase::create( error = create_clustered_index_when_no_primary(trx, norm_name); if (error) { - trx_commit_for_mysql(trx); + innobase_commit_low(trx); + + row_mysql_unlock_data_dictionary(); trx_free_for_mysql(trx); @@ -2500,7 +2639,9 @@ ha_innobase::create( first */ if ((error = create_index(trx, form, norm_name, (uint) primary_key_no))) { - trx_commit_for_mysql(trx); + innobase_commit_low(trx); + + row_mysql_unlock_data_dictionary(); trx_free_for_mysql(trx); @@ -2514,7 +2655,9 @@ ha_innobase::create( if ((error = create_index(trx, form, norm_name, i))) { - trx_commit_for_mysql(trx); + innobase_commit_low(trx); + + row_mysql_unlock_data_dictionary(); trx_free_for_mysql(trx); @@ -2526,17 +2669,21 @@ ha_innobase::create( error = row_table_add_foreign_constraints(trx, create_info->create_statement, norm_name); - error = convert_error_code_to_mysql(error); + error = convert_error_code_to_mysql(error, NULL); if (error) { - trx_commit_for_mysql(trx); + innobase_commit_low(trx); + + row_mysql_unlock_data_dictionary(); trx_free_for_mysql(trx); DBUG_RETURN(error); } - trx_commit_for_mysql(trx); + innobase_commit_low(trx); + + row_mysql_unlock_data_dictionary(); /* Flush the log to reduce probability that the .frm files and the InnoDB data dictionary get out-of-sync if the user runs @@ -2604,11 +2751,11 @@ ha_innobase::delete_table( srv_active_wake_master_thread(); - trx_commit_for_mysql(trx); + innobase_commit_low(trx); trx_free_for_mysql(trx); - error = convert_error_code_to_mysql(error); + error = convert_error_code_to_mysql(error, NULL); DBUG_RETURN(error); } @@ -2661,10 +2808,10 @@ innobase_drop_database( srv_active_wake_master_thread(); - trx_commit_for_mysql(trx); + innobase_commit_low(trx); trx_free_for_mysql(trx); - error = convert_error_code_to_mysql(error); + error = convert_error_code_to_mysql(error, NULL); return(error); } @@ -2714,10 +2861,10 @@ ha_innobase::rename_table( srv_active_wake_master_thread(); - trx_commit_for_mysql(trx); + innobase_commit_low(trx); trx_free_for_mysql(trx); - error = convert_error_code_to_mysql(error); + error = convert_error_code_to_mysql(error, NULL); DBUG_RETURN(error); } @@ -2980,6 +3127,8 @@ ha_innobase::check( ulint ret; ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N); + ut_a(prebuilt->trx == + (trx_t*) current_thd->transaction.all.innobase_tid); if (prebuilt->mysql_template == NULL) { /* Build the template; we will use a dummy template @@ -3029,8 +3178,9 @@ ha_innobase::update_table_comment( *pos++=' '; } - pos += sprintf(pos, "InnoDB free: %lu kB", - (ulong) innobase_get_free_space()); + pos += my_sprintf(pos, + (pos,"InnoDB free: %lu kB", + (ulong) innobase_get_free_space())); /* We assume 450 - length bytes of space to print info */ @@ -3216,6 +3366,51 @@ ha_innobase::external_lock( } /**************************************************************************** +Implements the SHOW INNODB STATUS command. Send the output of the InnoDB +Monitor to the client. */ + +int +innodb_show_status( +/*===============*/ + THD* thd) /* in: the MySQL query thread of the caller */ +{ + String* packet = &thd->packet; + char* buf; + + DBUG_ENTER("innodb_show_status"); + + /* We let the InnoDB Monitor to output at most 100 kB of text */ + buf = (char*)ut_malloc(100 * 1024); + + srv_sprintf_innodb_monitor(buf, 100 * 1024); + + List<Item> field_list; + + field_list.push_back(new Item_empty_string("Status", strlen(buf))); + + if(send_fields(thd, field_list, 1)) { + DBUG_RETURN(-1); + } + + packet->length(0); + + net_store_data(packet, buf); + + if (my_net_write(&thd->net, (char*)thd->packet.ptr(), + packet->length())) { + ut_free(buf); + + DBUG_RETURN(-1); + } + + ut_free(buf); + + send_eof(&thd->net); + + DBUG_RETURN(0); +} + +/**************************************************************************** Handling the shared INNOBASE_SHARE structure that is needed to provide table locking. ****************************************************************************/ @@ -3338,6 +3533,9 @@ ha_innobase::get_auto_increment() longlong nr; int error; + ut_a(prebuilt->trx == + (trx_t*) current_thd->transaction.all.innobase_tid); + /* Also SHOW TABLE STATUS calls this function. Previously, when we did always read the max autoinc key value, setting x-locks, users were surprised that SHOW TABLE STATUS could end up in a deadlock with diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index ce320737ef6..a9a7c9997ad 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -201,4 +201,5 @@ int innobase_report_binlog_offset_and_commit( int innobase_rollback(THD *thd, void* trx_handle); int innobase_close_connection(THD *thd); int innobase_drop_database(char *path); +int innodb_show_status(THD* thd); diff --git a/sql/handler.cc b/sql/handler.cc index 95f238260db..7aba6817eca 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -218,6 +218,7 @@ int ha_autocommit_or_rollback(THD *thd, int error) } else (void) ha_rollback_stmt(thd); + thd->variables.tx_isolation=thd->session_tx_isolation; } #endif @@ -274,6 +275,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) { bool operation_done= 0; bool transaction_commited= 0; + /* Update the binary log if we have cached some queries */ if (trans == &thd->transaction.all && mysql_bin_log.is_open() && my_b_tell(&thd->transaction.trans_log)) diff --git a/sql/item_func.cc b/sql/item_func.cc index 618eb259bd0..3e5c082033b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1466,20 +1466,15 @@ void item_user_lock_release(ULL *ull) ull->locked=0; if (mysql_bin_log.is_open()) { - THD *thd = current_thd; - uint save_query_length; char buf[256]; String tmp(buf,sizeof(buf)); tmp.length(0); tmp.append("DO RELEASE_LOCK(\""); tmp.append(ull->key,ull->key_length); tmp.append("\")"); - save_query_length=thd->query_length; - thd->query_length=tmp.length(); - Query_log_event qev(thd,tmp.ptr()); + Query_log_event qev(current_thd,tmp.ptr(), tmp.length()); qev.error_code=0; // this query is always safe to run on slave mysql_bin_log.write(&qev); - thd->query_length=save_query_length; } if (--ull->count) pthread_cond_signal(&ull->cond); diff --git a/sql/item_func.h b/sql/item_func.h index 6c0c2cda06d..77b78495214 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -208,9 +208,14 @@ public: void fix_length_and_dec() {} Field *tmp_table_field(TABLE *t_arg) { - if (!t_arg) return result_field; - return (max_length > 11) ? (Field *)new Field_longlong(max_length,maybe_null,name, t_arg,unsigned_flag) : (Field *)new Field_long(max_length,maybe_null,name, t_arg,unsigned_flag); - } + if (!t_arg) + return result_field; + return ((max_length > 11) ? + (Field *)new Field_longlong(max_length, maybe_null, name, t_arg, + unsigned_flag) : + (Field *)new Field_long(max_length, maybe_null, name, t_arg, + unsigned_flag)); + } }; class Item_func_signed :public Item_int_func diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 482bf499757..835b1c7547d 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -37,12 +37,18 @@ public: void left_right_max_length(); Field *tmp_table_field(TABLE *t_arg) { - if (!t_arg) return result_field; - return (max_length > 255) ? (Field *)new Field_blob(max_length,maybe_null, name,t_arg, binary) : (Field *) new Field_string(max_length,maybe_null, name,t_arg, binary); - } + if (!t_arg) + return result_field; + return ((max_length > 255) ? + (Field *) new Field_blob(max_length, maybe_null, name, t_arg, + binary) : + (Field *) new Field_string(max_length, maybe_null, name, t_arg, + binary)); + } unsigned int size_of() { return sizeof(*this);} }; + class Item_func_md5 :public Item_str_func { String tmp_value; diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index d867433ef91..4478c3df266 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -242,8 +242,7 @@ public: } Field *tmp_table_field(TABLE *t_arg) { - if (!t_arg) return result_field; - return new Field_date(maybe_null, name, t_arg); + return (!t_arg) ? result_field : new Field_date(maybe_null, name, t_arg); } unsigned int size_of() { return sizeof(*this);} }; @@ -261,9 +260,9 @@ public: } Field *tmp_table_field(TABLE *t_arg) { - if (!t_arg) return result_field; - return new Field_datetime(maybe_null, name, t_arg); - } + return (!t_arg) ? result_field : new Field_datetime(maybe_null, name, + t_arg); + } unsigned int size_of() { return sizeof(*this);} }; @@ -289,8 +288,7 @@ public: } Field *tmp_table_field(TABLE *t_arg) { - if (!t_arg) return result_field; - return new Field_time(maybe_null, name, t_arg); + return (!t_arg) ? result_field : new Field_time(maybe_null, name, t_arg); } unsigned int size_of() { return sizeof(*this);} }; @@ -386,11 +384,11 @@ public: } Field *tmp_table_field(TABLE *t_arg) { - if (!t_arg) return result_field; - return new Field_time(maybe_null, name, t_arg); - } + return (!t_arg) ? result_field : new Field_time(maybe_null, name, t_arg); + } }; + enum interval_type { INTERVAL_YEAR, INTERVAL_MONTH, INTERVAL_DAY, INTERVAL_HOUR, INTERVAL_MINUTE, INTERVAL_SECOND, INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, @@ -452,8 +450,7 @@ public: } Field *tmp_table_field(TABLE *t_arg) { - if (!t_arg) return result_field; - return new Field_date(maybe_null, name, t_arg); + return (!t_arg) ? result_field : new Field_date(maybe_null, name, t_arg); } }; @@ -468,9 +465,8 @@ public: } Field *tmp_table_field(TABLE *t_arg) { - if (!t_arg) return result_field; - return new Field_time(maybe_null, name, t_arg); - } + return (!t_arg) ? result_field : new Field_time(maybe_null, name, t_arg); + } }; class Item_datetime_typecast :public Item_typecast @@ -484,7 +480,7 @@ public: } Field *tmp_table_field(TABLE *t_arg) { - if (!t_arg) return result_field; - return new Field_datetime(maybe_null, name, t_arg); - } + return (!t_arg) ? result_field : new Field_datetime(maybe_null, name, + t_arg); + } }; diff --git a/sql/lex.h b/sql/lex.h index eec3c650ba8..39298323d75 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -30,7 +30,7 @@ #endif /* - Symbols are breaked in to separated arrays to allow field names with + Symbols are broken into separated arrays to allow field names with same name as functions. These are kept sorted for human lookup (the symbols are hashed). */ @@ -251,6 +251,7 @@ static SYMBOL symbols[] = { { "NEW", SYM(NEW_SYM),0,0}, { "NCHAR", SYM(NCHAR_SYM),0,0}, { "NO", SYM(NO_SYM),0,0}, + { "NO_FOREIGN_KEY_CHECKS", SYM(NO_FOREIGN_KEY_CHECKS), 0, 0}, { "NOT", SYM(NOT),0,0}, { "NULL", SYM(NULL_SYM),0,0}, { "NUMERIC", SYM(NUMERIC_SYM),0,0}, @@ -284,6 +285,7 @@ static SYMBOL symbols[] = { { "RELAY_LOG_POS", SYM(RELAY_LOG_POS_SYM),0,0}, { "RELOAD", SYM(RELOAD),0,0}, { "REGEXP", SYM(REGEXP),0,0}, + { "RELAXED_UNIQUE_CHECKS", SYM(RELAXED_UNIQUE_CHECKS), 0, 0}, { "RENAME", SYM(RENAME),0,0}, { "REPAIR", SYM(REPAIR),0,0}, { "REPLACE", SYM(REPLACE),0,0}, diff --git a/sql/lock.cc b/sql/lock.cc index 93c826f2528..056ed0fec8f 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -28,6 +28,7 @@ TODO: #include "mysql_priv.h" #include <hash.h> +#include <assert.h> extern HASH open_cache; @@ -427,6 +428,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) char key[MAX_DBKEY_LENGTH]; uint key_length; DBUG_ENTER("lock_table_name"); + safe_mutex_assert_owner(&LOCK_open); key_length=(uint) (strmov(strmov(key,table_list->db)+1,table_list->name) -key)+ 1; @@ -486,6 +488,7 @@ bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list) { bool result=0; DBUG_ENTER("wait_for_locked_table_names"); + safe_mutex_assert_owner(&LOCK_open); while (locked_named_table(thd,table_list)) { diff --git a/sql/log.cc b/sql/log.cc index 95f6319231d..19f2db8403b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -80,8 +80,9 @@ static int find_uniq_filename(char *name) DBUG_RETURN(0); } + MYSQL_LOG::MYSQL_LOG() - :bytes_written(0), last_time(0), query_start(0), index_file(-1), name(0), + :bytes_written(0), last_time(0), query_start(0), name(0), file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), inited(0), no_rotate(0), need_start_event(1) { @@ -91,8 +92,10 @@ MYSQL_LOG::MYSQL_LOG() */ index_file_name[0] = 0; bzero((char*) &log_file,sizeof(log_file)); + bzero((char*) &index_file, sizeof(index_file)); } + MYSQL_LOG::~MYSQL_LOG() { if (inited) @@ -103,15 +106,6 @@ MYSQL_LOG::~MYSQL_LOG() } } -void MYSQL_LOG::set_index_file_name(const char* index_file_name) -{ - if (index_file_name) - fn_format(this->index_file_name,index_file_name,mysql_data_home,".index", - 4); - else - this->index_file_name[0] = 0; -} - int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name) { @@ -132,12 +126,6 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name) return 0; } -bool MYSQL_LOG::open_index( int options) -{ - return (index_file < 0 && - (index_file = my_open(index_file_name, options | O_BINARY , - MYF(MY_WME))) < 0); -} void MYSQL_LOG::init(enum_log_type log_type_arg, enum cache_type io_cache_type_arg, @@ -148,32 +136,41 @@ void MYSQL_LOG::init(enum_log_type log_type_arg, no_auto_events = no_auto_events_arg; if (!inited) { - inited=1; + inited= 1; (void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW); (void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW); (void) pthread_cond_init(&update_cond, 0); } } -void MYSQL_LOG::close_index() -{ - if (index_file >= 0) - { - my_close(index_file, MYF(0)); - index_file = -1; - } -} -void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, - const char *new_name, enum cache_type io_cache_type_arg, +/* + Open a (new) log file. + + DESCRIPTION + - If binary logs, also open the index file and register the new + file name in it + - When calling this when the file is in use, you must have a locks + on LOCK_log and LOCK_index. + + RETURN VALUES + 0 ok + 1 error +*/ + +bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, + const char *new_name, const char *index_file_name_arg, + enum cache_type io_cache_type_arg, bool no_auto_events_arg) { - MY_STAT tmp_stat; char buff[512]; - File file= -1; - bool do_magic; + File file= -1, index_file_nr= -1; int open_flags = O_CREAT | O_APPEND | O_BINARY; DBUG_ENTER("MYSQL_LOG::open"); + DBUG_PRINT("enter",("log_type: %d",(int) log_type)); + + last_time=query_start=0; + write_error=0; if (!inited && log_type_arg == LOG_BIN && *fn_ext(log_name)) no_rotate = 1; @@ -191,13 +188,7 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, else open_flags |= O_WRONLY; - if (log_type == LOG_BIN && !index_file_name[0]) - fn_format(index_file_name, name, mysql_data_home, ".index", 6); - db[0]=0; - do_magic = ((log_type == LOG_BIN) && !my_stat(log_file_name, - &tmp_stat, MYF(0))); - open_count++; if ((file=my_open(log_file_name,open_flags, MYF(MY_WME | ME_WAITTANG))) < 0 || @@ -205,7 +196,8 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, my_tell(file,MYF(MY_WME)), 0, MYF(MY_WME | MY_NABP))) goto err; - if (log_type == LOG_NORMAL) + switch (log_type) { + case LOG_NORMAL: { char *end; #ifdef __NT__ @@ -217,8 +209,9 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, if (my_b_write(&log_file, (byte*) buff,(uint) (end-buff)) || flush_io_cache(&log_file)) goto err; + break; } - else if (log_type == LOG_NEW) + case LOG_NEW: { time_t skr=time(NULL); struct tm tm_tmp; @@ -234,49 +227,98 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, if (my_b_write(&log_file, (byte*) buff,(uint) strlen(buff)) || flush_io_cache(&log_file)) goto err; + break; } - else if (log_type == LOG_BIN) + case LOG_BIN: { - bool error; - if (do_magic) + bool write_file_name_to_index_file=0; + + myf opt= MY_UNPACK_FILENAME; + if (!index_file_name_arg) + { + index_file_name_arg= name; // Use same basename for index file + opt= MY_UNPACK_FILENAME | MY_REPLACE_EXT; + } + + if (!my_b_filelength(&log_file)) { - if (my_b_write(&log_file, (byte*) BINLOG_MAGIC, BIN_LOG_HEADER_SIZE) || - open_index(O_APPEND | O_RDWR | O_CREAT)) + /* + The binary log file was empty (probably newly created) + This is the normal case and happens when the user doesn't specify + an extension for the binary log files. + In this case we write a standard header to it. + */ + if (my_b_write(&log_file, (byte*) BINLOG_MAGIC, BIN_LOG_HEADER_SIZE)) goto err; bytes_written += BIN_LOG_HEADER_SIZE; + write_file_name_to_index_file=1; } + if (!my_b_inited(&index_file)) + { + /* + First open of this class instance + Create an index file that will hold all file names uses for logging. + Add new entries to the end of it. + */ + fn_format(index_file_name, index_file_name_arg, mysql_data_home, + ".index", opt); + if ((index_file_nr= my_open(index_file_name, + O_RDWR | O_CREAT | O_BINARY , + MYF(MY_WME))) < 0 || + init_io_cache(&index_file, index_file_nr, + IO_SIZE, WRITE_CACHE, + my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)), + 0, MYF(MY_WME))) + goto err; + } + else + { + safe_mutex_assert_owner(&LOCK_index); + reinit_io_cache(&index_file, WRITE_CACHE, my_b_filelength(&index_file), + 0, 0); + } if (need_start_event && !no_auto_events) { + need_start_event=0; Start_log_event s; s.set_log_pos(this); s.write(&log_file); - need_start_event=0; } - flush_io_cache(&log_file); - pthread_mutex_lock(&LOCK_index); - error=(my_write(index_file, (byte*) log_file_name, strlen(log_file_name), - MYF(MY_NABP | MY_WME)) || - my_write(index_file, (byte*) "\n", 1, MYF(MY_NABP | MY_WME))); - pthread_mutex_unlock(&LOCK_index); - if (error) - { - close_index(); + if (flush_io_cache(&log_file)) goto err; + + if (write_file_name_to_index_file) + { + /* As this is a new log file, we write the file name to the index file */ + if (my_b_write(&index_file, (byte*) log_file_name, + strlen(log_file_name)) || + my_b_write(&index_file, (byte*) "\n", 1) || + flush_io_cache(&index_file)) + goto err; } + break; } - DBUG_VOID_RETURN; + case LOG_CLOSED: // Impossible + DBUG_ASSERT(1); + break; + } + DBUG_RETURN(0); err: - sql_print_error("Could not use %s for logging (error %d)", log_name,errno); + sql_print_error("Could not use %s for logging (error %d)", log_name, errno); if (file >= 0) my_close(file,MYF(0)); + if (index_file_nr >= 0) + my_close(index_file_nr,MYF(0)); end_io_cache(&log_file); - x_free(name); name=0; + end_io_cache(&index_file); + safeFree(name); log_type=LOG_CLOSED; - DBUG_VOID_RETURN; + DBUG_RETURN(1); } + int MYSQL_LOG::get_current_log(LOG_INFO* linfo) { pthread_mutex_lock(&LOCK_log); @@ -286,107 +328,231 @@ int MYSQL_LOG::get_current_log(LOG_INFO* linfo) return 0; } -// if log_name is "" we stop at the first entry -int MYSQL_LOG::find_first_log(LOG_INFO* linfo, const char* log_name, - bool need_mutex) +/* + Move all data up in a file in an filename index file + + SYNOPSIS + copy_up_file_and_fill() + index_file File to move + offset Move everything from here to beginning + + NOTE + File will be truncated to be 'offset' shorter or filled up with + newlines + + IMPLEMENTATION + We do the copy outside of the IO_CACHE as the cache buffers would just + make things slower and more complicated. + In most cases the copy loop should only do one read. + + RETURN VALUES + 0 ok +*/ + +static bool copy_up_file_and_fill(IO_CACHE *index_file, my_off_t offset) { - if (index_file < 0) - return LOG_INFO_INVALID; - int error = 0; - char* fname = linfo->log_file_name; - uint log_name_len = (uint) strlen(log_name); - IO_CACHE io_cache; + int bytes_read; + my_off_t init_offset= offset; + File file= index_file->file; + byte io_buf[IO_SIZE*2]; + DBUG_ENTER("copy_up_file_and_fill"); + + for (;; offset+= bytes_read) + { + (void) my_seek(file, offset, MY_SEEK_SET, MYF(0)); + if ((bytes_read= (int) my_read(file, io_buf, sizeof(io_buf), MYF(MY_WME))) + < 0) + goto err; + if (!bytes_read) + break; // end of file + (void) my_seek(file, offset-init_offset, MY_SEEK_SET, MYF(0)); + if (my_write(file, (byte*) io_buf, bytes_read, MYF(MY_WME | MY_NABP))) + goto err; + } + /* The following will either truncate the file or fill the end with \n' */ + if (my_chsize(file, offset - init_offset, '\n', MYF(MY_WME))) + goto err; + + /* Reset data in old index cache */ + reinit_io_cache(index_file, READ_CACHE, (my_off_t) 0, 0, 1); + DBUG_RETURN(0); + +err: + DBUG_RETURN(1); +} + + +/* + Find the position in the log-index-file for the given log name + + SYNOPSIS + find_log_pos() + linfo Store here the found log file name and position to + the NEXT log file name in the index file. + log_name Filename to find in the index file. + Is a null pointer if we want to read the first entry + need_mutex Set this to 1 if the parent doesn't already have a + lock on LOCK_index + + NOTE + On systems without the truncate function the file will end with one ore + more empty lines + + RETURN VALUES + 0 ok + LOG_INFO_EOF End of log-index-file found + LOG_INFO_IO Got IO error while reading file +*/ + +int MYSQL_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name, + bool need_lock) +{ + int error= 0; + char *fname= linfo->log_file_name; + uint log_name_len= log_name ? (uint) strlen(log_name) : 0; + DBUG_ENTER("find_log_pos"); + DBUG_PRINT("enter",("log_name: %s", log_name ? log_name : "NULL")); /* Mutex needed because we need to make sure the file pointer does not move from under our feet */ - if (need_mutex) + if (need_lock) pthread_mutex_lock(&LOCK_index); - if (init_io_cache(&io_cache, index_file, IO_SIZE, READ_CACHE, (my_off_t) 0, - 0, MYF(MY_WME))) - { - error = LOG_INFO_SEEK; - goto err; - } + safe_mutex_assert_owner(&LOCK_index); + + /* As the file is flushed, we can't get an error here */ + (void) reinit_io_cache(&index_file, READ_CACHE, (my_off_t) 0, 0, 0); + for (;;) { uint length; - if (!(length=my_b_gets(&io_cache, fname, FN_REFLEN-1))) + my_off_t offset= my_b_tell(&index_file); + /* If we get 0 or 1 characters, this is the end of the file */ + + if ((length= my_b_gets(&index_file, fname, FN_REFLEN)) <= 1) { - error = !io_cache.error ? LOG_INFO_EOF : LOG_INFO_IO; - goto err; + /* Did not find the given entry; Return not found or error */ + error= !index_file.error ? LOG_INFO_EOF : LOG_INFO_IO; + break; } - // if the log entry matches, empty string matching anything - if (!log_name_len || + // if the log entry matches, null string matching anything + if (!log_name || (log_name_len == length-1 && fname[log_name_len] == '\n' && !memcmp(fname, log_name, log_name_len))) { + DBUG_PRINT("info",("Found log file entry")); fname[length-1]=0; // remove last \n - linfo->index_file_offset = my_b_tell(&io_cache); + linfo->index_file_start_offset= offset; + linfo->index_file_offset = my_b_tell(&index_file); break; } } - error = 0; err: - if (need_mutex) + if (need_lock) pthread_mutex_unlock(&LOCK_index); - end_io_cache(&io_cache); - return error; - + DBUG_RETURN(error); } +/* + Find the position in the log-index-file for the given log name + + SYNOPSIS + find_next_log() + linfo Store here the next log file name and position to + the file name after that. + need_lock Set this to 1 if the parent doesn't already have a + lock on LOCK_index + + NOTE + - Before calling this function, one has to call find_log_pos() + to set up 'linfo' + - Mutex needed because we need to make sure the file pointer does not move + from under our feet + + RETURN VALUES + 0 ok + LOG_INFO_EOF End of log-index-file found + LOG_INFO_SEEK Could not allocate IO cache + LOG_INFO_IO Got IO error while reading file +*/ + int MYSQL_LOG::find_next_log(LOG_INFO* linfo, bool need_lock) { - /* - Mutex needed because we need to make sure the file pointer does not move - from under our feet - */ - if (index_file < 0) - return LOG_INFO_INVALID; - int error = 0; - char* fname = linfo->log_file_name; - IO_CACHE io_cache; + int error= 0; uint length; + char *fname= linfo->log_file_name; + if (need_lock) pthread_mutex_lock(&LOCK_index); - if (init_io_cache(&io_cache, index_file, IO_SIZE, - READ_CACHE, (my_off_t) linfo->index_file_offset, 0, - MYF(MY_WME))) - { - error = LOG_INFO_SEEK; - goto err; - } - if (!(length=my_b_gets(&io_cache, fname, FN_REFLEN))) + safe_mutex_assert_owner(&LOCK_index); + + /* As the file is flushed, we can't get an error here */ + (void) reinit_io_cache(&index_file, READ_CACHE, linfo->index_file_offset, 0, + 0); + + linfo->index_file_start_offset= linfo->index_file_offset; + if ((length=my_b_gets(&index_file, fname, FN_REFLEN)) <= 1) { - error = !io_cache.error ? LOG_INFO_EOF : LOG_INFO_IO; + error = !index_file.error ? LOG_INFO_EOF : LOG_INFO_IO; goto err; } fname[length-1]=0; // kill /n - linfo->index_file_offset = my_b_tell(&io_cache); - error = 0; + linfo->index_file_offset = my_b_tell(&index_file); err: if (need_lock) pthread_mutex_unlock(&LOCK_index); - end_io_cache(&io_cache); return error; } -int MYSQL_LOG::reset_logs(THD* thd) +/* + Delete all logs refered to in the index file + Start writing to a new log file. The new index file will only contain + this file. + + SYNOPSIS + reset_logs() + thd Thread + + NOTE + If not called from slave thread, write start event to new log + + + RETURN VALUES + 0 ok + 1 error +*/ + +bool MYSQL_LOG::reset_logs(THD* thd) { LOG_INFO linfo; - int error=0; + bool error=0; const char* save_name; enum_log_type save_log_type; + DBUG_ENTER("reset_logs"); + /* + We need to get both locks to be sure that no one is trying to + write to the index log file. + */ pthread_mutex_lock(&LOCK_log); - if (find_first_log(&linfo,"")) + pthread_mutex_lock(&LOCK_index); + + /* Save variables so that we can reopen the log */ + save_name=name; + name=0; // Protect against free + save_log_type=log_type; + close(0); // Don't close the index file + + /* First delete all old log files */ + + if (find_log_pos(&linfo, NullS, 0)) { error=1; goto err; @@ -395,27 +561,58 @@ int MYSQL_LOG::reset_logs(THD* thd) for (;;) { my_delete(linfo.log_file_name, MYF(MY_WME)); - if (find_next_log(&linfo)) + if (find_next_log(&linfo, 0)) break; } - save_name=name; - name=0; - save_log_type=log_type; - close(1); - my_delete(index_file_name, MYF(MY_WME)); - if (thd && !thd->slave_thread) + + /* Start logging with a new file */ + close(1); // Close index file + my_delete(index_file_name, MYF(MY_WME)); // Reset (open will update) + if (!thd->slave_thread) need_start_event=1; - open(save_name,save_log_type,0,io_cache_type,no_auto_events); - my_free((gptr)save_name,MYF(0)); + open(save_name, save_log_type, 0, index_file_name, + io_cache_type, no_auto_events); + my_free((gptr) save_name, MYF(0)); err: + pthread_mutex_unlock(&LOCK_index); pthread_mutex_unlock(&LOCK_log); - return error; + DBUG_RETURN(error); } +/* + Delete the current log file, remove it from index file and start on next + + SYNOPSIS + purge_first_log() + rli Relay log information + + NOTE + - This is only called from the slave-execute thread when it has read + all commands from a log and want to switch to a new log. + - When this happens, we should never be in an active transaction as + a transaction is always written as a single block to the binary log. + + IMPLEMENTATION + - Protects index file with LOCK_index + - Delete first log file, + - Copy all file names after this one to the front of the index file + - If the OS has truncate, truncate the file, else fill it with \n' + - Read the first file name from the index file and store in rli->linfo + + RETURN VALUES + 0 ok + 1 error +*/ + int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli) { + File file; + bool error= 1; + my_off_t offset, init_offset; + DBUG_ENTER("purge_first_log"); + /* Test pre-conditions. @@ -423,330 +620,248 @@ int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli) stored it in rli->relay_log_name */ DBUG_ASSERT(is_open()); - DBUG_ASSERT(index_file >= 0); DBUG_ASSERT(rli->slave_running == 1); DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->relay_log_name)); DBUG_ASSERT(rli->linfo.index_file_offset == strlen(rli->relay_log_name) + 1); - int tmp_fd; - char* fname, *io_buf; - int error = 0; - - if (!(fname= (char*) my_malloc(IO_SIZE+FN_REFLEN, MYF(MY_WME)))) - return 1; + /* We have already processed the relay log, so it's safe to delete it */ + my_delete(rli->relay_log_name, MYF(0)); pthread_mutex_lock(&LOCK_index); - my_seek(index_file,rli->linfo.index_file_offset, - MY_SEEK_SET, MYF(MY_WME)); - io_buf = fname + FN_REFLEN; - strxmov(fname,rli->relay_log_name,".tmp",NullS); - - if ((tmp_fd = my_open(fname,O_CREAT|O_BINARY|O_RDWR, MYF(MY_WME))) < 0) + if (copy_up_file_and_fill(&index_file, rli->linfo.index_file_offset)) { - error = 1; + error= LOG_INFO_IO; goto err; } - for (;;) - { - int bytes_read; - bytes_read = my_read(index_file, (byte*) io_buf, IO_SIZE, MYF(0)); - if (bytes_read < 0) // error - { - error=1; - goto err; - } - if (!bytes_read) - break; // end of file - // otherwise, we've read something and need to write it out - if (my_write(tmp_fd, (byte*) io_buf, bytes_read, MYF(MY_WME|MY_NABP))) - { - error=1; - goto err; - } - } -err: - if (tmp_fd) - my_close(tmp_fd, MYF(MY_WME)); - if (error) - my_delete(fname, MYF(0)); // do not report error if the file is not there - else - { - MY_STAT s; - my_close(index_file, MYF(MY_WME)); - if (!my_stat(rli->relay_log_name,&s,MYF(0))) - { - sql_print_error("The first log %s failed to stat during purge", - rli->relay_log_name); - error=1; - goto err; - } - if (my_rename(fname,index_file_name,MYF(MY_WME)) || - (index_file=my_open(index_file_name,O_BINARY|O_RDWR|O_APPEND, - MYF(MY_WME)))<0 || - my_delete(rli->relay_log_name, MYF(MY_WME))) - error=1; - - pthread_mutex_lock(&rli->log_space_lock); - rli->log_space_total -= s.st_size; - pthread_mutex_unlock(&rli->log_space_lock); - /* - Ok to broadcast after the critical region as there is no risk of - the mutex being destroyed by this thread later - this helps save - context switches - */ - pthread_cond_broadcast(&rli->log_space_cond); - - if ((error=find_first_log(&rli->linfo,"",0/*no mutex*/))) - { - char buff[22]; - sql_print_error("next log error=%d,offset=%s,log=%s",error, - llstr(rli->linfo.index_file_offset,buff), - rli->linfo.log_file_name); - goto err2; - } - rli->relay_log_pos = BIN_LOG_HEADER_SIZE; - strmake(rli->relay_log_name,rli->linfo.log_file_name, - sizeof(rli->relay_log_name)-1); - flush_relay_log_info(rli); - } /* - No need to free io_buf because we allocated both fname and io_buf in - one malloc() + Update the space counter used by all relay logs + Ok to broadcast after the critical region as there is no risk of + the mutex being destroyed by this thread later - this helps save + context switches */ + pthread_mutex_lock(&rli->log_space_lock); + rli->log_space_total -= rli->relay_log_pos; + pthread_mutex_unlock(&rli->log_space_lock); + pthread_cond_broadcast(&rli->log_space_cond); + + /* + Read the next log file name from the index file and pass it back to + the caller + */ + if ((error=find_log_pos(&rli->linfo, NullS, 0 /*no mutex*/))) + { + char buff[22]; + sql_print_error("next log error: %d offset: %s log: %s", + error, + llstr(rli->linfo.index_file_offset,buff), + rli->linfo.log_file_name); + goto err; + } + rli->relay_log_pos = BIN_LOG_HEADER_SIZE; + strmake(rli->relay_log_name,rli->linfo.log_file_name, + sizeof(rli->relay_log_name)-1); + + /* Store where we are in the new file for the execution thread */ + flush_relay_log_info(rli); -err2: +err: pthread_mutex_unlock(&LOCK_index); - my_free(fname, MYF(MY_WME)); - return error; + DBUG_RETURN(error); } +/* + Remove all logs before the given log from disk and from the index file. + + SYNOPSIS + purge_logs() + thd Thread pointer + to_log Delete all log file name before this file. This file is not + deleted + + NOTES + If any of the logs before the deleted one is in use, + only purge logs up to this one. + + RETURN VALUES + 0 ok + LOG_INFO_PURGE_NO_ROTATE Binary file that can't be rotated + LOG_INFO_EOF to_log not found +*/ + int MYSQL_LOG::purge_logs(THD* thd, const char* to_log) { int error; - char fname[FN_REFLEN]; - char *p; - uint fname_len, i; - bool logs_to_purge_inited = 0, logs_to_keep_inited = 0, found_log = 0; - DYNAMIC_ARRAY logs_to_purge, logs_to_keep; - my_off_t purge_offset ; - LINT_INIT(purge_offset); - IO_CACHE io_cache; - - if (index_file < 0) - return LOG_INFO_INVALID; + LOG_INFO log_info; + DBUG_ENTER("purge_logs"); + if (no_rotate) - return LOG_INFO_PURGE_NO_ROTATE; + DBUG_RETURN(LOG_INFO_PURGE_NO_ROTATE); + pthread_mutex_lock(&LOCK_index); - - if (init_io_cache(&io_cache,index_file, IO_SIZE*2, READ_CACHE, (my_off_t) 0, - 0, MYF(MY_WME))) - { - error = LOG_INFO_MEM; + if ((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/))) goto err; - } - if (my_init_dynamic_array(&logs_to_purge, sizeof(char*), 1024, 1024)) - { - error = LOG_INFO_MEM; - goto err; - } - logs_to_purge_inited = 1; - - if (my_init_dynamic_array(&logs_to_keep, sizeof(char*), 1024, 1024)) - { - error = LOG_INFO_MEM; - goto err; - } - logs_to_keep_inited = 1; - - for (;;) - { - my_off_t init_purge_offset= my_b_tell(&io_cache); - if (!(fname_len=my_b_gets(&io_cache, fname, FN_REFLEN))) - { - if (!io_cache.error) - break; - error = LOG_INFO_IO; - goto err; - } - fname[--fname_len]=0; // kill \n - if (!memcmp(fname, to_log, fname_len + 1 )) - { - found_log = 1; - purge_offset = init_purge_offset; - } - - // if one of the logs before the target is in use - if (!found_log && log_in_use(fname)) - { - error = LOG_INFO_IN_USE; - goto err; - } - - if (!(p = sql_memdup(fname, fname_len+1)) || - insert_dynamic(found_log ? &logs_to_keep : &logs_to_purge, - (gptr) &p)) - { - error = LOG_INFO_MEM; - goto err; - } - } - - end_io_cache(&io_cache); - if (!found_log) - { - error = LOG_INFO_EOF; + /* + File name exists in index file; Delete until we find this file + or a file that is used. + */ + if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/))) goto err; - } - - for (i = 0; i < logs_to_purge.elements; i++) + while (strcmp(to_log,log_info.log_file_name) && + !log_in_use(log_info.log_file_name)) { - char* l; - get_dynamic(&logs_to_purge, (gptr)&l, i); - if (my_delete(l, MYF(MY_WME))) - sql_print_error("Error deleting %s during purge", l); + /* It's not fatal even if we can't delete a log file */ + my_delete(log_info.log_file_name, MYF(0)); + if (find_next_log(&log_info, 0)) + break; } - + /* If we get killed -9 here, the sysadmin would have to edit the log index file after restart - otherwise, this should be safe */ -#ifdef HAVE_FTRUNCATE - if (ftruncate(index_file,0)) - { - sql_print_error("Could not truncate the binlog index file \ -during log purge for write"); - error = LOG_INFO_FATAL; - goto err; - } - my_seek(index_file, 0, MY_SEEK_CUR,MYF(MY_WME)); -#else - my_close(index_file, MYF(MY_WME)); - my_delete(index_file_name, MYF(MY_WME)); - if ((index_file = my_open(index_file_name, - O_CREAT | O_BINARY | O_RDWR | O_APPEND, - MYF(MY_WME)))<0) + + if (copy_up_file_and_fill(&index_file, log_info.index_file_start_offset)) { - sql_print_error("Could not re-open the binlog index file \ -during log purge for write"); - error = LOG_INFO_FATAL; + error= LOG_INFO_IO; goto err; } -#endif - - for (i = 0; i < logs_to_keep.elements; i++) - { - char* l; - get_dynamic(&logs_to_keep, (gptr)&l, i); - if (my_write(index_file, (byte*) l, strlen(l), MYF(MY_WME|MY_NABP)) || - my_write(index_file, (byte*) "\n", 1, MYF(MY_WME|MY_NABP))) - { - error = LOG_INFO_FATAL; - goto err; - } - } - // now update offsets - adjust_linfo_offsets(purge_offset); - error = 0; + // now update offsets in index file for running threads + adjust_linfo_offsets(log_info.index_file_start_offset); err: pthread_mutex_unlock(&LOCK_index); - if (logs_to_purge_inited) - delete_dynamic(&logs_to_purge); - if (logs_to_keep_inited) - delete_dynamic(&logs_to_keep); - end_io_cache(&io_cache); - return error; + DBUG_RETURN(error); } -// we assume that buf has at least FN_REFLEN bytes alloced + +/* + Create a new log file name + + SYNOPSIS + make_log_name() + buf buf of at least FN_REFLEN where new name is stored + + NOTE + If file name will be longer then FN_REFLEN it will be truncated +*/ + void MYSQL_LOG::make_log_name(char* buf, const char* log_ident) { - buf[0] = 0; // In case of error - if (inited) + if (inited) // QQ When is this not true ? { - int dir_len = dirname_length(log_file_name); - int ident_len = (uint) strlen(log_ident); - if (dir_len + ident_len + 1 > FN_REFLEN) - return; // protection agains malicious buffer overflow - - memcpy(buf, log_file_name, dir_len); - // copy filename + end null - memcpy(buf + dir_len, log_ident, ident_len + 1); + uint dir_len = dirname_length(log_file_name); + if (dir_len > FN_REFLEN) + dir_len=FN_REFLEN-1; + strnmov(buf, log_file_name, dir_len); + strmake(buf+dir_len, log_ident, FN_REFLEN - dir_len); } } -bool MYSQL_LOG::is_active(const char* log_file_name) + +/* + Check if we are writing/reading to the given log file +*/ + +bool MYSQL_LOG::is_active(const char *log_file_name_arg) { - return inited && !strcmp(log_file_name, this->log_file_name); + return inited && !strcmp(log_file_name, log_file_name_arg); } -void MYSQL_LOG::new_file(bool inside_mutex) + +/* + Start writing to a new log file or reopen the old file + + SYNOPSIS + new_file() + need_lock Set to 1 (default) if caller has not locked + LOCK_log and LOCK_index + + NOTE + The new file name is stored last in the index file +*/ + +void MYSQL_LOG::new_file(bool need_lock) { - if (is_open()) + char new_name[FN_REFLEN], *new_name_ptr, *old_name; + enum_log_type save_log_type; + + if (!is_open()) + return; // Should never happen + + if (need_lock) { - char new_name[FN_REFLEN], *old_name=name; - if (!inside_mutex) - VOID(pthread_mutex_lock(&LOCK_log)); + pthread_mutex_lock(&LOCK_log); + pthread_mutex_lock(&LOCK_index); + } + safe_mutex_assert_owner(&LOCK_log); + safe_mutex_assert_owner(&LOCK_index); - if (!no_rotate) + new_name_ptr= name; // Reuse old name if not binlog + + /* + Only rotate open logs that are marked non-rotatable + (binlog with constant name are non-rotatable) + */ + if (!no_rotate) + { + if (log_type == LOG_BIN) { - /* - Only rotate open logs that are marked non-rotatable - (binlog with constant name are non-rotatable) - */ if (generate_new_name(new_name, name)) { - if (!inside_mutex) + /* Error; Continue using old log file */ + if (need_lock) VOID(pthread_mutex_unlock(&LOCK_log)); return; // Something went wrong } - if (log_type == LOG_BIN) + new_name_ptr=new_name; + if (!no_auto_events) { - if (!no_auto_events) - { - /* - We log the whole file name for log file as the user may decide - to change base names at some point. - */ - THD* thd = current_thd; - Rotate_log_event r(thd,new_name+dirname_length(new_name)); - r.set_log_pos(this); - - /* - This log rotation could have been initiated by a master of - the slave running with log-bin we set the flag on rotate - event to prevent inifinite log rotation loop - */ - if (thd && thd->slave_thread) - r.flags |= LOG_EVENT_FORCED_ROTATE_F; - r.write(&log_file); - bytes_written += r.get_event_len(); - } /* - Update needs to be signaled even if there is no rotate event - log rotation should give the waiting thread a signal to - discover EOF and move on to the next log. + We log the whole file name for log file as the user may decide + to change base names at some point. */ - signal_update(); + THD* thd = current_thd; + Rotate_log_event r(thd,new_name+dirname_length(new_name)); + r.set_log_pos(this); + + /* + Becasue this log rotation could have been initiated by a master of + the slave running with log-bin, we set the flag on rotate + event to prevent inifinite log rotation loop + */ + if (thd->slave_thread) + r.flags|= LOG_EVENT_FORCED_ROTATE_F; + r.write(&log_file); + bytes_written += r.get_event_len(); } - else - strmov(new_name, old_name); // Reopen old file name + /* + Update needs to be signaled even if there is no rotate event + log rotation should give the waiting thread a signal to + discover EOF and move on to the next log. + */ + signal_update(); } - name=0; - close(); - open(old_name, log_type, new_name, io_cache_type, no_auto_events); - my_free(old_name,MYF(0)); - last_time=query_start=0; - write_error=0; - if (!inside_mutex) - VOID(pthread_mutex_unlock(&LOCK_log)); + } + old_name=name; + save_log_type=log_type; + name=0; // Don't free name + close(); + open(old_name, save_log_type, new_name_ptr, index_file_name, io_cache_type, + no_auto_events); + my_free(old_name,MYF(0)); + + if (need_lock) + { + pthread_mutex_unlock(&LOCK_index); + pthread_mutex_unlock(&LOCK_log); } } + bool MYSQL_LOG::append(Log_event* ev) { bool error = 0; @@ -763,21 +878,23 @@ bool MYSQL_LOG::append(Log_event* ev) goto err; } bytes_written += ev->get_event_len(); - if ((uint)my_b_append_tell(&log_file) > max_binlog_size) + if ((uint) my_b_append_tell(&log_file) > max_binlog_size) { - new_file(1); + pthread_mutex_lock(&LOCK_index); + new_file(0); + pthread_mutex_unlock(&LOCK_index); } - signal_update(); err: pthread_mutex_unlock(&LOCK_log); + signal_update(); // Safe as we don't call close return error; } bool MYSQL_LOG::appendv(const char* buf, uint len,...) { - bool error = 0; + bool error= 0; va_list(args); va_start(args,len); @@ -788,24 +905,32 @@ bool MYSQL_LOG::appendv(const char* buf, uint len,...) { if (my_b_append(&log_file,(byte*) buf,len)) { - error = 1; - break; + error= 1; + goto err; } bytes_written += len; } while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint))); if ((uint) my_b_append_tell(&log_file) > max_binlog_size) { - new_file(1); + pthread_mutex_lock(&LOCK_index); + new_file(0); + pthread_mutex_unlock(&LOCK_index); } - + +err: + pthread_mutex_unlock(&LOCK_log); if (!error) signal_update(); - pthread_mutex_unlock(&LOCK_log); return error; } +/* + Write to normal (not rotable) log + This is the format for the 'normal', 'slow' and 'update' logs. +*/ + bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, const char *format,...) { @@ -886,13 +1011,18 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, } +/* + Write an event to the binary log +*/ + bool MYSQL_LOG::write(Log_event* event_info) { bool error=0; if (!inited) // Can't use mutex if not init return 0; - VOID(pthread_mutex_lock(&LOCK_log)); + pthread_mutex_lock(&LOCK_log); + /* In most cases this is only called if 'is_open()' is true */ if (is_open()) { @@ -900,7 +1030,7 @@ bool MYSQL_LOG::write(Log_event* event_info) THD *thd=event_info->thd; const char* db = event_info->get_db(); #ifdef USING_TRANSACTIONS - IO_CACHE *file = ((event_info->get_cache_stmt() && thd) ? + IO_CACHE *file = ((event_info->get_cache_stmt()) ? &thd->transaction.trans_log : &log_file); #else @@ -942,14 +1072,10 @@ bool MYSQL_LOG::write(Log_event* event_info) char buf[1024] = "SET CHARACTER SET "; char* p = strend(buf); p = strmov(p, thd->variables.convert_set->name); - int save_query_length = thd->query_length; - // just in case somebody wants it later - thd->query_length = (uint)(p - buf); - Query_log_event e(thd, buf); + Query_log_event e(thd, buf, (ulong)(p - buf)); e.set_log_pos(this); if (e.write(file)) goto err; - thd->query_length = save_query_length; // clean up } event_info->set_log_pos(this); if (event_info->write(file) || @@ -986,12 +1112,18 @@ err: if (file == &log_file) signal_update(); if (should_rotate) - new_file(1); // inside mutex + { + pthread_mutex_lock(&LOCK_index); + new_file(0); // inside mutex + pthread_mutex_unlock(&LOCK_index); + } } - VOID(pthread_mutex_unlock(&LOCK_log)); + + pthread_mutex_unlock(&LOCK_log); return error; } + uint MYSQL_LOG::next_file_id() { uint res; @@ -1001,74 +1133,102 @@ uint MYSQL_LOG::next_file_id() return res; } + /* Write a cached log entry to the binary log - We only come here if there is something in the cache. - 'cache' needs to be reinitialized after this functions returns. + + NOTE + - We only come here if there is something in the cache. + - The thing in the cache is always a complete transcation + - 'cache' needs to be reinitialized after this functions returns. + + IMPLEMENTATION + - To support transaction over replication, we wrap the transaction + with BEGIN/COMMIT in the binary log. */ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache) { VOID(pthread_mutex_lock(&LOCK_log)); - bool error=1; - if (is_open()) + if (is_open()) // Should always be true { + uint length; + /* - We come here when the queries to be logged could not fit into memory - and part of the queries are stored in a log file on disk. + Add the "BEGIN" and "COMMIT" in the binlog around transactions + which may contain more than 1 SQL statement. If we run with + AUTOCOMMIT=1, then MySQL immediately writes each SQL statement to + the binlog when the statement has been completed. No need to add + "BEGIN" ... "COMMIT" around such statements. Otherwise, MySQL uses + thd->transaction.trans_log to cache the SQL statements until the + explicit commit, and at the commit writes the contents in .trans_log + to the binlog. + + We write the "BEGIN" mark first in the buffer (.trans_log) where we + store the SQL statements for a transaction. At the transaction commit + we will add the "COMMIT mark and write the buffer to the binlog. */ - - uint length; + { + Query_log_event qinfo(thd, "BEGIN", 5, TRUE); + if (qinfo.write(&log_file)) + goto err; + } /* Read from the file used to cache the queries .*/ if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0)) - { - sql_print_error(ER(ER_ERROR_ON_WRITE), cache->file_name, errno); goto err; - } length=my_b_bytes_in_cache(cache); do { /* Write data to the binary log file */ if (my_b_write(&log_file, cache->read_pos, length)) - { - if (!write_error) - sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno); goto err; - } cache->read_pos=cache->read_end; // Mark buffer used up } while ((length=my_b_fill(cache))); - if (flush_io_cache(&log_file)) + + /* + We write the command "COMMIT" as the last SQL command in the + binlog segment cached for this transaction + */ + { - if (!write_error) - sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno); - goto err; + Query_log_event qinfo(thd, "COMMIT", 6, TRUE); + if (qinfo.write(&log_file) || flush_io_cache(&log_file)) + goto err; } if (cache->error) // Error on read { sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, errno); + write_error=1; // Don't give more errors goto err; } - error = ha_report_binlog_offset_and_commit(thd, log_file_name, - log_file.pos_in_file); - if (error) + if ((ha_report_binlog_offset_and_commit(thd, log_file_name, + log_file.pos_in_file))) goto err; + signal_update(); } - error=0; + VOID(pthread_mutex_unlock(&LOCK_log)); + return 0; err: - if (error) - write_error=1; - else - signal_update(); - + if (!write_error) + { + write_error= 1; + sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno); + } VOID(pthread_mutex_unlock(&LOCK_log)); - - return error; + return 1; } -/* Write update log in a format suitable for incremental backup */ +/* + Write update log in a format suitable for incremental backup + + NOTE + - This code should be deleted in MySQL 5,0 as the binary log + is a full replacement for the update log. + +*/ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, time_t query_start) @@ -1190,30 +1350,42 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, return error; } +/* + Wait until we get a signal that the binary log has been updated + + SYNOPSIS + wait_for_update() + thd Thread variable + + NOTES + One must have a lock on LOCK_log before calling this function. +*/ + + void MYSQL_LOG:: wait_for_update(THD* thd) { const char* old_msg = thd->enter_cond(&update_cond, &LOCK_log, "Slave: waiting for binlog update"); pthread_cond_wait(&update_cond, &LOCK_log); - /* - This is not a bug: - We unlock the mutex for the caller, and expect him to lock it and - then not unlock it upon return. This is a rather odd way of doing - things, but this is the cleanest way I could think of to solve the - race deadlock caused by THD::awake() first acquiring mysys_var - mutex and then the current mutex, while wait_for_update being - called with the current mutex already aquired and THD::exit_cond() - trying to acquire mysys_var mutex. We do need the mutex to be - acquired prior to the invocation of wait_for_update in all cases, - so mutex acquisition inside wait_for_update() is not an option. - */ - pthread_mutex_unlock(&LOCK_log); thd->exit_cond(old_msg); } +/* + Close the log file + + SYNOPSIS + close() + exiting Set to 1 if we should also close the index file + This can be set to 0 if we are going to do call open + at once after close, in which case we don't want to + close the index file. +*/ + void MYSQL_LOG::close(bool exiting) { // One can't set log_type here! + DBUG_ENTER("MYSQL_LOG::close"); + DBUG_PRINT("enter",("exiting: %d", (int) exiting)); if (is_open()) { if (log_type == LOG_BIN && !no_auto_events) @@ -1227,28 +1399,46 @@ void MYSQL_LOG::close(bool exiting) if (my_close(log_file.file,MYF(0)) < 0 && ! write_error) { write_error=1; - sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno); + sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno); } } - if (exiting && index_file >= 0) + + /* + The following test is needed even if is_open() is not set, as we may have + called a not complete close earlier and the index file is still open. + */ + + if (exiting && my_b_inited(&index_file)) { - if (my_close(index_file,MYF(0)) < 0 && ! write_error) + end_io_cache(&index_file); + if (my_close(index_file.file, MYF(0)) < 0 && ! write_error) { - write_error=1; - sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno); + write_error= 1; + sql_print_error(ER(ER_ERROR_ON_WRITE), index_file_name, errno); } - index_file=-1; - log_type=LOG_CLOSED; } + log_type= LOG_CLOSED; safeFree(name); + DBUG_VOID_RETURN; } /* Check if a string is a valid number - Return: - TRUE String is a number - FALSE Error + + SYNOPSIS + test_if_number() + str String to test + res Store value here + allow_wildcards Set to 1 if we should ignore '%' and '_' + + NOTE + For the moment the allow_wildcards argument is not used + Should be move to some other file. + + RETURN VALUES + 1 String is a number + 0 Error */ static bool test_if_number(register const char *str, @@ -1320,7 +1510,6 @@ void sql_print_error(const char *format,...) } - void sql_perror(const char *message) { #ifdef HAVE_STRERROR diff --git a/sql/log_event.cc b/sql/log_event.cc index 52e97310d75..afa821d0bb1 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -149,6 +149,14 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg) } } +/* + Delete all temporary files used for SQL_LOAD. + + TODO + - When we get a 'server start' event, we should only remove + the files associated with the server id that just started. + Easily fixable by adding server_id as a prefix to the log files. +*/ static void cleanup_load_tmpdir() { @@ -195,7 +203,7 @@ Log_event::Log_event(const char* buf, bool old_format) int Log_event::exec_event(struct st_relay_log_info* rli) { - if (rli) + if (rli) // QQ When is this not true ? { rli->inc_pos(get_event_len(),log_pos); DBUG_ASSERT(rli->sql_thd != 0); @@ -749,9 +757,9 @@ int Rotate_log_event::write_data(IO_CACHE* file) #ifndef MYSQL_CLIENT Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, - bool using_trans) + ulong query_length, bool using_trans) :Log_event(thd_arg), data_buf(0), query(query_arg), db(thd_arg->db), - q_len(thd_arg->query_length), + q_len((uint32) query_length), error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno), thread_id(thd_arg->thread_id), cache_stmt(using_trans && @@ -1267,7 +1275,7 @@ Slave_log_event::Slave_log_event(THD* thd_arg, Log_event(thd_arg),mem_pool(0),master_host(0) { DBUG_ENTER("Slave_log_event"); - if (!rli->inited) + if (!rli->inited) // QQ When can this happen ? DBUG_VOID_RETURN; MASTER_INFO* mi = rli->mi; @@ -1605,6 +1613,14 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) init_sql_alloc(&thd->mem_root, 8192,0); thd->db = rewrite_db((char*)db); DBUG_ASSERT(q_len == strlen(query)); + + /* + InnoDB internally stores the master log position it has processed so far; + position to store is really pos + pending + event_len + since we must store the pos of the END of the current log event + */ + rli->event_len= get_event_len(); + if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) { thd->query = (char*)query; @@ -1783,14 +1799,26 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli) } +/* + The master started + + IMPLEMENTATION + - To handle the case where the master died without a stop event, + we clean up all temporary tables + locks that we got. + + TODO + - Remove all active user locks + - If we have an active transaction at this point, the master died + in the middle while writing the transaction to the binary log. + In this case we should stop the slave. +*/ + int Start_log_event::exec_event(struct st_relay_log_info* rli) { + /* All temporary tables was deleted on the master */ close_temporary_tables(thd); /* If we have old format, load_tmpdir is cleaned up by the I/O thread - - TODO: cleanup_load_tmpdir() needs to remove only the files associated - with the server id that has just started */ if (!rli->mi->old_format) cleanup_load_tmpdir(); @@ -1798,6 +1826,14 @@ int Start_log_event::exec_event(struct st_relay_log_info* rli) } +/* + The master stopped. Clean up all temporary tables + locks that the + master may have set. + + TODO + - Remove all active user locks +*/ + int Stop_log_event::exec_event(struct st_relay_log_info* rli) { // do not clean up immediately after rotate event @@ -1808,16 +1844,35 @@ int Stop_log_event::exec_event(struct st_relay_log_info* rli) } /* We do not want to update master_log pos because we get a rotate event - before stop, so by now master_log_name is set to the next log - if we updated it, we will have incorrect master coordinates and this + before stop, so by now master_log_name is set to the next log. + If we updated it, we will have incorrect master coordinates and this could give false triggers in MASTER_POS_WAIT() that we have reached - the targed position when in fact we have not + the target position when in fact we have not. */ rli->inc_pos(get_event_len(), 0); flush_relay_log_info(rli); return 0; } + +/* + Got a rotate log even from the master + + IMPLEMENTATION + - Rotate the log file if the name of the log file changed + (In practice this should always be the case) + + TODO + - Investigate/Test if we can't ignore all rotate log events + that we get from the master (and not even write it to the local + binary log). + + RETURN VALUES + 0 ok + 1 Impossible new log file name (rotate log event is ignored) +*/ + + int Rotate_log_event::exec_event(struct st_relay_log_info* rli) { bool rotate_binlog = 0, write_slave_event = 0; @@ -1829,18 +1884,19 @@ int Rotate_log_event::exec_event(struct st_relay_log_info* rli) TODO: probably needs re-write rotate local binlog only if the name of remote has changed */ - if (!*log_name || !(log_name[ident_len] == 0 && - !memcmp(log_name, new_log_ident, ident_len))) + if (!*log_name || (memcmp(log_name, new_log_ident, ident_len) || + log_name[ident_len] != 0)) { - write_slave_event = (!(flags & LOG_EVENT_FORCED_ROTATE_F) - && mysql_bin_log.is_open()); + write_slave_event = (!(flags & LOG_EVENT_FORCED_ROTATE_F) && + mysql_bin_log.is_open()); rotate_binlog = (*log_name && write_slave_event); if (ident_len >= sizeof(rli->master_log_name)) { + // This should be impossible pthread_mutex_unlock(&rli->data_lock); DBUG_RETURN(1); } - memcpy(log_name, new_log_ident,ident_len); + memcpy(log_name, new_log_ident, ident_len); log_name[ident_len] = 0; } rli->master_log_pos = pos; @@ -1848,7 +1904,7 @@ int Rotate_log_event::exec_event(struct st_relay_log_info* rli) if (rotate_binlog) { mysql_bin_log.new_file(); - rli->master_log_pos = 4; + rli->master_log_pos = BIN_LOG_HEADER_SIZE; } DBUG_PRINT("info", ("master_log_pos: %d", (ulong) rli->master_log_pos)); pthread_cond_broadcast(&rli->data_cond); diff --git a/sql/log_event.h b/sql/log_event.h index 9b8145f14b0..b69643c366a 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -317,8 +317,8 @@ public: #ifndef MYSQL_CLIENT bool cache_stmt; - Query_log_event(THD* thd_arg, const char* query_arg, - bool using_trans=0); + Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length, + bool using_trans=0); const char* get_db() { return db; } void pack_info(String* packet); int exec_event(struct st_relay_log_info* rli); diff --git a/sql/mini_client.cc b/sql/mini_client.cc index a50bef4bbca..2b58430ef08 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -107,6 +107,8 @@ static my_bool is_NT(void) } #endif +extern ulong slave_net_timeout; + /* ** Create a named pipe connection */ @@ -197,6 +199,7 @@ MYSQL *mc_mysql_init(MYSQL *mysql) #ifdef __WIN__ mysql->options.connect_timeout=20; #endif + mysql->net.read_timeout = slave_net_timeout; return mysql; } @@ -413,7 +416,9 @@ my_bool mc_mysql_reconnect(MYSQL *mysql) mysql->client_flag, mysql->net.read_timeout)) { tmp_mysql.reconnect=0; - mc_mysql_close(&tmp_mysql); + mc_mysql_close(&tmp_mysql); + mysql->net.last_errno=CR_SERVER_GONE_ERROR; + strmov(mysql->net.last_error,ER(mysql->net.last_errno)); DBUG_RETURN(1); } tmp_mysql.free_me=mysql->free_me; @@ -504,11 +509,12 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user, struct sockaddr_un UNIXaddr; #endif DBUG_ENTER("mc_mysql_connect"); - - DBUG_PRINT("enter",("host: %s db: %s user: %s", + DBUG_PRINT("enter",("host: %s db: %s user: %s connect_time_out: %u read_timeout: %u", host ? host : "(Null)", db ? db : "(Null)", - user ? user : "(Null)")); + user ? user : "(Null)", + net_read_timeout, + (uint) slave_net_timeout)); thr_alarm_init(&alarmed); thr_alarm(&alarmed, net_read_timeout, &alarm_buff); @@ -652,7 +658,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user, goto error; } vio_keepalive(net->vio,TRUE); - + net->read_timeout=slave_net_timeout; /* Get version info */ mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */ if ((pkt_length=mc_net_safe_read(mysql)) == packet_error) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f34b2671175..a7c37059ecc 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -162,6 +162,7 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); #define OPTION_BIG_SELECTS 1024 /* for SQL OPTION */ #define OPTION_LOG_OFF 2048 #define OPTION_UPDATE_LOG 4096 /* update log flag */ +#define TMP_TABLE_ALL_COLUMNS 8192 #define OPTION_WARNINGS 16384 #define OPTION_AUTO_IS_NULL 32768 #define OPTION_FOUND_COMMENT 65536L @@ -176,14 +177,19 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); #define OPTION_INTERNAL_SUBTRANSACTIONS OPTION_QUOTE_SHOW_CREATE*2 /* Set if we are updating a non-transaction safe table */ -#define OPTION_STATUS_NO_TRANS_UPDATE OPTION_INTERNAL_SUBTRANSACTIONS*2 +#define OPTION_STATUS_NO_TRANS_UPDATE OPTION_INTERNAL_SUBTRANSACTIONS*2 /* The following is set when parsing the query */ #define QUERY_NO_INDEX_USED OPTION_STATUS_NO_TRANS_UPDATE*2 #define QUERY_NO_GOOD_INDEX_USED QUERY_NO_INDEX_USED*2 - -#define SELECT_NO_UNLOCK (QUERY_NO_GOOD_INDEX_USED*2) -#define TMP_TABLE_ALL_COLUMNS (SELECT_NO_UNLOCK*2) +/* The following can be set when importing tables in a 'wrong order' + to suppress foreign key checks */ +#define OPTION_NO_FOREIGN_KEY_CHECKS QUERY_NO_GOOD_INDEX_USED*2 +/* The following speeds up inserts to InnoDB tables by suppressing unique + key checks in some cases */ +#define OPTION_RELAXED_UNIQUE_CHECKS OPTION_NO_FOREIGN_KEY_CHECKS*2 +#define SELECT_NO_UNLOCK ((ulong) OPTION_RELAXED_UNIQUE_CHECKS*2) +/* NOTE: we have now used up all 32 bits of the OPTION flag! */ /* Bits for different SQL modes modes (including ANSI mode) */ #define MODE_REAL_AS_FLOAT 1 @@ -574,8 +580,9 @@ void sql_print_error(const char *format,...) __attribute__ ((format (printf, 1, 2))); bool fn_format_relative_to_data_home(my_string to, const char *name, const char *dir, const char *extension); -void open_log(MYSQL_LOG *log, const char *hostname, - const char *opt_name, const char *extension, +bool open_log(MYSQL_LOG *log, const char *hostname, + const char *opt_name, const char *extension, + const char *index_file_name, enum_log_type type, bool read_append = 0, bool no_auto_events = 0); @@ -610,7 +617,7 @@ extern ulong select_range_check_count, select_range_count, select_scan_count; extern ulong select_full_range_join_count,select_full_join_count; extern ulong slave_open_temp_tables, query_cache_size; extern ulong thd_startup_options, slow_launch_threads, slow_launch_time; -extern ulong server_id; +extern ulong server_id, concurrency; extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count; extern ulong ha_read_key_count, ha_read_next_count, ha_read_prev_count; extern ulong ha_read_first_count, ha_read_last_count; @@ -637,6 +644,7 @@ extern bool opt_disable_networking, opt_skip_show_db; extern bool volatile abort_loop, shutdown_in_progress, grant_option; extern uint volatile thread_count, thread_running, global_read_lock; extern my_bool opt_safe_show_db, opt_local_infile, lower_case_table_names; +extern my_bool opt_slave_compressed_protocol; extern char f_fyllchar; extern MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log; @@ -663,7 +671,8 @@ extern struct system_variables max_system_variables; extern SHOW_COMP_OPTION have_isam, have_innodb, have_berkeley_db; extern SHOW_COMP_OPTION have_raid, have_openssl, have_symlink; -extern SHOW_COMP_OPTION have_query_cache; +extern SHOW_COMP_OPTION have_query_cache, have_berkeley_db, have_innodb; + #ifndef __WIN__ extern pthread_t signal_thread; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d441c9c8412..be77f2bc7b3 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -101,14 +101,14 @@ extern "C" { // Because of SCO 3.2V4.2 int allow_severity = LOG_INFO; int deny_severity = LOG_WARNING; -#ifdef __linux__ -#define my_fromhost(A) fromhost() -#define my_hosts_access(A) hosts_access() -#define my_eval_client(A) eval_client() -#else +#ifdef __STDC__ #define my_fromhost(A) fromhost(A) #define my_hosts_access(A) hosts_access(A) #define my_eval_client(A) eval_client(A) +#else +#define my_fromhost(A) fromhost() +#define my_hosts_access(A) hosts_access() +#define my_eval_client(A) eval_client() #endif #endif /* HAVE_LIBWRAP */ @@ -252,15 +252,15 @@ bool opt_skip_slave_start = 0; // If set, slave is not autostarted */ bool opt_reckless_slave = 0; -ulong back_log, connect_timeout; +ulong back_log, connect_timeout, concurrency; char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], time_zone[30]; bool opt_log, opt_update_log, opt_bin_log, opt_slow_log; bool opt_disable_networking=0, opt_skip_show_db=0; -my_bool opt_local_infile, opt_external_locking; +my_bool opt_local_infile, opt_external_locking, opt_slave_compressed_protocol; static bool opt_do_pstack = 0; static ulong opt_specialflag=SPECIAL_ENGLISH; -static ulong concurrency; + static ulong opt_myisam_block_size; static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET; static my_string opt_logname=0,opt_update_logname=0, @@ -1428,6 +1428,17 @@ static void init_signals(void) sigaction(SIGILL, &sa, NULL); sigaction(SIGFPE, &sa, NULL); } + +#ifdef HAVE_GETRLIMIT + if (test_flags & TEST_CORE_ON_SIGNAL) + { + /* Change limits so that we will get a core file */ + struct rlimit rl; + rl.rlim_cur = rl.rlim_max = RLIM_INFINITY; + if (setrlimit(RLIMIT_CORE, &rl)) + sql_print_error("Warning: setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals"); + } +#endif (void) sigemptyset(&set); #ifdef THREAD_SPECIFIC_SIGPIPE sigset(SIGPIPE,abort_thread); @@ -1701,10 +1712,11 @@ const char *load_default_groups[]= { "mysqld","server",0 }; char *libwrapName=NULL; #endif -void open_log(MYSQL_LOG *log, const char *hostname, - const char *opt_name, const char *extension, - enum_log_type type, bool read_append, - bool no_auto_events) +bool open_log(MYSQL_LOG *log, const char *hostname, + const char *opt_name, const char *extension, + const char *index_file_name, + enum_log_type type, bool read_append, + bool no_auto_events) { char tmp[FN_REFLEN]; if (!opt_name || !opt_name[0]) @@ -1728,8 +1740,9 @@ void open_log(MYSQL_LOG *log, const char *hostname, opt_name=tmp; } } - log->open(opt_name,type,0,(read_append) ? SEQ_READ_APPEND : WRITE_CACHE, - no_auto_events); + return log->open(opt_name, type, 0, index_file_name, + (read_append) ? SEQ_READ_APPEND : WRITE_CACHE, + no_auto_events); } @@ -1939,17 +1952,18 @@ int main(int argc, char **argv) /* Setup log files */ if (opt_log) - open_log(&mysql_log, glob_hostname, opt_logname, ".log", LOG_NORMAL); + open_log(&mysql_log, glob_hostname, opt_logname, ".log", NullS, + LOG_NORMAL); if (opt_update_log) { open_log(&mysql_update_log, glob_hostname, opt_update_logname, "", - LOG_NEW); + NullS, LOG_NEW); using_update_log=1; } if (opt_slow_log) open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log", - LOG_NORMAL); + NullS, LOG_NORMAL); #ifdef __WIN__ #define MYSQL_ERR_FILE "mysql.err" if (!opt_console) @@ -2051,9 +2065,8 @@ The server will not act as a slave."); strmov(strcend(tmp,'.'),"-bin"); opt_bin_logname=my_strdup(tmp,MYF(MY_WME)); } - mysql_bin_log.set_index_file_name(opt_binlog_index_name); open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin", - LOG_BIN); + opt_binlog_index_name,LOG_BIN); using_update_log=1; } @@ -2353,13 +2366,7 @@ static void create_new_thread(THD *thd) delete thd; DBUG_VOID_RETURN; } - if (pthread_mutex_lock(&LOCK_thread_count)) - { - DBUG_PRINT("error",("Can't lock LOCK_thread_count")); - close_connection(net,ER_OUT_OF_RESOURCES); - delete thd; - DBUG_VOID_RETURN; - } + pthread_mutex_lock(&LOCK_thread_count); if (thread_count-delayed_insert_threads > max_used_connections) max_used_connections=thread_count-delayed_insert_threads; thd->thread_id=thread_id++; @@ -2818,7 +2825,7 @@ enum options { OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_SIZE, OPT_QUERY_CACHE_TYPE, OPT_RECORD_BUFFER, OPT_RECORD_RND_BUFFER, OPT_RELAY_LOG_SPACE_LIMIT, - OPT_SLAVE_NET_TIMEOUT, OPT_SLOW_LAUNCH_TIME, + OPT_SLAVE_NET_TIMEOUT, OPT_SLAVE_COMPRESSED_PROTOCOL, OPT_SLOW_LAUNCH_TIME, OPT_SORT_BUFFER, OPT_TABLE_CACHE, OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE, OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK, @@ -2967,8 +2974,10 @@ struct my_option my_long_options[] = "Set to 1 if you want to have logs archived", 0, 0, 0, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_flush_log_at_trx_commit", OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT, - "Set to 0 if you don't want to flush logs", 0, 0, 0, GET_LONG, OPT_ARG, - 0, 0, 0, 0, 0, 0}, + "Set to 0 if you don't want to flush logs", + (gptr*) &innobase_flush_log_at_trx_commit, + (gptr*) &innobase_flush_log_at_trx_commit, + 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_flush_method", OPT_INNODB_FLUSH_METHOD, "With which method to flush data", (gptr*) &innobase_unix_file_flush_method, (gptr*) &innobase_unix_file_flush_method, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, @@ -3046,7 +3055,7 @@ struct my_option my_long_options[] = {"master-retry-count", OPT_MASTER_RETRY_COUNT, "The number of tries the slave will make to connect to the master before giving up.", (gptr*) &master_retry_count, (gptr*) &master_retry_count, 0, GET_ULONG, - REQUIRED_ARG, 60, 0, 0, 0, 0, 0}, + REQUIRED_ARG, 3600*24, 0, 0, 0, 0, 0}, {"master-info-file", OPT_MASTER_INFO_FILE, "The location of the file that remembers where we left off on the master during the replication process. The default is `master.info' in the data directory. You should not need to change this.", (gptr*) &master_info_file, (gptr*) &master_info_file, 0, GET_STR, @@ -3329,7 +3338,7 @@ struct my_option my_long_options[] = { "ft_min_word_len", OPT_FT_MIN_WORD_LEN, "The minimum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.", (gptr*) &ft_min_word_len, (gptr*) &ft_min_word_len, 0, GET_ULONG, - REQUIRED_ARG, 4, 1, HA_FT_MAXLEN, 0, 1, 0}, + REQUIRED_ARG, 4, 2, HA_FT_MAXLEN, 0, 1, 0}, { "ft_max_word_len", OPT_FT_MAX_WORD_LEN, "The maximum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.", (gptr*) &ft_max_word_len, (gptr*) &ft_max_word_len, 0, GET_ULONG, @@ -3547,6 +3556,11 @@ struct my_option my_long_options[] = "Undocumented", (gptr*) &relay_log_space_limit, (gptr*) &relay_log_space_limit, 0, GET_ULONG, REQUIRED_ARG, 0L, 0L, (longlong) ULONG_MAX, 0, 1, 0}, + {"slave_compressed_protocol", OPT_SLAVE_COMPRESSED_PROTOCOL, + "Use compression on master/slave protocol", + (gptr*) &opt_slave_compressed_protocol, + (gptr*) &opt_slave_compressed_protocol, + 0, GET_BOOL, REQUIRED_ARG, 0, 0, 1, 0, 1, 0}, {"slave_net_timeout", OPT_SLAVE_NET_TIMEOUT, "Number of seconds to wait for more data from a master/slave connection before aborting the read.", (gptr*) &slave_net_timeout, (gptr*) &slave_net_timeout, 0, @@ -3654,6 +3668,7 @@ struct show_var_st status_vars[]= { {"Com_show_slave_hosts", (char*) (com_stat+(uint) SQLCOM_SHOW_SLAVE_HOSTS),SHOW_LONG}, {"Com_show_slave_status", (char*) (com_stat+(uint) SQLCOM_SHOW_SLAVE_STAT),SHOW_LONG}, {"Com_show_status", (char*) (com_stat+(uint) SQLCOM_SHOW_STATUS),SHOW_LONG}, + {"Com_show_innodb_status", (char*) (com_stat+(uint) SQLCOM_SHOW_INNODB_STATUS),SHOW_LONG}, {"Com_show_tables", (char*) (com_stat+(uint) SQLCOM_SHOW_TABLES),SHOW_LONG}, {"Com_show_variables", (char*) (com_stat+(uint) SQLCOM_SHOW_VARIABLES),SHOW_LONG}, {"Com_slave_start", (char*) (com_stat+(uint) SQLCOM_SLAVE_START),SHOW_LONG}, @@ -4238,9 +4253,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case OPT_INNODB_LOG_ARCHIVE: innobase_log_archive= argument ? test(atoi(argument)) : 1; break; - case OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT: - innobase_flush_log_at_trx_commit= argument ? test(atoi(argument)) : 1; - break; case OPT_INNODB_FAST_SHUTDOWN: innobase_fast_shutdown= argument ? test(atoi(argument)) : 1; break; diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 5ff040003d5..0eb3e1d6a75 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -107,7 +107,10 @@ int my_net_init(NET *net, Vio* vio) net->fd = vio_fd(vio); /* For perl DBI/DBD */ #if defined(MYSQL_SERVER) && !defined(___WIN__) && !defined(__EMX__) && !defined(OS2) if (!(test_flags & TEST_BLOCKING)) - vio_blocking(vio, FALSE); + { + my_bool old_mode; + vio_blocking(vio, FALSE, &old_mode); + } #endif vio_fastsend(vio); } @@ -161,17 +164,14 @@ void net_clear(NET *net) { #if !defined(EXTRA_DEBUG) && !defined(EMBEDDED_LIBRARY) int count; /* One may get 'unused' warn */ - bool is_blocking=vio_is_blocking(net->vio); - if (is_blocking) - vio_blocking(net->vio, FALSE); - if (!vio_is_blocking(net->vio)) /* Safety if SSL */ + my_bool old_mode; + if (!vio_blocking(net->vio, FALSE, &old_mode)) { while ( (count = vio_read(net->vio, (char*) (net->buff), (uint32) net->max_packet)) > 0) DBUG_PRINT("info",("skipped %d bytes from file: %s", count,vio_description(net->vio))); - if (is_blocking) - vio_blocking(net->vio, TRUE); + vio_blocking(net->vio, TRUE, &old_mode); } #endif /* EXTRA_DEBUG */ net->pkt_nr=net->compress_pkt_nr=0; /* Ready for new command */ @@ -382,20 +382,18 @@ net_real_write(NET *net,const char *packet,ulong len) { if (!thr_alarm(&alarmed,(uint) net->write_timeout,&alarm_buff)) { /* Always true for client */ - if (!vio_is_blocking(net->vio)) + my_bool old_mode; + while (vio_blocking(net->vio, TRUE, &old_mode) < 0) { - while (vio_blocking(net->vio, TRUE) < 0) - { - if (vio_should_retry(net->vio) && retry_count++ < RETRY_COUNT) - continue; + if (vio_should_retry(net->vio) && retry_count++ < RETRY_COUNT) + continue; #ifdef EXTRA_DEBUG - fprintf(stderr, - "%s: my_net_write: fcntl returned error %d, aborting thread\n", - my_progname,vio_errno(net->vio)); + fprintf(stderr, + "%s: my_net_write: fcntl returned error %d, aborting thread\n", + my_progname,vio_errno(net->vio)); #endif /* EXTRA_DEBUG */ - net->error=2; /* Close socket */ - goto end; - } + net->error=2; /* Close socket */ + goto end; } retry_count=0; continue; @@ -439,8 +437,9 @@ net_real_write(NET *net,const char *packet,ulong len) #endif if (thr_alarm_in_use(&alarmed)) { + my_bool old_mode; thr_end_alarm(&alarmed); - vio_blocking(net->vio, net_blocking); + vio_blocking(net->vio, net_blocking, &old_mode); } net->reading_or_writing=0; DBUG_RETURN(((int) (pos != end))); @@ -461,10 +460,12 @@ static void my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed) { ALARM alarm_buff; uint retry_count=0; + my_bool old_mode; + if (!thr_alarm_in_use(&alarmed)) { if (!thr_alarm(alarmed,net->read_timeout,&alarm_buff) || - (!vio_is_blocking(net->vio) && vio_blocking(net->vio,TRUE) < 0)) + vio_blocking(net->vio, TRUE, &old_mode) < 0) return; /* Can't setup, abort */ } while (remain > 0) @@ -538,29 +539,27 @@ my_real_read(NET *net, ulong *complen) { if (!thr_alarm(&alarmed,net->read_timeout,&alarm_buff)) /* Don't wait too long */ { - if (!vio_is_blocking(net->vio)) - { - while (vio_blocking(net->vio,TRUE) < 0) - { - if (vio_should_retry(net->vio) && - retry_count++ < RETRY_COUNT) - continue; - DBUG_PRINT("error", - ("fcntl returned error %d, aborting thread", - vio_errno(net->vio))); + my_bool old_mode; + while (vio_blocking(net->vio, TRUE, &old_mode) < 0) + { + if (vio_should_retry(net->vio) && + retry_count++ < RETRY_COUNT) + continue; + DBUG_PRINT("error", + ("fcntl returned error %d, aborting thread", + vio_errno(net->vio))); #ifdef EXTRA_DEBUG - fprintf(stderr, - "%s: read: fcntl returned error %d, aborting thread\n", - my_progname,vio_errno(net->vio)); + fprintf(stderr, + "%s: read: fcntl returned error %d, aborting thread\n", + my_progname,vio_errno(net->vio)); #endif /* EXTRA_DEBUG */ - len= packet_error; - net->error=2; /* Close socket */ + len= packet_error; + net->error=2; /* Close socket */ #ifdef MYSQL_SERVER - net->last_errno=ER_NET_FCNTL_ERROR; + net->last_errno=ER_NET_FCNTL_ERROR; #endif - goto end; - } - } + goto end; + } retry_count=0; continue; } @@ -583,7 +582,9 @@ my_real_read(NET *net, ulong *complen) continue; } #endif - DBUG_PRINT("error",("Couldn't read packet: remain: %lu errno: %d length: %ld alarmed: %d", remain,vio_errno(net->vio),length,alarmed)); + DBUG_PRINT("error",("Couldn't read packet: remain: %lu errno: %d length: %ld alarmed: %d", + remain,vio_errno(net->vio), length, + thr_got_alarm(&alarmed))); len= packet_error; net->error=2; /* Close socket */ #ifdef MYSQL_SERVER @@ -653,8 +654,9 @@ my_real_read(NET *net, ulong *complen) end: if (thr_alarm_in_use(&alarmed)) { + my_bool old_mode; thr_end_alarm(&alarmed); - vio_blocking(net->vio, net_blocking); + vio_blocking(net->vio, net_blocking, &old_mode); } net->reading_or_writing=0; return(len); diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index f5f5b2de9fc..54843f1dfa4 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -240,7 +240,7 @@ static int find_target_pos(LEX_MASTER_INFO *mi, IO_CACHE *log, char *errmsg) int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg) { LOG_INFO linfo; - char search_file_name[FN_REFLEN],last_log_name[FN_REFLEN]; + char last_log_name[FN_REFLEN]; IO_CACHE log; File file = -1, last_file = -1; pthread_mutex_t *log_lock; @@ -264,9 +264,8 @@ int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg) } linfo.index_file_offset = 0; - search_file_name[0] = 0; - if (mysql_bin_log.find_first_log(&linfo, search_file_name)) + if (mysql_bin_log.find_log_pos(&linfo, NullS)) { strmov(errmsg,"Could not find first log"); return 1; @@ -619,18 +618,22 @@ int show_slave_hosts(THD* thd) int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi) { - if (!mi->host || !*mi->host) /* empty host */ - return 1; + DBUG_ENTER("connect_to_master"); + if (!mi->host || !*mi->host) /* empty host */ + { + DBUG_PRINT("error",("empty hostname")); + DBUG_RETURN(1); + } if (!mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0, mi->port, 0, 0, slave_net_timeout)) { sql_print_error("Connection to master failed: %s", mc_mysql_error(mysql)); - return 1; + DBUG_RETURN(1); } - return 0; + DBUG_RETURN(0); } @@ -671,12 +674,17 @@ static inline int fetch_db_tables(THD* thd, MYSQL* mysql, const char* db, return 0; } +/* + Load all MyISAM tables from master to this slave. + + REQUIREMENTS + - No active transaction (flush_relay_log_info would not work in this case) +*/ int load_master_data(THD* thd) { MYSQL mysql; MYSQL_RES* master_status_res = 0; - bool slave_was_running = 0; int error = 0; const char* errmsg=0; int restart_thread_mask; @@ -840,7 +848,8 @@ int load_master_data(THD* thd) } } thd->proc_info="purging old relay logs"; - if (purge_relay_logs(&active_mi->rli,0 /* not only reset, but also reinit */, + if (purge_relay_logs(&active_mi->rli,thd, + 0 /* not only reset, but also reinit */, &errmsg)) { send_error(&thd->net, 0, "Failed purging old relay logs"); diff --git a/sql/set_var.cc b/sql/set_var.cc index a9882af546a..6aa5450d094 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -186,6 +186,8 @@ sys_var_thd_enum sys_query_cache_type("query_cache_type", sys_var_bool_ptr sys_safe_show_db("safe_show_database", &opt_safe_show_db); sys_var_long_ptr sys_server_id("server_id",&server_id); +sys_var_bool_ptr sys_slave_compressed_protocol("slave_compressed_protocol", + &opt_slave_compressed_protocol); sys_var_long_ptr sys_slave_net_timeout("slave_net_timeout", &slave_net_timeout); sys_var_long_ptr sys_slow_launch_time("slow_launch_time", @@ -251,6 +253,15 @@ static sys_var_thd_bit sys_buffer_results("sql_buffer_result", static sys_var_thd_bit sys_quote_show_create("sql_quote_show_create", set_option_bit, OPTION_QUOTE_SHOW_CREATE); +static sys_var_thd_bit sys_foreign_key_checks("foreign_key_checks", + set_option_bit, + OPTION_NO_FOREIGN_KEY_CHECKS, + 1); +static sys_var_thd_bit sys_unique_checks("unique_checks", + set_option_bit, + OPTION_RELAXED_UNIQUE_CHECKS, + 1); + /* Local state variables */ @@ -290,6 +301,7 @@ sys_var *sys_variables[]= &sys_delayed_queue_size, &sys_flush, &sys_flush_time, + &sys_foreign_key_checks, &sys_identity, &sys_insert_id, &sys_interactive_timeout, @@ -326,7 +338,7 @@ sys_var *sys_variables[]= #ifdef HAVE_QUERY_CACHE &sys_query_cache_limit, &sys_query_cache_type, -#endif HAVE_QUERY_CACHE +#endif /* HAVE_QUERY_CACHE */ &sys_quote_show_create, &sys_read_buff_size, &sys_read_rnd_buff_size, @@ -335,6 +347,7 @@ sys_var *sys_variables[]= &sys_safe_updates, &sys_select_limit, &sys_server_id, + &sys_slave_compressed_protocol, &sys_slave_net_timeout, &sys_slave_skip_counter, &sys_slow_launch_time, @@ -349,6 +362,7 @@ sys_var *sys_variables[]= &sys_timestamp, &sys_tmp_table_size, &sys_tx_isolation, + &sys_unique_checks }; @@ -403,7 +417,7 @@ struct show_var_st init_vars[]= { {"innodb_file_io_threads", (char*) &innobase_file_io_threads, SHOW_LONG }, {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG }, {"innodb_thread_concurrency", (char*) &innobase_thread_concurrency, SHOW_LONG }, - {"innodb_flush_log_at_trx_commit", (char*) &innobase_flush_log_at_trx_commit, SHOW_MY_BOOL}, + {"innodb_flush_log_at_trx_commit", (char*) &innobase_flush_log_at_trx_commit, SHOW_LONG}, {"innodb_fast_shutdown", (char*) &innobase_fast_shutdown, SHOW_MY_BOOL}, {"innodb_flush_method", (char*) &innobase_unix_file_flush_method, SHOW_CHAR_PTR}, {"innodb_lock_wait_timeout", (char*) &innobase_lock_wait_timeout, SHOW_LONG }, @@ -988,10 +1002,11 @@ bool sys_var_slave_skip_counter::update(THD *thd, set_var *var) static bool set_option_bit(THD *thd, set_var *var) { - if (var->save_result.ulong_value == 0) - thd->options&= ~((sys_var_thd_bit*) var->var)->bit_flag; + sys_var_thd_bit *sys_var= ((sys_var_thd_bit*) var->var); + if ((var->save_result.ulong_value != 0) == sys_var->reverse) + thd->options&= ~sys_var->bit_flag; else - thd->options|= ((sys_var_thd_bit*) var->var)->bit_flag; + thd->options|= sys_var->bit_flag; return 0; } @@ -1142,7 +1157,7 @@ void set_var_free() 0 Unknown variable (error message is given) */ -sys_var *find_sys_var(const char *str, uint length=0) +sys_var *find_sys_var(const char *str, uint length) { sys_var *var= (sys_var*) hash_search(&system_variable_hash, str, length ? length : diff --git a/sql/set_var.h b/sql/set_var.h index 607e44d2ef3..46463089b03 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -128,7 +128,7 @@ public: } void set_default(THD *thd, enum_var_type type) { - return (*set_default_func)(thd, type); + (*set_default_func)(thd, type); } SHOW_TYPE type() { return SHOW_CHAR; } byte *value_ptr(THD *thd, enum_var_type type) { return (byte*) value; } diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 868bb42b6be..9c3bf3b32a1 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -1,28 +1,28 @@ /* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB This file is public domain and comes with NO WARRANTY of any kind */ -/* Updated by Roberto de Martin Serqueira - martinsc@uol.com.br - 08.20.2001 */ +/* Updated by Thiago Delgado Pinto - thiagodp@ieg.com.br - 06.07.2002 */ "hashchk", "isamchk", -"não", -"sim", -"Não pode criar arquivo '%-.64s' (erro no. %d)", -"Não pode criar tabela '%-.64s' (erro no. %d)", -"Não pode criar banco de dados '%-.64s' (erro no. %d)", -"Não pode criar banco de dados '%-.64s'. Banco de dados já existe", -"Não pode eliminar banco de dados '%-.64s'. Banco de dados não existe", +"NÃO", +"SIM", +"Não pode criar o arquivo '%-.64s' (erro no. %d)", +"Não pode criar a tabela '%-.64s' (erro no. %d)", +"Não pode criar o banco de dados '%-.64s' (erro no. %d)", +"Não pode criar o banco de dados '%-.64s'. Este banco de dados já existe", +"Não pode eliminar o banco de dados '%-.64s'. Este banco de dados não existe", "Erro ao eliminar banco de dados (não pode eliminar '%-.64s' - erro no. %d)", "Erro ao eliminar banco de dados (não pode remover diretório '%-.64s' - erro no. %d)", -"Erro na deleção de '%-.64s' (erro no. %d)", -"Não pode ler registro em tabela do sistema", -"Não pode obter status de '%-.64s' (erro no. %d)", -"Não pode obter diretório corrente (erro no. %d)", -"Não pode travar arquivo (erro no. %d)", -"Não pode abrir arquivo '%-.64s' (erro no. %d)", -"Não pode encontrar arquivo '%-.64s' (erro no. %d)", -"Não pode ler diretório de '%-.64s' (erro no. %d)", +"Erro na remoção de '%-.64s' (erro no. %d)", +"Não pode ler um registro numa tabela do sistema", +"Não pode obter o status de '%-.64s' (erro no. %d)", +"Não pode obter o diretório corrente (erro no. %d)", +"Não pode travar o arquivo (erro no. %d)", +"Não pode abrir o arquivo '%-.64s' (erro no. %d)", +"Não pode encontrar o arquivo '%-.64s' (erro no. %d)", +"Não pode ler o diretório de '%-.64s' (erro no. %d)", "Não pode mudar para o diretório '%-.64s' (erro no. %d)", "Registro alterado desde a última leitura da tabela '%-.64s'", -"Disco cheio (%s). Aguardando alguém liberar algum espaço....", +"Disco cheio (%s). Aguardando alguém liberar algum espaço...", "Não pode gravar. Chave duplicada na tabela '%-.64s'", "Erro ao fechar '%-.64s' (erro no. %d)", "Erro ao ler arquivo '%-.64s' (erro no. %d)", @@ -30,13 +30,13 @@ "Erro ao gravar arquivo '%-.64s' (erro no. %d)", "'%-.64s' está com travamento contra alterações", "Ordenação abortada", -"'View' '%-.64s' não existe para '%-.64s'", +"Visão '%-.64s' não existe para '%-.64s'", "Obteve erro %d no manipulador de tabelas", "Manipulador de tabela para '%-.64s' não tem esta opção", "Não pode encontrar registro em '%-.64s'", "Informação incorreta no arquivo '%-.64s'", -"Arquivo de índice incorreto para tabela '%-.64s'. Tente reparar", -"Arquivo chave desatualizado para tabela '%-.64s'. Repare-o!", +"Arquivo de índice incorreto para tabela '%-.64s'. Tente repará-lo", +"Arquivo de índice desatualizado para tabela '%-.64s'. Repare-o!", "Tabela '%-.64s' é somente para leitura", "Sem memória. Reinicie o programa e tente novamente (necessita de %d bytes)", "Sem memória para ordenação. Aumente tamanho do 'buffer' de ordenação", @@ -46,10 +46,10 @@ "Não pode obter nome do 'host' para seu endereço", "Negociação de acesso falhou", "Acesso negado para o usuário '%-.32s@%-.64s' ao banco de dados '%-.64s'", -"Acesso negado para o usuário '%-.32s@%-.64s' (uso de senha: %s)", +"Acesso negado para o usuário '%-.32s@%-.64s' (senha usada: %s)", "Nenhum banco de dados foi selecionado", "Comando desconhecido", -"Coluna '%-.64s' não pode ter NULL", +"Coluna '%-.64s' não pode ser vazia", "Banco de dados '%-.64s' desconhecido", "Tabela '%-.64s' já existe", "Tabela '%-.64s' desconhecida", @@ -66,9 +66,9 @@ "Entrada '%-.64s' duplicada para a chave %d", "Especificador de coluna incorreto para a coluna '%-.64s'", "%s próximo a '%-.80s' na linha %d", -"'Query' estava vazia", +"Consulta (query) estava vazia", "Tabela/alias '%-.64s' não única", -"Valor 'default' inválido para '%-.64s'", +"Valor padrão (default) inválido para '%-.64s'", "Definida mais de uma chave primária", "Especificadas chaves demais. O máximo permitido são %d chaves", "Especificadas partes de chave demais. O máximo permitido são %d partes", @@ -82,50 +82,50 @@ "%s: Obteve sinal %d. Abortando!\n", "%s: 'Shutdown' completo\n", "%s: Forçando finalização da 'thread' %ld - usuário '%-.32s'\n", -"Não pode criar 'IP socket'", +"Não pode criar o soquete IP", "Tabela '%-.64s' não possui um índice como o usado em CREATE INDEX. Recrie a tabela", -"Argumento separador de campos não é o esperado. Confira no manual", -"Você não pode usar comprimento de linha fixo com BLOBs. Favor usar 'fields terminated by'", +"Argumento separador de campos não é o esperado. Cheque o manual", +"Você não pode usar comprimento de linha fixo com BLOBs. Por favor, use campos com comprimento limitado.", "Arquivo '%-.64s' tem que estar no diretório do banco de dados ou ter leitura possível para todos", "Arquivo '%-.80s' já existe", "Registros: %ld - Deletados: %ld - Ignorados: %ld - Avisos: %ld", "Registros: %ld - Duplicados: %ld", -"Parte de chave incorreta. A parte de chave usada não é um 'string' ou o comprimento usado é maior do que a parte de chave ou o manipulador de tabelas não aceita partes de chaves únicas", +"Sub parte da chave incorreta. A parte da chave usada não é uma 'string' ou o comprimento usado é maior que parte da chave ou o manipulador de tabelas não suporta sub chaves únicas", "Você não pode deletar todas as colunas com ALTER TABLE. Use DROP TABLE em seu lugar", -"Não pode fazer DROP '%-.64s'. Confira se esta coluna/chave existe", +"Não se pode fazer DROP '%-.64s'. Confira se esta coluna/chave existe", "Registros: %ld - Duplicados: %ld - Avisos: %ld", -"INSERT TABLE '%-.64s' não é permitido em lista de tabelas FROM", +"INSERT TABLE '%-.64s' não é permitido na lista de tabelas contidas em FROM", "'Id' de 'thread' %lu desconhecido", "Você não é proprietário da 'thread' %lu", "Nenhuma tabela usada", "'Strings' demais para coluna '%-.64s' e SET", "Não pode gerar um nome de arquivo de 'log' único '%-.64s'.(1-999)\n", -"Tabela '%-.64s' foi travada com trava de READ e não pode ser atualizada", +"Tabela '%-.64s' foi travada com trava de leitura e não pode ser atualizada", "Tabela '%-.64s' não foi travada com LOCK TABLES", -"Coluna BLOB '%-.64s' não pode ter um valor 'default'", +"Coluna BLOB '%-.64s' não pode ter um valor padrão (default)", "Nome de banco de dados '%-.100s' incorreto", "Nome de tabela '%-.100s' incorreto", -"O SELECT examinaria registros demais e provavelmente tomaria um tempo muito longo. Confira sua cláusula WHERE e use SET OPTION SQL_BIG_SELECTS=1, se o SELECT estiver correto", +"O SELECT examinaria registros demais e provavelmente levaria muito tempo. Cheque sua cláusula WHERE e use SET OPTION SQL_BIG_SELECTS=1, se o SELECT estiver correto", "Erro desconhecido", "'Procedure' '%-.64s' desconhecida", "Número de parâmetros incorreto para a 'procedure' '%-.64s'", "Parâmetros incorretos para a 'procedure' '%-.64s'", "Tabela '%-.64s' desconhecida em '%-.32s'", "Coluna '%-.64s' especificada duas vezes", -"Uso inválido de função de grupo", +"Uso inválido de função de agrupamento (GROUP)", "Tabela '%-.64s' usa uma extensão que não existe nesta versão do MySQL", "Uma tabela tem que ter pelo menos uma (1) coluna", "Tabela '%-.64s' está cheia", "Conjunto de caracteres '%-.64s' desconhecido", -"Tabelas demais. O MySQL pode usar somente %d tabelas em um JOIN", +"Tabelas demais. O MySQL pode usar somente %d tabelas em uma junção (JOIN)", "Colunas demais", "Tamanho de linha grande demais. O máximo tamanho de linha, não contando BLOBs, é %d. Você tem que mudar alguns campos para BLOBs", "Estouro da pilha do 'thread'. Usados %ld de uma pilha de %ld . Use 'mysqld -O thread_stack=#' para especificar uma pilha maior, se necessário", -"Dependência cruzada encontrada em OUTER JOIN. Examine suas condições ON", -"Coluna '%-.64s' é usada com UNIQUE ou INDEX, mas não está definida como NOT NULL", +"Dependência cruzada encontrada em junção externa (OUTER JOIN). Examine as condições utilizadas nas cláusulas 'ON'", +"Coluna '%-.64s' é usada com única (UNIQUE) ou índice (INDEX), mas não está definida como não-nula (NOT NULL)", "Não pode carregar a função '%-.64s'", "Não pode inicializar a função '%-.64s' - '%-.80s'", -"Não é permitido caminho para biblioteca compartilhada", +"Não há caminhos (paths) permitidos para biblioteca compartilhada", "Função '%-.64s' já existe", "Não pode abrir biblioteca compartilhada '%-.64s' (erro no. '%d' - '%-.64s')", "Não pode encontrar a função '%-.64s' na biblioteca", @@ -133,34 +133,34 @@ "'Host' '%-.64s' está bloqueado devido a muitos erros de conexão. Desbloqueie com 'mysqladmin flush-hosts'", "'Host' '%-.64s' não tem permissão para se conectar com este servidor MySQL", "Você está usando o MySQL como usuário anônimo e usuários anônimos não têm permissão para mudar senhas", -"Você tem que ter o privilégio para atualizar tabelas no banco de dados mysql para ser capaz de mudar a senha de outros", -"Não pode encontrar nenhuma linha que combine na tabela user", +"Você deve ter privilégios para atualizar tabelas no banco de dados mysql para ser capaz de mudar a senha de outros", +"Não pode encontrar nenhuma linha que combine na tabela usuário (user table)", "Linhas que combinaram: %ld - Alteradas: %ld - Avisos: %ld", "Não pode criar uma nova 'thread' (erro no. %d). Se você não estiver sem memória disponível, você pode consultar o manual sobre um possível 'bug' dependente do sistema operacional", "Contagem de colunas não confere com a contagem de valores na linha %ld", "Não pode reabrir a tabela '%-.64s', "Uso inválido do valor NULL", "Obteve erro '%-.64s' em regexp", -"Mistura de colunas GROUP (MIN(),MAX(),COUNT()...) com colunas não GROUP é ilegal, se não existir cláusula GROUP BY", -"Não existe tal 'grant' definido para o usuário '%-.32s' no 'host' '%-.64s'", +"Mistura de colunas agrupadas (com MIN(), MAX(), COUNT(), ...) com colunas não agrupadas é ilegal, se não existir uma cláusula de agrupamento (cláusula GROUP BY)", +"Não existe tal permissão (grant) definida para o usuário '%-.32s' no 'host' '%-.64s'", "Comando '%-.16s' negado para o usuário '%-.32s@%-.64s' na tabela '%-.64s'", "Comando '%-.16s' negado para o usuário '%-.32s@%-.64s' na coluna '%-.64s', na tabela '%-.64s'", "Comando GRANT/REVOKE ilegal. Por favor consulte no manual quais privilégios podem ser usados.", "Argumento de 'host' ou de usuário para o GRANT é longo demais", "Tabela '%-.64s.%-.64s' não existe", -"Não existe tal 'grant' definido para o usuário '%-.32s' no 'host' '%-.64s', na tabela '%-.64s'", +"Não existe tal permissão (grant) definido para o usuário '%-.32s' no 'host' '%-.64s', na tabela '%-.64s'", "Comando usado não é permitido para esta versão do MySQL", "Você tem um erro de sintaxe no seu SQL", -"'Thread' de inserção retardada ('delayed') não conseguiu obter trava solicitada para tabela '%-.64s'", -"Excesso de 'threads' retardadas ('delayed') em uso", +"'Thread' de inserção retardada (atrasada) pois não conseguiu obter a trava solicitada para tabela '%-.64s'", +"Excesso de 'threads' retardadas (atrasadas) em uso", "Conexão %ld abortou para o banco de dados '%-.64s' - usuário '%-.32s' (%-.64s)", -"Obteve um pacote maior do que 'max_allowed_packet'", +"Obteve um pacote maior do que a taxa máxima de pacotes definida (max_allowed_packet)", "Obteve um erro de leitura no 'pipe' da conexão", "Obteve um erro em fcntl()", "Obteve pacotes fora de ordem", "Não conseguiu descomprimir pacote de comunicação", "Obteve um erro na leitura de pacotes de comunicação", -"Obteve expiração de tempo ('timeout') na leitura de pacotes de comunicação", +"Obteve expiração de tempo (timeout) na leitura de pacotes de comunicação", "Obteve um erro na escrita de pacotes de comunicação", "Obteve expiração de tempo ('timeout') na escrita de pacotes de comunicação", "'String' resultante é mais longa do que 'max_allowed_packet'", @@ -169,56 +169,56 @@ "INSERT DELAYED não pode ser usado com a tabela '%-.64s', porque ela está travada com LOCK TABLES", "Nome de coluna '%-.100s' incorreto", "O manipulador de tabela usado não pode indexar a coluna '%-.64s'", -"Tabelas no MERGE não estão todas definidas identicamente", +"Todas as tabelas contidas na tabela fundida (MERGE) não estão definidas identicamente", "Não pode gravar, devido à restrição UNIQUE, na tabela '%-.64s'", "Coluna BLOB '%-.64s' usada na especificação de chave sem o comprimento da chave", -"Todas as partes de uma PRIMARY KEY têm que ser NOT NULL. Se você precisar de NULL em uma chave, use UNIQUE em seu lugar", +"Todas as partes de uma chave primária devem ser não-nulas. Se você precisou usar um valor nulo (NULL) em uma chave, use a cláusula UNIQUE em seu lugar", "O resultado consistiu em mais do que uma linha", "Este tipo de tabela requer uma chave primária", "Esta versão do MySQL não foi compilada com suporte a RAID", -"Você está usando modo de atualização seguro e tentou atualizar uma tabela sem um WHERE que use uma coluna de KEY", +"Você está usando modo de atualização seguro e tentou atualizar uma tabela sem uma cláusula WHERE que use uma coluna chave", "Chave '%-.64s' não existe na tabela '%-.64s'", "Não pode abrir a tabela", -"O manipulador de tabela não suporta check/repair", -"Não lhe é permitido executar este comando em uma 'transaction'", +"O manipulador de tabela não suporta checagem/reparação (check/repair)", +"Não lhe é permitido executar este comando em uma transação", "Obteve erro %d durante COMMIT", "Obteve erro %d durante ROLLBACK", "Obteve erro %d durante FLUSH_LOGS", "Obteve erro %d durante CHECKPOINT", -"Conexão %ld abortada ao banco de dados '%-.64s' - usuário '%-.32s' - 'host' `%-.64s' ('%-.64s')", -"O manipulador de tabela não suporta DUMP binário de tabela", +"Conexão %ld abortada para banco de dados '%-.64s' - usuário '%-.32s' - 'host' `%-.64s' ('%-.64s')", +"O manipulador de tabela não suporta 'dump' binário de tabela", "Binlog fechado. Não pode fazer RESET MASTER", -"Falhou na reconstrução do índice da tabela '%-.64s' 'dumped'", +"Falhou na reconstrução do índice da tabela 'dumped' '%-.64s'", "Erro no 'master' '%-.64s'", -"Erro de rede na leitura do 'master'", -"Erro de rede na gravação do 'master'", -"Não pode encontrar índice FULLTEXT que combine com a lista de colunas", -"Não pode executar o comando dado porque você tem tabelas ativas travadas ou uma 'transaction' ativa", -"Variável de sistema '%-.64s' desconhecida", +"Erro de rede lendo do 'master'", +"Erro de rede gravando no 'master'", +"Não pode encontrar um índice para o texto todo que combine com a lista de colunas", +"Não pode executar o comando dado porque você tem tabelas ativas travadas ou uma transação ativa", +"Variável de sistema '%-.64' desconhecida", "Tabela '%-.64s' está marcada como danificada e deve ser reparada", "Tabela '%-.64s' está marcada como danificada e a última reparação (automática?) falhou", -"Aviso: Algumas tabelas não-transacionais alteradas não puderam ser reconstituídas ('rolled back')", -"'Multi-statement transaction' requereu mais do que 'max_binlog_cache_size' bytes de armazenagem. Aumente o valor desta variável do mysqld e tente novamente', +"Aviso: Algumas tabelas não-transacionais alteradas não puderam ser reconstituídas (rolled back)", +"Transações multi-declaradas (multi-statement transactions) requeriram mais do que o valor limite (max_binlog_cache_size) de bytes para armazenagem. Aumente o valor desta variável do mysqld e tente novamente", "Esta operação não pode ser realizada com um 'slave' em execução. Execute SLAVE STOP primeiro", "Esta operação requer um 'slave' em execução. Configure o 'slave' e execute SLAVE START", "O servidor não está configurado como 'slave'. Acerte o arquivo de configuração ou use CHANGE MASTER TO", "Não pode inicializar a estrutura de informação do 'master'. Verifique as permissões em 'master.info'", "Não conseguiu criar 'thread' de 'slave'. Verifique os recursos do sistema", -"Usuário '%-.64s' já possui 'max_user_connections' conexões ativas", -"Você pode usar apenas expressões de constante com SET", -"Excedido tempo de espera (timeout) do travamento", +"Usuário '%-.64s' já possui mais que o valor máximo de conexões (max_user_connections) ativas", +"Você pode usar apenas expressões constantes com SET", +"Tempo de espera (timeout) de travamento excedido. Tente reiniciar a transação.", "O número total de travamentos excede o tamanho da tabela de travamentos", -"Travamentos de atualização não podem ser obtidos durante uma transação de READ UNCOMMITTED", +"Travamentos de atualização não podem ser obtidos durante uma transação de tipo READ UNCOMMITTED", "DROP DATABASE não permitido enquanto uma 'thread' está mantendo um travamento global de leitura", "CREATE DATABASE não permitido enquanto uma 'thread' está mantendo um travamento global de leitura", "Argumentos errados para %s", "Não é permitido a %-.32s@%-.64s criar novos usuários", -"Incorrect table definition; All MERGE tables must be in the same database", -"Deadlock found when trying to get lock; Try restarting transaction", -"The used table type doesn't support FULLTEXT indexes", -"Cannot add foreign key constraint", -"Cannot add a child row: a foreign key constraint fails", -"Cannot delete a parent row: a foreign key constraint fails", +"Definição incorreta da tabela. Todas as tabelas contidas na junção devem estar no mesmo banco de dados.", +"Encontrado um travamento fatal (deadlock) quando tentava obter uma trava. Tente reiniciar a transação.", +"O tipo de tabela utilizado não suporta índices de texto completo (fulltext indexes)", +"Não pode acrescentar uma restrição de chave estrangeira", +"Não pode acrescentar uma linha filha: uma restrição de chave estrangeira falhou", +"Não pode apagar uma linha pai: uma restrição de chave estrangeira falhou", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", "Error when executing command %s: %-.128s", diff --git a/sql/slave.cc b/sql/slave.cc index e8119c6aea2..84e0f6dd236 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -23,7 +23,6 @@ #include "sql_repl.h" #include "repl_failsafe.h" #include <thr_alarm.h> -#include <my_dir.h> #include <assert.h> bool use_slave_mask = 0; @@ -80,9 +79,15 @@ static int request_table_dump(MYSQL* mysql, const char* db, const char* table); static int create_table_from_dump(THD* thd, NET* net, const char* db, const char* table_name); static int check_master_version(MYSQL* mysql, MASTER_INFO* mi); - char* rewrite_db(char* db); + +/* + Get a bit mask for which threads are running so that we later can + restart these threads +*/ + + void init_thread_mask(int* mask,MASTER_INFO* mi,bool inverse) { bool set_io = mi->slave_running, set_sql = mi->rli.slave_running; @@ -104,6 +109,7 @@ void init_thread_mask(int* mask,MASTER_INFO* mi,bool inverse) *mask = tmp_mask; } + void lock_slave_threads(MASTER_INFO* mi) { //TODO: see if we can do this without dual mutex @@ -118,46 +124,45 @@ void unlock_slave_threads(MASTER_INFO* mi) pthread_mutex_unlock(&mi->run_lock); } + int init_slave() { DBUG_ENTER("init_slave"); - // TODO (multi-master): replace this with list initialization + + /* + TODO: re-write this to interate through the list of files + for multi-master + */ active_mi = &main_mi; - // TODO: the code below is a copy-paste mess - clean it up /* - make sure slave thread gets started if server_id is set, - valid master.info is present, and master_host has not been specified + If master_host is not specified, try to read it from the master_info file. + If master_host is specified, create the master_info file if it doesn't + exists. */ - if (server_id && !master_host) + if (init_master_info(active_mi,master_info_file,relay_log_info_file, + !master_host)) { - /* - TODO: re-write this to interate through the list of files - for multi-master - */ - char fname[FN_REFLEN+128]; - MY_STAT stat_area; - fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32); - if (my_stat(fname, &stat_area, MYF(0)) && - !init_master_info(active_mi,master_info_file,relay_log_info_file)) - master_host = active_mi->host; + sql_print_error("Warning: failed to initialized master info"); + DBUG_RETURN(0); } - // slave thread - if (master_host) + + /* + make sure slave thread gets started if server_id is set, + valid master.info is present, and master_host has not been specified + */ + if (server_id && !master_host && active_mi->host[0]) + master_host= active_mi->host; + + if (master_host && !opt_skip_slave_start) { - if (!opt_skip_slave_start) - { - if (start_slave_threads(1 /* need mutex */, - 0 /* no wait for start*/, - active_mi, - master_info_file, - relay_log_info_file, - SLAVE_IO | SLAVE_SQL)) - sql_print_error("Warning: Can't create threads to handle slave"); - } - else if (init_master_info(active_mi, master_info_file, - relay_log_info_file)) - sql_print_error("Warning: failed to initialized master info"); + if (start_slave_threads(1 /* need mutex */, + 0 /* no wait for start*/, + active_mi, + master_info_file, + relay_log_info_file, + SLAVE_IO | SLAVE_SQL)) + sql_print_error("Warning: Can't create threads to handle slave"); } DBUG_RETURN(0); } @@ -175,7 +180,35 @@ static byte* get_table_key(TABLE_RULE_ENT* e, uint* len, return (byte*)e->db; } -// TODO: check proper initialization of master_log_name/master_log_pos + +/* + Open the given relay log + + SYNOPSIS + init_relay_log_pos() + rli Relay information (will be initialized) + log Name of relay log file to read from. NULL = First log + pos Position in relay log file + need_data_lock Set to 1 if this functions should do mutex locks + errmsg Store pointer to error message here + + DESCRIPTION + - Close old open relay log files. + - If we are using the same relay log as the running IO-thread, then set + rli->cur_log to point to the same IO_CACHE entry. + - If not, open the 'log' binary file. + + TODO + - check proper initialization of master_log_name/master_log_pos + - We may always want to delete all logs before 'log'. + Currently if we are not calling this with 'log' as NULL or the first + log we will never delete relay logs. + If we want this we should not set skip_log_purge to 1. + + RETURN VALUES + 0 ok + 1 error. errmsg is set to point to the error message +*/ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log, ulonglong pos, bool need_data_lock, @@ -184,13 +217,14 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log, DBUG_ENTER("init_relay_log_pos"); *errmsg=0; - if (rli->log_pos_current) + if (rli->log_pos_current) // TODO: When can this happen ? DBUG_RETURN(0); pthread_mutex_t *log_lock=rli->relay_log.get_log_lock(); pthread_mutex_lock(log_lock); if (need_data_lock) pthread_mutex_lock(&rli->data_lock); + /* Close log file and free buffers if it's already open */ if (rli->cur_log_fd >= 0) { end_io_cache(&rli->cache_buf); @@ -198,37 +232,37 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log, rli->cur_log_fd = -1; } - if (!log) - log = rli->relay_log_name; // already inited - if (!pos) - pos = rli->relay_log_pos; // already inited - else - rli->relay_log_pos = pos; + rli->relay_log_pos = pos; /* Test to see if the previous run was with the skip of purging If yes, we do not purge when we restart */ - if (rli->relay_log.find_first_log(&rli->linfo,"")) + if (rli->relay_log.find_log_pos(&rli->linfo,NullS)) { *errmsg="Could not find first log during relay log initialization"; goto err; } - if (strcmp(log,rli->linfo.log_file_name)) - rli->skip_log_purge=1; - - if (rli->relay_log.find_first_log(&rli->linfo,log)) + + if (log) // If not first log { - *errmsg="Could not find target log during relay log initialization"; - goto err; + if (strcmp(log, rli->linfo.log_file_name)) + rli->skip_log_purge=1; // Different name; Don't purge + if (rli->relay_log.find_log_pos(&rli->linfo, log)) + { + *errmsg="Could not find target log during relay log initialization"; + goto err; + } } strmake(rli->relay_log_name,rli->linfo.log_file_name, sizeof(rli->relay_log_name)-1); - // to make end_io_cache(&rli->cache_buf) safe in all cases - if (!rli->inited) - bzero((char*) &rli->cache_buf, sizeof(IO_CACHE)); if (rli->relay_log.is_active(rli->linfo.log_file_name)) { + /* + The IO thread is using this log file. + In this case, we will use the same IO_CACHE pointer to + read data as the IO thread is using to write data. + */ if (my_b_tell((rli->cur_log=rli->relay_log.get_log_file())) == 0 && check_binlog_magic(rli->cur_log,errmsg)) goto err; @@ -236,10 +270,9 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log, } else { - if (rli->inited) - end_io_cache(&rli->cache_buf); - if (rli->cur_log_fd >= 0) - my_close(rli->cur_log_fd,MYF(MY_WME)); + /* + Open the relay log and set rli->cur_log to point at this one + */ if ((rli->cur_log_fd=open_binlog(&rli->cache_buf, rli->linfo.log_file_name,errmsg)) < 0) goto err; @@ -257,6 +290,7 @@ err: DBUG_RETURN ((*errmsg) ? 1 : 0); } + /* called from get_options() in mysqld.cc on start-up */ void init_slave_skip_errors(const char* arg) @@ -294,12 +328,13 @@ void init_slave_skip_errors(const char* arg) are not running */ -int purge_relay_logs(RELAY_LOG_INFO* rli, bool just_reset, const char** errmsg) +int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset, + const char** errmsg) { + int error=0; DBUG_ENTER("purge_relay_logs"); if (!rli->inited) DBUG_RETURN(0); /* successfully do nothing */ - int error=0; DBUG_ASSERT(rli->slave_running == 0); DBUG_ASSERT(rli->mi->slave_running == 0); @@ -309,14 +344,14 @@ int purge_relay_logs(RELAY_LOG_INFO* rli, bool just_reset, const char** errmsg) rli->pending=0; rli->master_log_name[0]=0; rli->master_log_pos=0; // 0 means uninitialized - if (rli->relay_log.reset_logs(rli->sql_thd) || - rli->relay_log.find_first_log(&rli->linfo,"")) + if (rli->relay_log.reset_logs(thd)) { *errmsg = "Failed during log reset"; error=1; goto err; } - strmake(rli->relay_log_name,rli->linfo.log_file_name, + /* Save name of used relay log file */ + strmake(rli->relay_log_name, rli->relay_log.get_log_fname(), sizeof(rli->relay_log_name)-1); // Just first log with magic number and nothing else rli->log_space_total= BIN_LOG_HEADER_SIZE; @@ -324,7 +359,8 @@ int purge_relay_logs(RELAY_LOG_INFO* rli, bool just_reset, const char** errmsg) rli->relay_log.reset_bytes_written(); rli->log_pos_current=0; if (!just_reset) - error = init_relay_log_pos(rli,0,0,0 /* do not need data lock */,errmsg); + error= init_relay_log_pos(rli, rli->relay_log_name, rli->relay_log_pos, + 0 /* do not need data lock */, errmsg); err: #ifndef DBUG_OFF @@ -335,6 +371,7 @@ err: DBUG_RETURN(error); } + int terminate_slave_threads(MASTER_INFO* mi,int thread_mask,bool skip_lock) { if (!mi->inited) @@ -374,6 +411,7 @@ int terminate_slave_threads(MASTER_INFO* mi,int thread_mask,bool skip_lock) return 0; } + int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock, pthread_mutex_t *cond_lock, pthread_cond_t* term_cond, @@ -417,6 +455,7 @@ int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock, return 0; } + int start_slave_thread(pthread_handler h_func, pthread_mutex_t* start_lock, pthread_mutex_t *cond_lock, pthread_cond_t* start_cond, @@ -438,13 +477,13 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t* start_lock, } if (*slave_running) - { - if (start_cond) - pthread_cond_broadcast(start_cond); - if (start_lock) - pthread_mutex_unlock(start_lock); - return ER_SLAVE_MUST_STOP; - } + { + if (start_cond) + pthread_cond_broadcast(start_cond); + if (start_lock) + pthread_mutex_unlock(start_lock); + return ER_SLAVE_MUST_STOP; + } if (pthread_create(&th, &connection_attrib, h_func, (void*)mi)) { if (start_lock) @@ -457,7 +496,7 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t* start_lock, while (!*slave_running) { const char* old_msg = thd->enter_cond(start_cond,cond_lock, - "Waiting for slave thread to start"); + "Waiting for slave thread to start"); pthread_cond_wait(start_cond,cond_lock); thd->exit_cond(old_msg); /* @@ -506,8 +545,6 @@ int start_slave_threads(bool need_slave_mutex, bool wait_for_start, lock_cond_io = &mi->run_lock; lock_cond_sql = &mi->rli.run_lock; } - if (init_master_info(mi,master_info_fname,slave_info_fname)) - DBUG_RETURN(ER_MASTER_INFO); if (thread_mask & SLAVE_IO) error=start_slave_thread(handle_slave_io,lock_io,lock_cond_io, @@ -660,6 +697,7 @@ void end_slave() free_string_array(&replicate_wild_ignore_table); } + static bool io_slave_killed(THD* thd, MASTER_INFO* mi) { DBUG_ASSERT(mi->io_thd == thd); @@ -667,6 +705,7 @@ static bool io_slave_killed(THD* thd, MASTER_INFO* mi) return mi->abort_slave || abort_loop || thd->killed; } + static bool sql_slave_killed(THD* thd, RELAY_LOG_INFO* rli) { DBUG_ASSERT(rli->sql_thd == thd); @@ -674,6 +713,7 @@ static bool sql_slave_killed(THD* thd, RELAY_LOG_INFO* rli) return rli->abort_slave || abort_loop || thd->killed; } + void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...) { va_list args; @@ -685,6 +725,7 @@ void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...) rli->last_slave_errno = err_code; } + void skip_load_data_infile(NET* net) { (void)my_net_write(net, "\xfb/dev/null", 10); @@ -693,6 +734,7 @@ void skip_load_data_infile(NET* net) send_ok(net); // the master expects it } + char* rewrite_db(char* db) { if (replicate_rewrite_db.is_empty() || !db) @@ -744,11 +786,11 @@ int db_ok(const char* db, I_List<i_string> &do_list, if (!strcmp(tmp->ptr, db)) return 0; // match } - return 1; } } + static int init_strvar_from_file(char *var, int max_size, IO_CACHE *f, const char *default_val) { @@ -777,6 +819,7 @@ static int init_strvar_from_file(char *var, int max_size, IO_CACHE *f, return 1; } + static int init_intvar_from_file(int* var, IO_CACHE* f, int default_val) { char buf[32]; @@ -794,32 +837,12 @@ static int init_intvar_from_file(int* var, IO_CACHE* f, int default_val) return 1; } + static int check_master_version(MYSQL* mysql, MASTER_INFO* mi) { - MYSQL_RES* res; - MYSQL_ROW row; - const char* version; - const char* errmsg = 0; + const char* errmsg= 0; - if (mc_mysql_query(mysql, "SELECT VERSION()", 0) - || !(res = mc_mysql_store_result(mysql))) - { - sql_print_error("Error checking master version: %s", - mc_mysql_error(mysql)); - return 1; - } - if (!(row = mc_mysql_fetch_row(res))) - { - errmsg = "Master returned no rows for SELECT VERSION()"; - goto err; - } - if (!(version = row[0])) - { - errmsg = "Master reported NULL for the version"; - goto err; - } - - switch (*version) { + switch (*mysql->server_version) { case '3': mi->old_format = 1; break; @@ -829,11 +852,9 @@ static int check_master_version(MYSQL* mysql, MASTER_INFO* mi) break; default: errmsg = "Master reported unrecognized MySQL version"; - goto err; + break; } err: - if (res) - mc_mysql_free_result(res); if (errmsg) { sql_print_error(errmsg); @@ -986,30 +1007,36 @@ int fetch_master_table(THD* thd, const char* db_name, const char* table_name, return error; } + void end_master_info(MASTER_INFO* mi) { + DBUG_ENTER("end_master_info"); + if (!mi->inited) - return; + DBUG_VOID_RETURN; end_relay_log_info(&mi->rli); if (mi->fd >= 0) - { - end_io_cache(&mi->file); - (void)my_close(mi->fd, MYF(MY_WME)); - mi->fd = -1; - } + { + end_io_cache(&mi->file); + (void)my_close(mi->fd, MYF(MY_WME)); + mi->fd = -1; + } mi->inited = 0; + + DBUG_VOID_RETURN; } + int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) { - DBUG_ENTER("init_relay_log_info"); MY_STAT stat_area; char fname[FN_REFLEN+128]; int info_fd; const char* msg = 0; int error = 0; + DBUG_ENTER("init_relay_log_info"); - if (rli->inited) + if (rli->inited) // Set if this function called DBUG_RETURN(0); fn_format(fname, info_fname, mysql_data_home, "", 4+32); pthread_mutex_lock(&rli->data_lock); @@ -1022,6 +1049,7 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) rli->skip_log_purge=0; rli->log_space_limit = relay_log_space_limit; rli->log_space_total = 0; + // TODO: make this work with multi-master if (!opt_relay_logname) { @@ -1034,11 +1062,12 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) strmov(strcend(tmp,'.'),"-relay-bin"); opt_relay_logname=my_strdup(tmp,MYF(MY_WME)); } - rli->relay_log.set_index_file_name(opt_relaylog_index_name); - open_log(&rli->relay_log, glob_hostname, opt_relay_logname, "-relay-bin", - LOG_BIN, 1 /* read_append cache */, - 1 /* no auto events */); - + if (open_log(&rli->relay_log, glob_hostname, opt_relay_logname, + "-relay-bin", opt_relaylog_index_name, + LOG_BIN, 1 /* read_append cache */, + 1 /* no auto events */)) + DBUG_RETURN(1); + /* if file does not exist */ if (!my_stat(fname, &stat_area, MYF(0))) { @@ -1052,13 +1081,12 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) init_io_cache(&rli->info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L,0, MYF(MY_WME))) { - if (info_fd >= 0) - my_close(info_fd, MYF(0)); - rli->info_fd= -1; - pthread_mutex_unlock(&rli->data_lock); - DBUG_RETURN(1); + msg= current_thd->net.last_error; + goto err; } - if (init_relay_log_pos(rli,"",BIN_LOG_HEADER_SIZE,0 /*no data mutex*/, + + /* Init relay log with first entry in the relay index file */ + if (init_relay_log_pos(rli,NullS,BIN_LOG_HEADER_SIZE,0 /* no data lock */, &msg)) goto err; rli->master_log_pos = 0; // uninitialized @@ -1075,6 +1103,7 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) if (info_fd >= 0) my_close(info_fd, MYF(0)); rli->info_fd= -1; + rli->relay_log.close(1); pthread_mutex_unlock(&rli->data_lock); DBUG_RETURN(1); } @@ -1097,38 +1126,42 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) rli->relay_log_pos= relay_log_pos; rli->master_log_pos= master_log_pos; - if (init_relay_log_pos(rli,0 /* log already inited */, - 0 /* pos already inited */, + if (init_relay_log_pos(rli, + rli->relay_log_name, + rli->relay_log_pos, 0 /* no data lock*/, &msg)) - goto err; + goto err; } DBUG_ASSERT(rli->relay_log_pos >= BIN_LOG_HEADER_SIZE); DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->relay_log_pos); - rli->inited = 1; /* Now change the cache from READ to WRITE - must do this before flush_relay_log_info */ reinit_io_cache(&rli->info_file, WRITE_CACHE,0L,0,1); - error=test(flush_relay_log_info(rli)); + error= flush_relay_log_info(rli); if (count_relay_log_space(rli)) { msg="Error counting relay log space"; goto err; } + rli->inited= 1; pthread_mutex_unlock(&rli->data_lock); DBUG_RETURN(error); err: sql_print_error(msg); end_io_cache(&rli->info_file); - my_close(info_fd, MYF(0)); + if (info_fd >= 0) + my_close(info_fd, MYF(0)); rli->info_fd= -1; + rli->relay_log.close(1); pthread_mutex_unlock(&rli->data_lock); DBUG_RETURN(1); } + static inline int add_relay_log(RELAY_LOG_INFO* rli,LOG_INFO* linfo) { MY_STAT s; @@ -1142,11 +1175,12 @@ static inline int add_relay_log(RELAY_LOG_INFO* rli,LOG_INFO* linfo) rli->log_space_total += s.st_size; #ifndef DBUG_OFF char buf[22]; -#endif DBUG_PRINT("info",("log_space_total: %s", llstr(rli->log_space_total,buf))); +#endif DBUG_RETURN(0); } + static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli) { bool slave_killed=0; @@ -1174,7 +1208,7 @@ static int count_relay_log_space(RELAY_LOG_INFO* rli) LOG_INFO linfo; DBUG_ENTER("count_relay_log_space"); rli->log_space_total = 0; - if (rli->relay_log.find_first_log(&linfo,"")) + if (rli->relay_log.find_log_pos(&linfo, NullS)) { sql_print_error("Could not find first log while counting relay log space"); DBUG_RETURN(1); @@ -1189,18 +1223,15 @@ static int count_relay_log_space(RELAY_LOG_INFO* rli) int init_master_info(MASTER_INFO* mi, const char* master_info_fname, - const char* slave_info_fname) + const char* slave_info_fname, + bool abort_if_no_master_info_file) { int fd,error; - MY_STAT stat_area; char fname[FN_REFLEN+128]; DBUG_ENTER("init_master_info"); if (mi->inited) DBUG_RETURN(0); - if (init_relay_log_info(&mi->rli, slave_info_fname)) - DBUG_RETURN(1); - mi->rli.mi = mi; mi->mysql=0; mi->file_id=1; mi->ignore_stop_event=0; @@ -1214,9 +1245,13 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, pthread_mutex_lock(&mi->data_lock); fd = mi->fd; - // we do not want any messages if the file does not exist - if (!my_stat(fname, &stat_area, MYF(0))) + if (access(fname,F_OK)) { + if (abort_if_no_master_info_file) + { + pthread_mutex_unlock(&mi->data_lock); + DBUG_RETURN(0); + } /* if someone removed the file from underneath our feet, just close the old descriptor and re-create the old file @@ -1281,6 +1316,11 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, DBUG_PRINT("master_info",("log_file_name: %s position: %ld", mi->master_log_name, (ulong) mi->master_log_pos)); + + if (init_relay_log_info(&mi->rli, slave_info_fname)) + goto err; + mi->rli.mi = mi; + mi->inited = 1; // now change cache READ -> WRITE - must do this before flush_master_info reinit_io_cache(&mi->file, WRITE_CACHE,0L,0,1); @@ -1289,7 +1329,6 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, DBUG_RETURN(error); err: - end_relay_log_info(&mi->rli); if (fd >= 0) { my_close(fd, MYF(0)); @@ -1300,6 +1339,7 @@ err: DBUG_RETURN(1); } + int register_slave_on_master(MYSQL* mysql) { String packet; @@ -1405,7 +1445,8 @@ int show_master_info(THD* thd, MASTER_INFO* mi) DBUG_RETURN(0); } -int flush_master_info(MASTER_INFO* mi) + +bool flush_master_info(MASTER_INFO* mi) { IO_CACHE* file = &mi->file; char lbuf[22]; @@ -1422,14 +1463,17 @@ int flush_master_info(MASTER_INFO* mi) DBUG_RETURN(0); } + int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, ulonglong log_pos) { - if (!inited) return -1; + if (!inited) + return -1; bool pos_reached = 0; int event_count = 0; pthread_mutex_lock(&data_lock); abort_pos_wait=0; // abort only if master info changes during wait + while (!thd->killed || !abort_pos_wait) { int cmp_result; @@ -1471,6 +1515,7 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, return thd->killed ? -1 : event_count; } + static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) { DBUG_ENTER("init_slave_thread"); @@ -1529,7 +1574,7 @@ static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed, { int nap_time = (int) (end_time - start_time); /* - the only reason we are asking for alarm is so that + The only reason we are asking for alarm is so that we will be woken up in case of murder, so if we do not get killed, set the alarm so it goes off after we wake up naturally */ @@ -1580,6 +1625,7 @@ static int request_dump(MYSQL* mysql, MASTER_INFO* mi, return 0; } + static int request_table_dump(MYSQL* mysql, const char* db, const char* table) { char buf[1024]; @@ -1608,6 +1654,7 @@ command"); return 0; } + /* read one event from the master @@ -1619,6 +1666,7 @@ command"); try a reconnect. We do not want to print anything to the error log in this case because this a anormal event in an idle server. + RETURN VALUES 'packet_error' Error number Length of packet @@ -1627,20 +1675,21 @@ command"); static ulong read_event(MYSQL* mysql, MASTER_INFO *mi, bool* suppress_warnings) { - ulong len = packet_error; + ulong len; + *suppress_warnings= 0; /* my_real_read() will time us out We check if we were told to die, and if not, try reading again + + TODO: Move 'events_till_disconnect' to the MASTER_INFO structure */ #ifndef DBUG_OFF if (disconnect_slave_event_count && !(events_till_disconnect--)) return packet_error; #endif - *suppress_warnings= 0; len = mc_net_safe_read(mysql); - if (len == packet_error || (long) len < 1) { if (mc_mysql_errno(mysql) == ER_NET_READ_INTERRUPTED) @@ -1694,6 +1743,7 @@ point. If you are sure that your master is ok, run this query manually on the\ } } + static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) { DBUG_ASSERT(rli->sql_thd==thd); @@ -1706,7 +1756,15 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) int type_code = ev->get_type_code(); int exec_res; pthread_mutex_lock(&rli->data_lock); - if (ev->server_id == ::server_id || + + /* + Skip queries originating from this server or number of + queries specified by the user in slave_skip_counter + We can't however skip event's that has something to do with the + log files themselves. + */ + + if (ev->server_id == (uint32) ::server_id || (rli->slave_skip_counter && type_code != ROTATE_EVENT)) { /* TODO: I/O thread should not even log events with the same server id */ @@ -1750,6 +1808,7 @@ This may also be a network problem, or just a bug in the master or slave code.\ } } + /* slave I/O thread */ pthread_handler_decl(handle_slave_io,arg) { @@ -1760,7 +1819,7 @@ slave_begin: MYSQL *mysql = NULL ; MASTER_INFO* mi = (MASTER_INFO*)arg; char llbuff[22]; - bool retried_once = 0; + uint retry_count= 0; ulonglong last_failed_pos = 0; // TODO: see if last_failed_pos is needed DBUG_ASSERT(mi->inited); @@ -1771,7 +1830,7 @@ slave_begin: // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff my_thread_init(); - thd = new THD; // note that contructor of THD uses DBUG_ ! + thd= new THD; // note that contructor of THD uses DBUG_ ! DBUG_ENTER("handle_slave_io"); THD_CHECK_SENTRY(thd); @@ -1785,12 +1844,13 @@ slave_begin: } mi->io_thd = thd; thd->thread_stack = (char*)&thd; // remember where our stack is - thd->store_globals(); + pthread_mutex_lock(&LOCK_thread_count); threads.append(thd); + pthread_mutex_unlock(&LOCK_thread_count); mi->slave_running = 1; mi->abort_slave = 0; - pthread_cond_broadcast(&mi->start_cond); pthread_mutex_unlock(&mi->run_lock); + pthread_cond_broadcast(&mi->start_cond); DBUG_PRINT("master_info",("log_file_name: '%s' position: %s", mi->master_log_name, @@ -1802,10 +1862,8 @@ slave_begin: goto err; } + thd->proc_info = "connecting to master"; -#ifndef DBUG_OFF - sql_print_error("Slave I/O thread initialized"); -#endif // we can get killed during safe_connect if (!safe_connect(thd, mysql, mi)) sql_print_error("Slave I/O thread: connected to master '%s@%s:%d',\ @@ -1858,12 +1916,13 @@ dump"); right away - if first time fails, sleep between re-tries hopefuly the admin can fix the problem sometime */ - if (retried_once) + if (retry_count++) + { + if (retry_count > master_retry_count) + goto err; // Don't retry forever safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed, (void*)mi); - else - retried_once = 1; - + } if (io_slave_killed(thd,mi)) { sql_print_error("Slave I/O thread killed while retrying master \ @@ -1894,7 +1953,8 @@ after reconnect"); ulong event_len = read_event(mysql, mi, &suppress_warnings); if (io_slave_killed(thd,mi)) { - sql_print_error("Slave I/O thread killed while reading event"); + if (global_system_variables.log_warnings) + sql_print_error("Slave I/O thread killed while reading event"); goto err; } @@ -1902,24 +1962,27 @@ after reconnect"); { if (mc_mysql_errno(mysql) == ER_NET_PACKET_TOO_LARGE) { - sql_print_error("Log entry on master is longer than \ -max_allowed_packet (%ld) on slave. Slave thread will be aborted. If the entry \ -is correct, restart the server with a higher value of max_allowed_packet", + sql_print_error("\ +Log entry on master is longer than max_allowed_packet (%ld) on \ +slave. If the entry is correct, restart the server with a higher value of \ +max_allowed_packet", thd->variables.max_allowed_packet); goto err; } thd->proc_info = "Waiting to reconnect after a failed read"; mc_end_server(mysql); - if (retried_once) // punish repeat offender with sleep + if (retry_count++) + { + if (retry_count > master_retry_count) + goto err; // Don't retry forever safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed, - (void*)mi); - else - retried_once = 1; - + (void*) mi); + } if (io_slave_killed(thd,mi)) { - sql_print_error("Slave I/O thread killed while waiting to \ + if (global_system_variables.log_warnings) + sql_print_error("Slave I/O thread killed while waiting to \ reconnect after a failed read"); goto err; } @@ -1931,19 +1994,20 @@ reconnecting to retry, log '%s' position %s", IO_RPL_LOG_NAME, if (safe_reconnect(thd, mysql, mi, suppress_warnings) || io_slave_killed(thd,mi)) { - sql_print_error("Slave I/O thread killed during or after a \ + if (global_system_variables.log_warnings) + sql_print_error("Slave I/O thread killed during or after a \ reconnect done to recover from failed read"); goto err; } goto connected; } // if (event_len == packet_error) + retry_count=0; // ok event, reset retry counter thd->proc_info = "Queueing event from master"; if (queue_event(mi,(const char*)mysql->net.read_pos + 1, event_len)) { - sql_print_error("Slave I/O thread could not queue event \ -from master"); + sql_print_error("Slave I/O thread could not queue event from master"); goto err; } flush_master_info(mi); @@ -1962,9 +2026,9 @@ log space"); sql_print_error("Slave I/O thread: debugging abort"); goto err; } -#endif +#endif } - } + } // error = 0; err: @@ -2009,7 +2073,7 @@ pthread_handler_decl(handle_slave_sql,arg) #ifndef DBUG_OFF slave_begin: #endif - THD *thd; /* needs to be first for thread_stack */ + THD *thd; /* needs to be first for thread_stack */ MYSQL *mysql = NULL ; bool retried_once = 0; ulonglong last_failed_pos = 0; // TODO: see if this can be removed @@ -2023,13 +2087,12 @@ slave_begin: rli->events_till_abort = abort_slave_event_count; #endif - // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff my_thread_init(); thd = new THD; // note that contructor of THD uses DBUG_ ! DBUG_ENTER("handle_slave_sql"); + THD_CHECK_SENTRY(thd); - pthread_detach_this_thread(); if (init_slave_thread(thd, SLAVE_THD_SQL)) { @@ -2042,24 +2105,28 @@ slave_begin: sql_print_error("Failed during slave thread initialization"); goto err; } - THD_CHECK_SENTRY(thd); - thd->thread_stack = (char*)&thd; // remember where our stack is + rli->sql_thd= thd; thd->temporary_tables = rli->save_temporary_tables; // restore temp tables - thd->store_globals(); + thd->thread_stack = (char*)&thd; // remember where our stack is + pthread_mutex_lock(&LOCK_thread_count); threads.append(thd); - rli->sql_thd = thd; + pthread_mutex_unlock(&LOCK_thread_count); rli->slave_running = 1; rli->abort_slave = 0; - pthread_cond_broadcast(&rli->start_cond); pthread_mutex_unlock(&rli->run_lock); + pthread_cond_broadcast(&rli->start_cond); // This should always be set to 0 when the slave thread is started rli->pending = 0; - if (init_relay_log_pos(rli,0,0,1 /*need data lock*/, &errmsg)) + if (init_relay_log_pos(rli, + rli->relay_log_name, + rli->relay_log_pos, + 1 /*need data lock*/, &errmsg)) { sql_print_error("Error initializing relay log position: %s", errmsg); goto err; } + THD_CHECK_SENTRY(thd); DBUG_ASSERT(rli->relay_log_pos >= BIN_LOG_HEADER_SIZE); DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->relay_log_pos); DBUG_ASSERT(rli->sql_thd == thd); @@ -2067,11 +2134,14 @@ slave_begin: DBUG_PRINT("master_info",("log_file_name: %s position: %s", rli->master_log_name, llstr(rli->master_log_pos,llbuff))); - - sql_print_error("Slave SQL thread initialized, starting replication in \ + if (global_system_variables.log_warnings) + sql_print_error("Slave SQL thread initialized, starting replication in \ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME, - llstr(rli->master_log_pos,llbuff),rli->relay_log_name, - llstr(rli->relay_log_pos,llbuff1)); + llstr(rli->master_log_pos,llbuff),rli->relay_log_name, + llstr(rli->relay_log_pos,llbuff1)); + + /* Read queries from the IO/THREAD until this thread is killed */ + while (!sql_slave_killed(thd,rli)) { thd->proc_info = "Processing master log event"; @@ -2088,14 +2158,14 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ RPL_LOG_NAME, llstr(rli->master_log_pos, llbuff)); goto err; } - } // while (!sql_slave_killed(thd,rli)) - read/exec loop + } - // error = 0; - err: - // print the current replication position + /* Thread stopped. Print the current replication position to the log */ sql_print_error("Slave SQL thread exiting, replication stopped in log \ '%s' at position %s", RPL_LOG_NAME, llstr(rli->master_log_pos,llbuff)); + + err: thd->query = thd->db = 0; // extra safety thd->proc_info = "Waiting for slave mutex on exit"; pthread_mutex_lock(&rli->run_lock); @@ -2113,7 +2183,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ net_end(&thd->net); // destructor will not free it, because we are weird DBUG_ASSERT(rli->sql_thd == thd); THD_CHECK_SENTRY(thd); - rli->sql_thd = 0; + rli->sql_thd= 0; pthread_mutex_lock(&LOCK_thread_count); THD_CHECK_SENTRY(thd); delete thd; @@ -2402,12 +2472,14 @@ int queue_event(MASTER_INFO* mi,const char* buf, ulong event_len) void end_relay_log_info(RELAY_LOG_INFO* rli) { + DBUG_ENTER("end_relay_log_info"); + if (!rli->inited) - return; + DBUG_VOID_RETURN; if (rli->info_fd >= 0) { end_io_cache(&rli->info_file); - (void)my_close(rli->info_fd, MYF(MY_WME)); + (void) my_close(rli->info_fd, MYF(MY_WME)); rli->info_fd = -1; } if (rli->cur_log_fd >= 0) @@ -2419,6 +2491,7 @@ void end_relay_log_info(RELAY_LOG_INFO* rli) rli->inited = 0; rli->log_pos_current=0; rli->relay_log.close(1); + DBUG_VOID_RETURN; } /* try to connect until successful or slave killed */ @@ -2440,48 +2513,54 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi, int last_errno= -2; // impossible error ulong err_count=0; char llbuff[22]; + DBUG_ENTER("connect_to_master"); #ifndef DBUG_OFF events_till_disconnect = disconnect_slave_event_count; #endif + uint client_flag=0; + if (opt_slave_compressed_protocol) + client_flag=CLIENT_COMPRESS; /* We will use compression */ + while (!(slave_was_killed = io_slave_killed(thd,mi)) && - (reconnect ? mc_mysql_reconnect(mysql) != 0 : + (reconnect ? mc_mysql_reconnect(mysql) != 0: !mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0, - mi->port, 0, 0, + mi->port, 0, client_flag, thd->variables.net_read_timeout))) { /* Don't repeat last error */ if (mc_mysql_errno(mysql) != last_errno) { + last_errno=mc_mysql_errno(mysql); suppress_warnings= 0; sql_print_error("Slave I/O thread: error connecting to master \ '%s@%s:%d': \ -%s, last_errno=%d, retry in %d sec",mi->user,mi->host,mi->port, - mc_mysql_error(mysql), last_errno=mc_mysql_errno(mysql), +Error: '%s' errno: %d retry-time: %d",mi->user,mi->host,mi->port, + mc_mysql_error(mysql), last_errno, mi->connect_retry); } - safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed, - (void*)mi); /* By default we try forever. The reason is that failure will trigger master election, so if the user did not set master_retry_count we - do not want to have electioin triggered on the first failure to + do not want to have election triggered on the first failure to connect */ - if (master_retry_count && err_count++ == master_retry_count) + if (++err_count == master_retry_count) { slave_was_killed=1; if (reconnect) change_rpl_status(RPL_ACTIVE_SLAVE,RPL_LOST_SOLDIER); break; } + safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed, + (void*)mi); } if (!slave_was_killed) { if (reconnect) { - if (!suppress_warnings) + if (!suppress_warnings && global_system_variables.log_warnings) sql_print_error("Slave: connected to master '%s@%s:%d',\ replication resumed in log '%s' at position %s", mi->user, mi->host, mi->port, @@ -2498,8 +2577,8 @@ replication resumed in log '%s' at position %s", mi->user, thd->set_active_vio(mysql->net.vio); #endif } - - return slave_was_killed; + DBUG_PRINT("exit",("slave_was_killed: %d", slave_was_killed)); + DBUG_RETURN(slave_was_killed); } @@ -2515,19 +2594,61 @@ static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi, } -int flush_relay_log_info(RELAY_LOG_INFO* rli) +/* + Store the file and position where the execute-slave thread are in the + relay log. + + SYNOPSIS + flush_relay_log_info() + rli Relay log information + + NOTES + - As this is only called by the slave thread, we don't need to + have a lock on this. + - If there is an active transaction, then we don't update the position + in the relay log. This is to ensure that we re-execute statements + if we die in the middle of an transaction that was rolled back. + - As a transaction never spans binary logs, we don't have to handle the + case where we do a relay-log-rotation in the middle of the transaction. + If this would not be the case, we would have to ensure that we + don't delete the relay log file where the transaction started when + we switch to a new relay log file. + + TODO + - Change the log file information to a binary format to avoid calling + longlong2str. + + RETURN VALUES + 0 ok + 1 write error +*/ + +bool flush_relay_log_info(RELAY_LOG_INFO* rli) { - register IO_CACHE* file = &rli->info_file; - char lbuf[22],lbuf1[22]; - + bool error=0; + IO_CACHE *file = &rli->info_file; + char buff[FN_REFLEN*2+22*2+4], *pos; + + /* sql_thd is not set when calling from init_slave() */ + if ((rli->sql_thd && rli->sql_thd->options & OPTION_BEGIN)) + return 0; // Wait for COMMIT + my_b_seek(file, 0L); - my_b_printf(file, "%s\n%s\n%s\n%s\n", - rli->relay_log_name, llstr(rli->relay_log_pos, lbuf), - rli->master_log_name, llstr(rli->master_log_pos, lbuf1) - ); - flush_io_cache(file); - flush_io_cache(rli->cur_log); - return 0; + pos=strmov(buff, rli->relay_log_name); + *pos++='\n'; + pos=longlong2str(rli->relay_log_pos, pos, 10); + *pos++='\n'; + pos=strmov(pos, rli->master_log_name); + *pos++='\n'; + pos=longlong2str(rli->master_log_pos, pos, 10); + *pos='\n'; + if (my_b_write(file, buff, (ulong) (pos-buff)+1)) + error=1; + if (flush_io_cache(file)) + error=1; + if (flush_io_cache(rli->cur_log)) // QQ Why this call ? + error=1; + return error; } @@ -2643,12 +2764,8 @@ Log_event* next_event(RELAY_LOG_INFO* rli) update. If we do not, show slave status will block */ pthread_mutex_unlock(&rli->data_lock); - - /* - IMPORTANT: note that wait_for_update will unlock lock_log, but - expects the caller to lock it - */ rli->relay_log.wait_for_update(rli->sql_thd); + pthread_mutex_unlock(log_lock); // re-acquire data lock since we released it earlier pthread_mutex_lock(&rli->data_lock); @@ -2680,13 +2797,13 @@ Log_event* next_event(RELAY_LOG_INFO* rli) else { /* - TODO: verify that no lock is ok here. At this point, if we - get this wrong, this is actually no big deal - the only time - this code will ever be executed is if we are recovering from - a bug when a full reload of the slave is not feasible or - desirable. + If hot_log is set, then we already have a lock on + LOCK_log. If not, we have to get the lock. + + According to Sasha, the only time this code will ever be executed + is if we are recovering from a bug. */ - if (rli->relay_log.find_next_log(&rli->linfo,0/*no lock*/)) + if (rli->relay_log.find_next_log(&rli->linfo, !hot_log)) { errmsg = "error switching to the next log"; goto err; @@ -2745,16 +2862,16 @@ event(errno: %d cur_log->error: %d)", my_b_seek(cur_log,rli->relay_log_pos+rli->pending); /* otherwise, we have had a partial read */ errmsg = "Aborting slave SQL thread because of partial event read"; - /* TODO; see if there is a way to do this without this goto */ - goto err; + break; // To end of function } } - if (!errmsg && was_killed) + if (!errmsg && global_system_variables.log_warnings) errmsg = "slave SQL thread was killed"; err: pthread_mutex_unlock(&rli->data_lock); - sql_print_error("Error reading relay log event: %s", errmsg); + if (errmsg) + sql_print_error("Error reading relay log event: %s", errmsg); DBUG_RETURN(0); } diff --git a/sql/slave.h b/sql/slave.h index 36849c884e9..c59ab03c275 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -139,6 +139,14 @@ typedef struct st_relay_log_info ulonglong log_space_limit,log_space_total; /* + InnoDB internally stores the master log position it has processed + so far; the position to store is really the sum of + pos + pending + event_len here since we must store the pos of the + END of the current log event + */ + int event_len; + + /* Needed for problems when slave stops and we want to restart it skipping one or more events in the master log that have caused errors, and have been manually applied by DBA already. @@ -167,6 +175,7 @@ typedef struct st_relay_log_info { relay_log_name[0] = master_log_name[0] = 0; bzero(&info_file,sizeof(info_file)); + bzero(&cache_buf, sizeof(cache_buf)); pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST); pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST); pthread_mutex_init(&log_space_lock, MY_MUTEX_INIT_FAST); @@ -204,7 +213,7 @@ typedef struct st_relay_log_info } /* thread safe read of position - not needed if we are in the slave thread, - but required otherwise + but required otherwise as var is a longlong */ inline void read_pos(ulonglong& var) { @@ -216,6 +225,7 @@ typedef struct st_relay_log_info int wait_for_pos(THD* thd, String* log_name, ulonglong log_pos); } RELAY_LOG_INFO; + Log_event* next_event(RELAY_LOG_INFO* rli); /* @@ -251,7 +261,7 @@ typedef struct st_master_info char master_log_name[FN_REFLEN]; my_off_t master_log_pos; - File fd; + File fd; // we keep the file open, so we need to remember the file pointer IO_CACHE file; /* the variables below are needed because we can change masters on the fly */ @@ -279,7 +289,7 @@ typedef struct st_master_info slave_running(0) { host[0] = 0; user[0] = 0; password[0] = 0; - bzero(&file,sizeof(file)); + bzero(&file, sizeof(file)); pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST); pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST); pthread_cond_init(&data_cond, NULL); @@ -328,8 +338,8 @@ typedef struct st_table_rule_ent int init_slave(); void init_slave_skip_errors(const char* arg); -int flush_master_info(MASTER_INFO* mi); -int flush_relay_log_info(RELAY_LOG_INFO* rli); +bool flush_master_info(MASTER_INFO* mi); +bool flush_relay_log_info(RELAY_LOG_INFO* rli); int register_slave_on_master(MYSQL* mysql); int terminate_slave_threads(MASTER_INFO* mi, int thread_mask, bool skip_lock = 0); @@ -384,7 +394,8 @@ void slave_print_error(RELAY_LOG_INFO* rli,int err_code, const char* msg, ...); void end_slave(); /* clean up */ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, - const char* slave_info_fname); + const char* slave_info_fname, + bool abort_if_no_master_info_file); void end_master_info(MASTER_INFO* mi); int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname); void end_relay_log_info(RELAY_LOG_INFO* rli); @@ -394,7 +405,8 @@ void init_thread_mask(int* mask,MASTER_INFO* mi,bool inverse); int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,ulonglong pos, bool need_data_lock, const char** errmsg); -int purge_relay_logs(RELAY_LOG_INFO* rli,bool just_reset,const char** errmsg); +int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset, + const char** errmsg); extern bool opt_log_slave_updates ; pthread_handler_decl(handle_slave_io,arg); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index e5abd5ce8a7..e2d462aa73c 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -497,10 +497,14 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, ulong user_access=NO_ACCESS; *priv_user=(char*) user; char *ptr=0; + DBUG_ENTER("acl_getroot"); bzero(mqh,sizeof(USER_RESOURCES)); if (!initialized) - return (ulong) ~NO_ACCESS; // If no data allow anything /* purecov: tested */ + { + // If no data allow anything + DBUG_RETURN((ulong) ~NO_ACCESS); /* purecov: tested */ + } VOID(pthread_mutex_lock(&acl_cache->lock)); /* @@ -616,7 +620,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, } } VOID(pthread_mutex_unlock(&acl_cache->lock)); - return user_access; + DBUG_RETURN(user_access); } @@ -1053,15 +1057,14 @@ bool change_password(THD *thd, const char *host, const char *user, VOID(pthread_mutex_unlock(&acl_cache->lock)); char buff[460]; - - Query_log_event qinfo(thd, buff); - qinfo.q_len = + ulong query_length= my_sprintf(buff, (buff,"SET PASSWORD FOR \"%-.120s\"@\"%-.120s\"=\"%-.120s\"", acl_user->user ? acl_user->user : "", acl_user->host.hostname ? acl_user->host.hostname : "", new_password)); - mysql_update_log.write(thd,buff,qinfo.q_len); + mysql_update_log.write(thd, buff, query_length); + Query_log_event qinfo(thd, buff, query_length); mysql_bin_log.write(&qinfo); DBUG_RETURN(0); } @@ -2868,9 +2871,9 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) } } } - db.append (" ON '",5); + db.append (" ON `",5); db.append(acl_db->db); - db.append ("'.* TO '",8); + db.append ("`.* TO '",8); db.append(lex_user->user.str,lex_user->user.length); db.append ("'@'",3); db.append(lex_user->host.str, lex_user->host.length); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 29cc925218f..58d251162ff 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -279,6 +279,7 @@ void intern_close_table(TABLE *table) static void free_cache_entry(TABLE *table) { DBUG_ENTER("free_cache_entry"); + safe_mutex_assert_owner(&LOCK_open); intern_close_table(table); if (!table->in_use) @@ -425,6 +426,7 @@ void close_thread_tables(THD *thd, bool locked) /* VOID(pthread_sigmask(SIG_SETMASK,&thd->block_signals,NULL)); */ if (!locked) VOID(pthread_mutex_lock(&LOCK_open)); + safe_mutex_assert_owner(&LOCK_open); DBUG_PRINT("info", ("thd->open_tables=%p", thd->open_tables)); @@ -550,13 +552,10 @@ void close_temporary_tables(THD *thd) } if (query && found_user_tables && mysql_bin_log.is_open()) { - uint save_query_len = thd->query_length; - *--end = 0; // Remove last ',' - thd->query_length = (uint)(end-query); - Query_log_event qinfo(thd, query); + /* The -1 is to remove last ',' */ + Query_log_event qinfo(thd, query, (ulong)(end-query)-1); qinfo.error_code=0; mysql_bin_log.write(&qinfo); - thd->query_length = save_query_len; } thd->temporary_tables=0; } @@ -669,11 +668,13 @@ TABLE *unlink_open_table(THD *thd, TABLE *list, TABLE *find) /* When we call the following function we must have a lock on - LOCK_OPEN ; This lock will be unlocked on return. + LOCK_open ; This lock will be unlocked on return. */ void wait_for_refresh(THD *thd) { + safe_mutex_assert_owner(&LOCK_open); + /* Wait until the current table is up to date */ const char *proc_info; thd->mysys_var->current_mutex= &LOCK_open; @@ -931,6 +932,7 @@ bool reopen_table(TABLE *table,bool locked) #endif if (!locked) VOID(pthread_mutex_lock(&LOCK_open)); + safe_mutex_assert_owner(&LOCK_open); if (open_unireg_entry(current_thd,&tmp,db,table_name,table->table_name, locked)) @@ -1022,6 +1024,8 @@ bool close_data_tables(THD *thd,const char *db, const char *table_name) bool reopen_tables(THD *thd,bool get_locks,bool in_refresh) { DBUG_ENTER("reopen_tables"); + safe_mutex_assert_owner(&LOCK_open); + if (!thd->open_tables) DBUG_RETURN(0); @@ -1259,6 +1263,8 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, table_list.next=0; if (!locked) pthread_mutex_lock(&LOCK_open); + safe_mutex_assert_owner(&LOCK_open); + if ((error=lock_table_name(thd,&table_list))) { if (error < 0) diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 6cfcff8a7ff..c25a7e5afe4 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -873,10 +873,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) || thd->variables.query_cache_type == 0) - { - DBUG_PRINT("qcache", ("query cache disabled or not in autocommit mode")); goto err; - } /* Check that we haven't forgot to reset the query cache variables */ DBUG_ASSERT(thd->net.query_cache_query == 0); @@ -1021,6 +1018,7 @@ err: DBUG_RETURN(0); // Query was not cached } + /* Remove all cached queries that uses any of the tables in the list */ diff --git a/sql/sql_class.h b/sql/sql_class.h index 633f7a4aa76..6a3daae6274 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -47,7 +47,7 @@ struct st_relay_log_info; typedef struct st_log_info { char log_file_name[FN_REFLEN]; - my_off_t index_file_offset; + my_off_t index_file_offset, index_file_start_offset; my_off_t pos; bool fatal; // if the purge happens to give us a negative offset pthread_mutex_t lock; @@ -64,7 +64,7 @@ class MYSQL_LOG { ulonglong bytes_written; time_t last_time,query_start; IO_CACHE log_file; - File index_file; + IO_CACHE index_file; char *name; char time_buff[20],db[NAME_LEN+1]; char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN]; @@ -106,16 +106,14 @@ public: void signal_update() { pthread_cond_broadcast(&update_cond);} void wait_for_update(THD* thd); void set_need_start_event() { need_start_event = 1; } - void set_index_file_name(const char* index_file_name = 0); void init(enum_log_type log_type_arg, enum cache_type io_cache_type_arg = WRITE_CACHE, bool no_auto_events_arg = 0); - void open(const char *log_name,enum_log_type log_type, - const char *new_name, enum cache_type io_cache_type_arg, + bool open(const char *log_name,enum_log_type log_type, + const char *new_name, const char *index_file_name_arg, + enum cache_type io_cache_type_arg, bool no_auto_events_arg); - void new_file(bool inside_mutex = 0); - bool open_index(int options); - void close_index(); + void new_file(bool need_lock= 1); bool write(THD *thd, enum enum_server_command command, const char *format,...); bool write(THD *thd, const char *query, uint query_length, @@ -135,13 +133,13 @@ public: bool is_active(const char* log_file_name); int purge_logs(THD* thd, const char* to_log); int purge_first_log(struct st_relay_log_info* rli); - int reset_logs(THD* thd); + bool reset_logs(THD* thd); // if we are exiting, we also want to close the index file void close(bool exiting = 0); // iterating through the log index file - int find_first_log(LOG_INFO* linfo, const char* log_name, - bool need_mutex=1); + int find_log_pos(LOG_INFO* linfo, const char* log_name, + bool need_mutex=1); int find_next_log(LOG_INFO* linfo, bool need_mutex=1); int get_current_log(LOG_INFO* linfo); uint next_file_id(); @@ -154,7 +152,7 @@ public: inline void lock_index() { pthread_mutex_lock(&LOCK_index);} inline void unlock_index() { pthread_mutex_unlock(&LOCK_index);} - inline File get_index_file() { return index_file;} + inline IO_CACHE *get_index_file() { return &index_file;} inline uint32 get_open_count() { return open_count; } }; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 87926d0612c..0e2cfba1b30 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -85,7 +85,7 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent) mysql_update_log.write(thd,thd->query, thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query); + Query_log_event qinfo(thd, thd->query, thd->query_length); mysql_bin_log.write(&qinfo); } } @@ -153,7 +153,9 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) send_ok(&thd->net,0); goto exit; } + pthread_mutex_lock(&LOCK_open); remove_db_from_cache(db); + pthread_mutex_unlock(&LOCK_open); error = -1; if ((deleted=mysql_rm_known_files(thd, dirp, db, path,0)) >= 0 && thd) @@ -171,7 +173,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query); + Query_log_event qinfo(thd, thd->query, thd->query_length); mysql_bin_log.write(&qinfo); } if (thd->query == path) diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 8ce25f257f5..eaa8c6c2a67 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -167,7 +167,8 @@ cleanup: mysql_update_log.write(thd,thd->query, thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, using_transactions); + Query_log_event qinfo(thd, thd->query, thd->query_length, + using_transactions); if (mysql_bin_log.write(&qinfo) && using_transactions) error=1; } @@ -469,7 +470,7 @@ bool multi_delete::send_eof() mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query); + Query_log_event qinfo(thd, thd->query, thd->query_length); if (mysql_bin_log.write(&qinfo) && !not_trans_safe) error=1; // Log write failed: roll back the SQL statement @@ -572,7 +573,7 @@ end: mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query); + Query_log_event qinfo(thd, thd->query, thd->query_length); mysql_bin_log.write(&qinfo); } send_ok(&thd->net); // This should return record count diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 053e96c5fdd..61d3544bfe0 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -301,7 +301,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields, mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, using_transactions); + Query_log_event qinfo(thd, thd->query, thd->query_length, + using_transactions); if (mysql_bin_log.write(&qinfo) && using_transactions) error=1; } @@ -1196,8 +1197,7 @@ bool delayed_insert::handle_inserts(void) mysql_update_log.write(&thd,row->query, row->query_length); if (using_bin_log) { - thd.query_length = row->query_length; - Query_log_event qinfo(&thd, row->query); + Query_log_event qinfo(&thd, row->query, row->query_length); mysql_bin_log.write(&qinfo); } } @@ -1377,7 +1377,7 @@ bool select_insert::send_eof() mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, + Query_log_event qinfo(thd, thd->query, thd->query_length, table->file->has_transactions()); mysql_bin_log.write(&qinfo); } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 9c1e017a4f6..9be8703b6c5 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -44,6 +44,7 @@ enum enum_sql_command { SQLCOM_SHOW_DATABASES, SQLCOM_SHOW_TABLES, SQLCOM_SHOW_FIELDS, SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_LOGS, SQLCOM_SHOW_STATUS, + SQLCOM_SHOW_INNODB_STATUS, SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT, SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3aff3255706..19b58ffbd25 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -23,6 +23,10 @@ #include <my_dir.h> #include <assert.h> +#ifdef HAVE_INNOBASE_DB +#include "ha_innodb.h" +#endif + #ifdef HAVE_OPENSSL /* Without SSL the handshake consists of one packet. This packet @@ -1426,9 +1430,22 @@ mysql_execute_command(void) case SQLCOM_LOAD_MASTER_DATA: // sync with master if (check_global_access(thd, SUPER_ACL)) goto error; - res = load_master_data(thd); + if (end_active_trans(thd)) + res= -1; + else + res = load_master_data(thd); break; +#ifdef HAVE_INNOBASE_DB + case SQLCOM_SHOW_INNODB_STATUS: + { + if (check_global_access(thd, SUPER_ACL)) + goto error; + res = innodb_show_status(thd); + break; + } +#endif + case SQLCOM_LOAD_MASTER_TABLE: { if (!tables->db) @@ -2307,7 +2324,7 @@ mysql_execute_command(void) mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query); + Query_log_event qinfo(thd, thd->query, thd->query_length); mysql_bin_log.write(&qinfo); } } @@ -2327,7 +2344,7 @@ mysql_execute_command(void) mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query); + Query_log_event qinfo(thd, thd->query, thd->query_length); mysql_bin_log.write(&qinfo); } if (mqh_used && lex->sql_command == SQLCOM_GRANT) @@ -3313,8 +3330,6 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) bool result=0; select_errors=0; /* Write if more errors */ - // TODO: figure out what's up with the commented out line below - // mysql_log.flush(); // Flush log if (options & REFRESH_GRANT) { acl_reload(); @@ -3370,7 +3385,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) if (options & REFRESH_SLAVE) { LOCK_ACTIVE_MI; - if (reset_slave(active_mi)) + if (reset_slave(thd, active_mi)) result=1; UNLOCK_ACTIVE_MI; } diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 305491c7346..049690eb318 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -94,7 +94,7 @@ end: mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query); + Query_log_event qinfo(thd, thd->query, thd->query_length); mysql_bin_log.write(&qinfo); } send_ok(&thd->net); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 3e652a4d5a6..9cc596f9bb5 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -180,6 +180,27 @@ err: } +/* + Adjust the position pointer in the binary log file for all running slaves + + SYNOPSIS + adjust_linfo_offsets() + purge_offset Number of bytes removed from start of log index file + + NOTES + - This is called when doing a PURGE when we delete lines from the + index log file + + REQUIREMENTS + - Before calling this function, we have to ensure that no threads are + using any binary log file before purge_offset.a + + TODO + - Inform the slave threads that they should sync the position + in the binary log file with flush_relay_log_info. + Now they sync is done for next read. +*/ + void adjust_linfo_offsets(my_off_t purge_offset) { THD *tmp; @@ -193,9 +214,10 @@ void adjust_linfo_offsets(my_off_t purge_offset) if ((linfo = tmp->current_linfo)) { pthread_mutex_lock(&linfo->lock); - /* index file offset can be less that purge offset - only if we just started reading the index file. In that case - we have nothing to adjust + /* + Index file offset can be less that purge offset only if + we just started reading the index file. In that case + we have nothing to adjust */ if (linfo->index_file_offset < purge_offset) linfo->fatal = (linfo->index_file_offset != 0); @@ -274,7 +296,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) { LOG_INFO linfo; char *log_file_name = linfo.log_file_name; - char search_file_name[FN_REFLEN]; + char search_file_name[FN_REFLEN], *name; IO_CACHE log; File file = -1; String* packet = &thd->packet; @@ -295,7 +317,6 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) } #endif - if (!mysql_bin_log.is_open()) { errmsg = "Binary log is not open"; @@ -307,17 +328,18 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) goto err; } + name=search_file_name; if (log_ident[0]) mysql_bin_log.make_log_name(search_file_name, log_ident); else - search_file_name[0] = 0; + name=0; // Find first log linfo.index_file_offset = 0; thd->current_linfo = &linfo; - if (mysql_bin_log.find_first_log(&linfo, search_file_name)) + if (mysql_bin_log.find_log_pos(&linfo, name)) { - errmsg = "Could not find first log"; + errmsg = "Could not find first log file name in binary log index file"; goto err; } @@ -332,19 +354,19 @@ impossible position"; } my_b_seek(&log, pos); // Seek will done on next read - packet->length(0); - // we need to start a packet with something other than 255 - // to distiquish it from error - packet->append("\0", 1); + /* + We need to start a packet with something other than 255 + to distiquish it from error + */ + packet->set("\0", 1); // if we are at the start of the log - if (pos == 4) + if (pos == BIN_LOG_HEADER_SIZE) { // tell the client log name with a fake rotate_event if (fake_rotate_event(net, packet, log_file_name, &errmsg)) goto err; - packet->length(0); - packet->append("\0", 1); + packet->set("\0", 1); } while (!net->error && net->vio != 0 && !thd->killed) @@ -376,20 +398,21 @@ impossible position"; goto err; } } - packet->length(0); - packet->append("\0",1); + packet->set("\0", 1); } - // TODO: now that we are logging the offset, check to make sure - // the recorded offset and the actual match + /* + TODO: now that we are logging the offset, check to make sure + the recorded offset and the actual match + */ if (error != LOG_READ_EOF) { - switch(error) { + switch (error) { case LOG_READ_BOGUS: errmsg = "bogus data in log event"; break; case LOG_READ_TOO_LARGE: - errmsg = "log event entry exceeded max_allowed_packet -\ - increase max_allowed_packet on master"; + errmsg = "log event entry exceeded max_allowed_packet; \ +Increase max_allowed_packet on master"; break; case LOG_READ_IO: errmsg = "I/O error reading log event"; @@ -410,18 +433,21 @@ impossible position"; if (!(flags & BINLOG_DUMP_NON_BLOCK) && mysql_bin_log.is_active(log_file_name)) { - // block until there is more data in the log - // unless non-blocking mode requested + /* + Block until there is more data in the log + */ if (net_flush(net)) { errmsg = "failed on net_flush()"; goto err; } - // we may have missed the update broadcast from the log - // that has just happened, let's try to catch it if it did - // if we did not miss anything, we just wait for other threads - // to signal us + /* + We may have missed the update broadcast from the log + that has just happened, let's try to catch it if it did. + If we did not miss anything, we just wait for other threads + to signal us. + */ { log.error=0; bool read_packet = 0, fatal_error = 0; @@ -435,32 +461,32 @@ impossible position"; } #endif - // no one will update the log while we are reading - // now, but we'll be quick and just read one record + /* + No one will update the log while we are reading + now, but we'll be quick and just read one record + + To be able to handle EOF properly, we have to have the + pthread_mutex_unlock() statements in the case statements. + */ pthread_mutex_lock(log_lock); - switch (Log_event::read_log_event(&log, packet, (pthread_mutex_t*)0)) - { + switch (Log_event::read_log_event(&log, packet, (pthread_mutex_t*)0)) { case 0: - pthread_mutex_unlock(log_lock); + /* we read successfully, so we'll need to send it to the slave */ read_packet = 1; - // we read successfully, so we'll need to send it to the - // slave break; + case LOG_READ_EOF: DBUG_PRINT("wait",("waiting for data in binary log")); - // wait_for_update unlocks the log lock - needed to avoid race if (!thd->killed) mysql_bin_log.wait_for_update(thd); - else - pthread_mutex_unlock(log_lock); DBUG_PRINT("wait",("binary log received update")); break; default: - pthread_mutex_unlock(log_lock); fatal_error = 1; break; } + pthread_mutex_unlock(log_lock); if (read_packet) { @@ -479,10 +505,11 @@ impossible position"; goto err; } } - packet->length(0); - packet->append("\0",1); - // no need to net_flush because we will get to flush later when - // we hit EOF pretty quick + packet->set("\0", 1); + /* + No need to net_flush because we will get to flush later when + we hit EOF pretty quick + */ } if (fatal_error) @@ -539,7 +566,6 @@ impossible position"; err: thd->proc_info = "waiting to finalize termination"; end_io_cache(&log); - pthread_mutex_lock(&LOCK_thread_count); /* Exclude iteration through thread list this is needed for purge_logs() - it will iterate through @@ -547,6 +573,7 @@ impossible position"; this mutex will make sure that it never tried to update our linfo after we return from this stack frame */ + pthread_mutex_lock(&LOCK_thread_count); thd->current_linfo = 0; pthread_mutex_unlock(&LOCK_thread_count); if (file >= 0) @@ -561,16 +588,19 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report) if (!thd) thd = current_thd; NET* net = &thd->net; int thread_mask; + DBUG_ENTER("start_slave"); if (check_access(thd, SUPER_ACL, any_db)) - return 1; + DBUG_RETURN(1); lock_slave_threads(mi); // this allows us to cleanly read slave_running init_thread_mask(&thread_mask,mi,1 /* inverse */); if (thd->lex.slave_thd_opt) thread_mask &= thd->lex.slave_thd_opt; if (thread_mask) { - if (server_id_supplied && (!mi->inited || (mi->inited && *mi->host))) + if (init_master_info(mi,master_info_file,relay_log_info_file, 0)) + slave_errno=ER_MASTER_INFO; + else if (server_id_supplied && *mi->host) slave_errno = start_slave_threads(0 /*no mutex */, 1 /* wait for start */, mi, @@ -588,12 +618,12 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report) { if (net_report) send_error(net, slave_errno); - return 1; + DBUG_RETURN(1); } else if (net_report) send_ok(net); - return 0; + DBUG_RETURN(0); } int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report ) @@ -628,7 +658,7 @@ int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report ) return 0; } -int reset_slave(MASTER_INFO* mi) +int reset_slave(THD *thd, MASTER_INFO* mi) { MY_STAT stat_area; char fname[FN_REFLEN]; @@ -639,7 +669,9 @@ int reset_slave(MASTER_INFO* mi) lock_slave_threads(mi); init_thread_mask(&restart_thread_mask,mi,0 /* not inverse */); if ((error=terminate_slave_threads(mi,restart_thread_mask,1 /*skip lock*/)) - || (error=purge_relay_logs(&mi->rli,1 /*just reset*/,&errmsg))) + || (error=purge_relay_logs(&mi->rli, thd, + 1 /* just reset */, + &errmsg))) goto err; end_master_info(mi); @@ -713,16 +745,17 @@ int change_master(THD* thd, MASTER_INFO* mi) thd->proc_info = "changing master"; LEX_MASTER_INFO* lex_mi = &thd->lex.mi; // TODO: see if needs re-write - if (init_master_info(mi,master_info_file,relay_log_info_file)) + if (init_master_info(mi, master_info_file, relay_log_info_file, 0)) { send_error(&thd->net, 0, "Could not initialize master info"); unlock_slave_threads(mi); DBUG_RETURN(1); } - /* data lock not needed since we have already stopped the running threads, - and we have the hold on the run locks which will keep all threads that - could possibly modify the data structures from running + /* + Data lock not needed since we have already stopped the running threads, + and we have the hold on the run locks which will keep all threads that + could possibly modify the data structures from running */ if ((lex_mi->host || lex_mi->port) && !lex_mi->log_file_name && !lex_mi->pos) { @@ -772,7 +805,8 @@ int change_master(THD* thd, MASTER_INFO* mi) { mi->rli.skip_log_purge=0; thd->proc_info="purging old relay logs"; - if (purge_relay_logs(&mi->rli,0 /* not only reset, but also reinit*/, + if (purge_relay_logs(&mi->rli, thd, + 0 /* not only reset, but also reinit */, &errmsg)) { net_printf(&thd->net, 0, "Failed purging old relay logs: %s",errmsg); @@ -782,12 +816,13 @@ int change_master(THD* thd, MASTER_INFO* mi) else { const char* msg; - if (init_relay_log_pos(&mi->rli,0/*log already inited*/, - 0 /*pos already inited*/, + /* Relay log is already initialized */ + if (init_relay_log_pos(&mi->rli, + mi->rli.relay_log_name, + mi->rli.relay_log_pos, 0 /*no data lock*/, &msg)) { - //Sasha: note that I had to change net_printf() to make this work net_printf(&thd->net,0,"Failed initializing relay log position: %s",msg); unlock_slave_threads(mi); DBUG_RETURN(1); @@ -857,26 +892,27 @@ int show_binlog_events(THD* thd) if (mysql_bin_log.is_open()) { - LOG_INFO linfo; - char search_file_name[FN_REFLEN]; - LEX_MASTER_INFO* lex_mi = &thd->lex.mi; + LEX_MASTER_INFO *lex_mi = &thd->lex.mi; uint event_count, limit_start, limit_end; - const char* log_file_name = lex_mi->log_file_name; - Log_event* ev; my_off_t pos = lex_mi->pos; + char search_file_name[FN_REFLEN], *name; + const char *log_file_name = lex_mi->log_file_name; + LOG_INFO linfo; + Log_event* ev; limit_start = thd->lex.select->offset_limit; limit_end = thd->lex.select->select_limit + limit_start; + name= search_file_name; if (log_file_name) mysql_bin_log.make_log_name(search_file_name, log_file_name); else - search_file_name[0] = 0; + name=0; // Find first log linfo.index_file_offset = 0; thd->current_linfo = &linfo; - if (mysql_bin_log.find_first_log(&linfo, search_file_name)) + if (mysql_bin_log.find_log_pos(&linfo, name)) { errmsg = "Could not find target log"; goto err; @@ -981,71 +1017,65 @@ int show_binlog_info(THD* thd) } +/* + Send a lost of all binary logs to client + + SYNOPSIS + show_binlogs() + thd Thread specific variable + + RETURN VALUES + 0 ok + 1 error (Error message sent to client) +*/ + int show_binlogs(THD* thd) { - const char* errmsg = 0; - File index_file; + const char *errmsg; + IO_CACHE *index_file; char fname[FN_REFLEN]; NET* net = &thd->net; List<Item> field_list; - String* packet = &thd->packet; - IO_CACHE io_cache; + String *packet = &thd->packet; uint length; if (!mysql_bin_log.is_open()) { - errmsg = "binlog is not open"; - goto err; + //TODO: Replace with ER() error message + errmsg= "You are not using binary logging"; + goto err_with_msg; } - field_list.push_back(new Item_empty_string("Log_name", 128)); + field_list.push_back(new Item_empty_string("Log_name", 255)); if (send_fields(thd, field_list, 1)) - { - sql_print_error("Failed in send_fields"); return 1; - } - mysql_bin_log.lock_index(); - index_file = mysql_bin_log.get_index_file(); - if (index_file < 0) - { - errmsg = "Uninitialized index file pointer"; - goto err2; - } - if (init_io_cache(&io_cache, index_file, IO_SIZE, READ_CACHE, 0, 0, - MYF(MY_WME))) - { - errmsg = "Failed on init_io_cache()"; - goto err2; - } - while ((length=my_b_gets(&io_cache, fname, sizeof(fname)))) + index_file=mysql_bin_log.get_index_file(); + + reinit_io_cache(index_file, READ_CACHE, (my_off_t) 0, 0, 0); + + /* The file ends with EOF or empty line */ + while ((length=my_b_gets(index_file, fname, sizeof(fname))) > 1) { - fname[--length]=0; int dir_len = dirname_length(fname); packet->length(0); - net_store_data(packet, fname + dir_len, length-dir_len); + /* The -1 is for removing newline from fname */ + net_store_data(packet, fname + dir_len, length-1-dir_len); if (my_net_write(net, (char*) packet->ptr(), packet->length())) - { - sql_print_error("Failed in my_net_write"); - end_io_cache(&io_cache); - mysql_bin_log.unlock_index(); - return 1; - } + goto err; } - mysql_bin_log.unlock_index(); - end_io_cache(&io_cache); send_eof(net); return 0; -err2: - mysql_bin_log.unlock_index(); - end_io_cache(&io_cache); -err: +err_with_msg: send_error(net, 0, errmsg); +err: + mysql_bin_log.unlock_index(); return 1; } + int log_loaded_block(IO_CACHE* file) { LOAD_FILE_INFO* lf_info; diff --git a/sql/sql_repl.h b/sql/sql_repl.h index 6770f8aa01a..af4fb33c9ef 100644 --- a/sql/sql_repl.h +++ b/sql/sql_repl.h @@ -31,7 +31,7 @@ int change_master(THD* thd, MASTER_INFO* mi); int show_binlog_events(THD* thd); int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1, const char* log_file_name2, ulonglong log_pos2); -int reset_slave(MASTER_INFO* mi); +int reset_slave(THD *thd, MASTER_INFO* mi); int reset_master(THD* thd); int purge_master_logs(THD* thd, const char* to_log); bool log_in_use(const char* log_name); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 98e3c21293e..5a5745f87cd 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5781,7 +5781,6 @@ remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having) ulong reclength,offset; uint field_count; THD *thd= current_thd; - DBUG_ENTER("remove_duplicates"); entry->reginfo.lock_type=TL_WRITE; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 296db748c03..df84bff0adc 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -20,6 +20,7 @@ #include "mysql_priv.h" #include <hash.h> #include <myisam.h> +#include <assert.h> #ifdef __WIN__ #include <io.h> @@ -181,7 +182,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, mysql_update_log.write(thd, thd->query,thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query); + Query_log_event qinfo(thd, thd->query, thd->query_length); mysql_bin_log.write(&qinfo); } } @@ -670,7 +671,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, mysql_update_log.write(thd,thd->query, thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query); + Query_log_event qinfo(thd, thd->query, thd->query_length); mysql_bin_log.write(&qinfo); } } @@ -834,6 +835,8 @@ bool close_cached_table(THD *thd,TABLE *table) { bool result=0; DBUG_ENTER("close_cached_table"); + safe_mutex_assert_owner(&LOCK_open); + if (table) { DBUG_PRINT("enter",("table: %s", table->table_name)); @@ -918,13 +921,17 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, fn_format(dst_path, dst_path,"", reg_ext, 4), MYF(MY_WME))) { + pthread_mutex_lock(&LOCK_open); unlock_table_name(thd, table); + pthread_mutex_unlock(&LOCK_open); DBUG_RETURN(send_check_errmsg(thd, table, "restore", "Failed copying .frm file")); } if (mysql_truncate(thd, table, 1)) { + pthread_mutex_lock(&LOCK_open); unlock_table_name(thd, table); + pthread_mutex_unlock(&LOCK_open); DBUG_RETURN(send_check_errmsg(thd, table, "restore", "Failed generating table from .frm file")); } @@ -935,7 +942,11 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, to finish the restore in the handler later on */ if (!(table->table = reopen_name_locked_table(thd, table))) + { + pthread_mutex_lock(&LOCK_open); unlock_table_name(thd, table); + pthread_mutex_unlock(&LOCK_open); + } DBUG_RETURN(0); } @@ -1000,7 +1011,8 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, thr_lock_type lock_type, bool open_for_modify, uint extra_open_options, - int (*prepare_func)(THD *, TABLE_LIST *, HA_CHECK_OPT *), + int (*prepare_func)(THD *, TABLE_LIST *, + HA_CHECK_OPT *), int (handler::*operator_func) (THD *, HA_CHECK_OPT *)) { @@ -1141,8 +1153,10 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, table->table->version=0; // Force close of table else if (open_for_modify) { + pthread_mutex_lock(&LOCK_open); remove_table_from_cache(thd, table->table->table_cache_key, table->table->real_name); + pthread_mutex_unlock(&LOCK_open); /* May be something modified consequently we have to invalidate cache */ query_cache_invalidate3(thd, table->table, 0); } @@ -1171,6 +1185,7 @@ int mysql_backup_table(THD* thd, TABLE_LIST* table_list) &handler::backup)); } + int mysql_restore_table(THD* thd, TABLE_LIST* table_list) { DBUG_ENTER("mysql_restore_table"); @@ -1180,6 +1195,7 @@ int mysql_restore_table(THD* thd, TABLE_LIST* table_list) &handler::restore)); } + int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) { DBUG_ENTER("mysql_repair_table"); @@ -1189,6 +1205,7 @@ int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) &handler::repair)); } + int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) { DBUG_ENTER("mysql_optimize_table"); @@ -1352,7 +1369,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query); + Query_log_event qinfo(thd, thd->query, thd->query_length); mysql_bin_log.write(&qinfo); } send_ok(&thd->net); @@ -1717,7 +1734,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, mysql_update_log.write(thd, thd->query,thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query); + Query_log_event qinfo(thd, thd->query, thd->query_length); mysql_bin_log.write(&qinfo); } goto end_temporary; @@ -1842,12 +1859,16 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, VOID(pthread_mutex_unlock(&LOCK_open)); goto err; } - +#ifdef HAVE_BERKELEY_DB + extern bool berkeley_flush_logs(void); + if (old_db_type == DB_TYPE_BERKELEY_DB && berkeley_flush_logs()) + goto err; +#endif thd->proc_info="end"; mysql_update_log.write(thd, thd->query,thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query); + Query_log_event qinfo(thd, thd->query, thd->query_length); mysql_bin_log.write(&qinfo); } VOID(pthread_cond_broadcast(&COND_refresh)); diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 9c458c27b95..b226bc1300a 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -242,6 +242,7 @@ Open streams: %10lu\n", (ulong) my_stream_opened); ALARM_INFO alarm_info; +#ifndef DONT_USE_THR_ALARM thr_alarm_info(&alarm_info); printf("\nAlarm status:\n\ Active alarms: %u\n\ @@ -250,7 +251,7 @@ Next alarm time: %lu\n", alarm_info.active_alarms, alarm_info.max_used_alarms, alarm_info.next_alarm_time); - +#endif fflush(stdout); if (thd) thd->proc_info="malloc"; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index a1a18560a9f..b5df0e03823 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -307,7 +307,8 @@ int mysql_update(THD *thd, mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, using_transactions); + Query_log_event qinfo(thd, thd->query, thd->query_length, + using_transactions); if (mysql_bin_log.write(&qinfo) && using_transactions) error=1; } @@ -789,7 +790,7 @@ bool multi_update::send_eof() if (updated || not_trans_safe) { mysql_update_log.write(thd,thd->query,thd->query_length); - Query_log_event qinfo(thd, thd->query); + Query_log_event qinfo(thd, thd->query, thd->query_length); /* mysql_bin_log is not open if binlogging or replication diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ade69236e96..97a4c5308ba 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -262,6 +262,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token NEW_SYM %token NCHAR_SYM %token NOT +%token NO_FOREIGN_KEY_CHECKS %token NO_SYM %token NULL_SYM %token NUM @@ -291,6 +292,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token REAL_NUM %token REFERENCES %token REGEXP +%token RELAXED_UNIQUE_CHECKS %token RELOAD %token RENAME %token REPEATABLE_SYM @@ -2709,6 +2711,8 @@ show_param: } | STATUS_SYM wild { Lex->sql_command= SQLCOM_SHOW_STATUS; } + | INNOBASE_SYM STATUS_SYM + { Lex->sql_command = SQLCOM_SHOW_INNODB_STATUS;} | opt_full PROCESSLIST_SYM { Lex->sql_command= SQLCOM_SHOW_PROCESSLIST;} | opt_var_type VARIABLES wild diff --git a/sql/table.cc b/sql/table.cc index 2a284d4c027..cc5666ff5fb 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -776,7 +776,7 @@ ulong make_new_entry(File file, uchar *fileinfo, TYPELIB *formnames, int2store(fileinfo+8,names+1); int2store(fileinfo+4,n_length+length); - VOID(my_chsize(file,newpos,MYF(MY_WME))); /* Append file with '\0' */ + VOID(my_chsize(file, newpos, 0, MYF(MY_WME)));/* Append file with '\0' */ DBUG_RETURN(newpos); } /* make_new_entry */ diff --git a/support-files/my-huge.cnf.sh b/support-files/my-huge.cnf.sh index 88d83afb986..50a14b0fc96 100644 --- a/support-files/my-huge.cnf.sh +++ b/support-files/my-huge.cnf.sh @@ -61,20 +61,19 @@ server-id = 1 # required unique id between 1 and 2^32 - 1 #set-variable = bdb_cache_size=384M #set-variable = bdb_max_lock=100000 -# Uncomment the following if you are using Innobase tables -#innodb_data_file_path = ibdata1:2000M;ibdata2:2000M +# Uncomment the following if you are using InnoDB tables #innodb_data_home_dir = @localstatedir@/ +#innodb_data_file_path = ibdata1:2000M;ibdata2:10M:autoextend #innodb_log_group_home_dir = @localstatedir@/ #innodb_log_arch_dir = @localstatedir@/ -#set-variable = innodb_mirrored_log_groups=1 -#set-variable = innodb_log_files_in_group=3 -#set-variable = innodb_log_file_size=5M +# You can set .._buffer_pool_size up to 50 - 80 % +# of RAM but beware of setting memory usage too high +#set-variable = innodb_buffer_pool_size=384M +#set-variable = innodb_additional_mem_pool_size=20M +# Set .._log_file_size to 25 % of buffer pool size +#set-variable = innodb_log_file_size=100M #set-variable = innodb_log_buffer_size=8M #innodb_flush_log_at_trx_commit=1 -#innodb_log_archive=0 -#set-variable = innodb_buffer_pool_size=16M -#set-variable = innodb_additional_mem_pool_size=2M -#set-variable = innodb_file_io_threads=4 #set-variable = innodb_lock_wait_timeout=50 [mysqldump] diff --git a/support-files/my-large.cnf.sh b/support-files/my-large.cnf.sh index 0602921abc1..3c388d611d8 100644 --- a/support-files/my-large.cnf.sh +++ b/support-files/my-large.cnf.sh @@ -42,20 +42,19 @@ server-id = 1 #set-variable = bdb_cache_size=64M #set-variable = bdb_max_lock=100000 -# Uncomment the following if you are using Innobase tables -#innodb_data_file_path = ibdata1:1000M +# Uncomment the following if you are using InnoDB tables #innodb_data_home_dir = @localstatedir@/ +#innodb_data_file_path = ibdata1:10M:autoextend #innodb_log_group_home_dir = @localstatedir@/ #innodb_log_arch_dir = @localstatedir@/ -#set-variable = innodb_mirrored_log_groups=1 -#set-variable = innodb_log_files_in_group=3 -#set-variable = innodb_log_file_size=5M +# You can set .._buffer_pool_size up to 50 - 80 % +# of RAM but beware of setting memory usage too high +#set-variable = innodb_buffer_pool_size=256M +#set-variable = innodb_additional_mem_pool_size=20M +# Set .._log_file_size to 25 % of buffer pool size +#set-variable = innodb_log_file_size=64M #set-variable = innodb_log_buffer_size=8M #innodb_flush_log_at_trx_commit=1 -#innodb_log_archive=0 -#set-variable = innodb_buffer_pool_size=16M -#set-variable = innodb_additional_mem_pool_size=2M -#set-variable = innodb_file_io_threads=4 #set-variable = innodb_lock_wait_timeout=50 # Point the following paths to different dedicated disks diff --git a/support-files/my-medium.cnf.sh b/support-files/my-medium.cnf.sh index bddba03eee9..a92494358cb 100644 --- a/support-files/my-medium.cnf.sh +++ b/support-files/my-medium.cnf.sh @@ -44,20 +44,19 @@ server-id = 1 #set-variable = bdb_cache_size=4M #set-variable = bdb_max_lock=10000 -# Uncomment the following if you are using Innobase tables -#innodb_data_file_path = ibdata1:400M +# Uncomment the following if you are using InnoDB tables #innodb_data_home_dir = @localstatedir@/ +#innodb_data_file_path = ibdata1:10M:autoextend #innodb_log_group_home_dir = @localstatedir@/ #innodb_log_arch_dir = @localstatedir@/ -#set-variable = innodb_mirrored_log_groups=1 -#set-variable = innodb_log_files_in_group=3 +# You can set .._buffer_pool_size up to 50 - 80 % +# of RAM but beware of setting memory usage too high +#set-variable = innodb_buffer_pool_size=16M +#set-variable = innodb_additional_mem_pool_size=2M +# Set .._log_file_size to 25 % of buffer pool size #set-variable = innodb_log_file_size=5M #set-variable = innodb_log_buffer_size=8M #innodb_flush_log_at_trx_commit=1 -#innodb_log_archive=0 -#set-variable = innodb_buffer_pool_size=16M -#set-variable = innodb_additional_mem_pool_size=2M -#set-variable = innodb_file_io_threads=4 #set-variable = innodb_lock_wait_timeout=50 [mysqldump] diff --git a/support-files/my-small.cnf.sh b/support-files/my-small.cnf.sh index 9e7d07ec449..b8941184fe0 100644 --- a/support-files/my-small.cnf.sh +++ b/support-files/my-small.cnf.sh @@ -41,20 +41,19 @@ server-id = 1 # Uncomment the following if you are NOT using BDB tables #skip-bdb -# Uncomment the following if you are using Innobase tables -#innodb_data_file_path = ibdata1:100M +# Uncomment the following if you are using InnoDB tables #innodb_data_home_dir = @localstatedir@/ +#innodb_data_file_path = ibdata1:10M:autoextend #innodb_log_group_home_dir = @localstatedir@/ #innodb_log_arch_dir = @localstatedir@/ -#set-variable = innodb_mirrored_log_groups=1 -#set-variable = innodb_log_files_in_group=3 +# You can set .._buffer_pool_size up to 50 - 80 % +# of RAM but beware of setting memory usage too high +#set-variable = innodb_buffer_pool_size=16M +#set-variable = innodb_additional_mem_pool_size=2M +# Set .._log_file_size to 25 % of buffer pool size #set-variable = innodb_log_file_size=5M #set-variable = innodb_log_buffer_size=8M #innodb_flush_log_at_trx_commit=1 -#innodb_log_archive=0 -#set-variable = innodb_buffer_pool_size=16M -#set-variable = innodb_additional_mem_pool_size=2M -#set-variable = innodb_file_io_threads=4 #set-variable = innodb_lock_wait_timeout=50 [mysqldump] diff --git a/vio/vio.c b/vio/vio.c index 67cb7ec95cd..bb97f195110 100644 --- a/vio/vio.c +++ b/vio/vio.c @@ -83,6 +83,7 @@ void vio_reset(Vio* vio, enum enum_vio_type type, DBUG_VOID_RETURN; } + /* Open the socket or TCP/IP connection and read the fnctl() status */ Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost) @@ -102,12 +103,14 @@ Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost) #elif defined(HAVE_SYS_IOCTL_H) /* hpux */ /* Non blocking sockets doesn't work good on HPUX 11.0 */ (void) ioctl(sd,FIOSNBIO,0); + vio->fcntl_mode &= ~O_NONBLOCK; #endif #else /* !defined(__WIN__) && !defined(__EMX__) */ { /* set to blocking mode by default */ ulong arg=0, r; r = ioctlsocket(sd,FIONBIO,(void*) &arg, sizeof(arg)); + vio->fcntl_mode &= ~O_NONBLOCK; } #endif } diff --git a/vio/viosocket.c b/vio/viosocket.c index dc2bfaa6e0c..176af25b395 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -110,11 +110,15 @@ int vio_write(Vio * vio, const gptr buf, int size) } -int vio_blocking(Vio * vio __attribute__((unused)), my_bool set_blocking_mode) +int vio_blocking(Vio * vio __attribute__((unused)), my_bool set_blocking_mode, + my_bool *old_mode) { int r=0; DBUG_ENTER("vio_blocking"); - DBUG_PRINT("enter", ("set_blocking_mode: %d", (int) set_blocking_mode)); + + *old_mode= test(!(vio->fcntl_mode & O_NONBLOCK)); + DBUG_PRINT("enter", ("set_blocking_mode: %d old_mode: %d", + (int) set_blocking_mode, (int) *old_mode)); #if !defined(HAVE_OPENSSL) #if !defined(___WIN__) && !defined(__EMX__) diff --git a/vio/viossl.c b/vio/viossl.c index 6d85b119f20..7365bdc3daf 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -259,8 +259,10 @@ void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout) char *str; char buf[1024]; X509* client_cert; + my_bool unused; DBUG_ENTER("sslaccept"); DBUG_PRINT("enter", ("sd=%d ptr=%p", vio->sd,ptr)); + vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE); vio->ssl_=0; vio->open_=FALSE; @@ -272,7 +274,7 @@ void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout) } DBUG_PRINT("info", ("ssl_=%p timeout=%ld",vio->ssl_, timeout)); SSL_clear(vio->ssl_); - vio_blocking(vio, FALSE); + vio_blocking(vio, FALSE, &unused); SSL_SESSION_set_timeout(SSL_get_session(vio->ssl_), timeout); SSL_set_fd(vio->ssl_,vio->sd); SSL_set_accept_state(vio->ssl_); @@ -310,12 +312,15 @@ void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout) DBUG_VOID_RETURN; } + void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout) { char *str; X509* server_cert; + my_bool unused; DBUG_ENTER("sslconnect"); DBUG_PRINT("enter", ("sd=%d ptr=%p ctx: %p", vio->sd,ptr,ptr->ssl_context_)); + vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE); vio->ssl_=0; vio->open_=FALSE; @@ -327,7 +332,7 @@ void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout) } DBUG_PRINT("info", ("ssl_=%p timeout=%ld",vio->ssl_, timeout)); SSL_clear(vio->ssl_); - vio_blocking(vio, FALSE); + vio_blocking(vio, FALSE, &unused); SSL_SESSION_set_timeout(SSL_get_session(vio->ssl_), timeout); SSL_set_fd (vio->ssl_, vio->sd); SSL_set_connect_state(vio->ssl_); |