mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
merge
This commit is contained in:
@ -42,3 +42,4 @@ bell@sanja.is.com.ua
|
|||||||
kaj@work.mysql.com
|
kaj@work.mysql.com
|
||||||
mwagner@cash.mwagner.org
|
mwagner@cash.mwagner.org
|
||||||
tom@basil-firewall.home.com
|
tom@basil-firewall.home.com
|
||||||
|
jani@rhols221.adsl.netsonic.fi
|
||||||
|
@ -48290,13 +48290,13 @@ Fixed bug in multi table delete.
|
|||||||
Fixed bug in @code{SELECT CONCAT(argument-list) ... GROUP BY 1}.
|
Fixed bug in @code{SELECT CONCAT(argument-list) ... GROUP BY 1}.
|
||||||
@item
|
@item
|
||||||
@code{SELECT .. INSERT} did a full rollback in case of an error. Fixed
|
@code{SELECT .. INSERT} did a full rollback in case of an error. Fixed
|
||||||
so that we only rollback the last statement.
|
so that we only roll back the last statement.
|
||||||
@item
|
@item
|
||||||
Fixed bug with empty expression for boolean fulltext search.
|
Fixed bug with empty expression for boolean fulltext search.
|
||||||
@item
|
@item
|
||||||
Fixed core dump bug in updating fulltext key from/to @code{NULL}.
|
Fixed core dump bug in updating fulltext key from/to @code{NULL}.
|
||||||
@item
|
@item
|
||||||
ODBC compatibility: Added @code{BIT_LENGTH()}
|
ODBC compatibility: Added @code{BIT_LENGTH()}.
|
||||||
@item
|
@item
|
||||||
Fixed core dump bug in @code{GROUP BY BINARY column}.
|
Fixed core dump bug in @code{GROUP BY BINARY column}.
|
||||||
@item
|
@item
|
||||||
@ -48315,7 +48315,7 @@ For more information, read @ref{Cast Functions}.
|
|||||||
@code{CREATE ... SELECT} on @code{DATE} and @code{TIME} functions now
|
@code{CREATE ... SELECT} on @code{DATE} and @code{TIME} functions now
|
||||||
create columns of the expected type.
|
create columns of the expected type.
|
||||||
@item
|
@item
|
||||||
Changed order of how keys are created in tables.
|
Changed order in which keys are created in tables.
|
||||||
@item
|
@item
|
||||||
Added a new columns @code{Null} and @code{Index_type} to @code{SHOW INDEX}.
|
Added a new columns @code{Null} and @code{Index_type} to @code{SHOW INDEX}.
|
||||||
@end itemize
|
@end itemize
|
||||||
@ -48330,17 +48330,17 @@ Fixed bug when @code{HANDLER} was used with some unsupported table type.
|
|||||||
@code{mysqldump} now puts @code{ALTER TABLE table_name DISABLE KEYS} and
|
@code{mysqldump} now puts @code{ALTER TABLE table_name DISABLE KEYS} and
|
||||||
@code{ALTER TABLE table_name DISABLE KEYS} in the sql dump.
|
@code{ALTER TABLE table_name DISABLE KEYS} in the sql dump.
|
||||||
@item
|
@item
|
||||||
Added @code{mysql_fix_extensions} script
|
Added @code{mysql_fix_extensions} script.
|
||||||
@item
|
@item
|
||||||
Fixed stack overrun problem @code{LOAD DATA FROM MASTER} on OSF1.
|
Fixed stack overrun problem @code{LOAD DATA FROM MASTER} on OSF1.
|
||||||
@item
|
@item
|
||||||
Fixed shutdown problem on HPUX.
|
Fixed shutdown problem on HP-UX.
|
||||||
@item
|
@item
|
||||||
Added functions @code{des_encrypt()} and @code{des_decrypt()}.
|
Added functions @code{des_encrypt()} and @code{des_decrypt()}.
|
||||||
@item
|
@item
|
||||||
Added statement @code{FLUSH DES_KEY_FILE}.
|
Added statement @code{FLUSH DES_KEY_FILE}.
|
||||||
@item
|
@item
|
||||||
Added mysqld option @code{--des-key-file}.
|
Added @code{mysqld} option @code{--des-key-file}.
|
||||||
@item
|
@item
|
||||||
@code{HEX(string)} now returns the characters in string converted to
|
@code{HEX(string)} now returns the characters in string converted to
|
||||||
hexadecimal.
|
hexadecimal.
|
||||||
@ -48352,7 +48352,7 @@ Changed @code{SELECT ... IN SHARE MODE} to
|
|||||||
@item
|
@item
|
||||||
A new query cache to cache results from identical @code{SELECT} queries.
|
A new query cache to cache results from identical @code{SELECT} queries.
|
||||||
@item
|
@item
|
||||||
Fixed core dump bug on 64 bit machines when it got a wrong communication
|
Fixed core dump bug on 64-bit machines when it got an incorrect communication
|
||||||
packet.
|
packet.
|
||||||
@item
|
@item
|
||||||
@code{MATCH ... AGAINST(... IN BOOLEAN MODE)} can now work
|
@code{MATCH ... AGAINST(... IN BOOLEAN MODE)} can now work
|
||||||
@ -48370,7 +48370,7 @@ of @code{FULLTEXT} indexes.
|
|||||||
Fixed bug in @code{DELETE ... WHERE ... MATCH ...}.
|
Fixed bug in @code{DELETE ... WHERE ... MATCH ...}.
|
||||||
@item
|
@item
|
||||||
Added support for @code{MATCH ... AGAINST(... IN BOOLEAN MODE)}.
|
Added support for @code{MATCH ... AGAINST(... IN BOOLEAN MODE)}.
|
||||||
@strong{Note: you have to rebuild your tables with
|
@strong{Note: you must rebuild your tables with
|
||||||
@code{ALTER TABLE tablename TYPE=MyISAM} to be
|
@code{ALTER TABLE tablename TYPE=MyISAM} to be
|
||||||
able to use boolean fulltext search}.
|
able to use boolean fulltext search}.
|
||||||
@item
|
@item
|
||||||
@ -48391,7 +48391,7 @@ Added boolean fulltext search code. It should be considered early alpha.
|
|||||||
Extended @code{MODIFY} and @code{CHANGE} in @code{ALTER TABLE} to accept
|
Extended @code{MODIFY} and @code{CHANGE} in @code{ALTER TABLE} to accept
|
||||||
the @code{AFTER} keyword.
|
the @code{AFTER} keyword.
|
||||||
@item
|
@item
|
||||||
Index are now used with @code{ORDER BY} on a whole @code{InnoDB} table.
|
Indexes are now used with @code{ORDER BY} on a whole @code{InnoDB} table.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@node News-4.0.0, , News-4.0.1, News-4.0.x
|
@node News-4.0.0, , News-4.0.1, News-4.0.x
|
||||||
@ -48446,28 +48446,28 @@ Speed up all internal list handling.
|
|||||||
@item
|
@item
|
||||||
Speed up @code{IS NULL}, @code{ISNULL()} and some other internal primitives.
|
Speed up @code{IS NULL}, @code{ISNULL()} and some other internal primitives.
|
||||||
@item
|
@item
|
||||||
Creating full text indexes are now much faster.
|
Full text index creation now is much faster.
|
||||||
@item
|
@item
|
||||||
Tree-like cache to speed up bulk inserts and
|
Tree-like cache to speed up bulk inserts and
|
||||||
@code{myisam_bulk_insert_tree_size} variable.
|
@code{myisam_bulk_insert_tree_size} variable.
|
||||||
@item
|
@item
|
||||||
Searching on packed (@code{CHAR}/@code{VARCHAR}) keys are now much faster.
|
Searching on packed (@code{CHAR}/@code{VARCHAR}) keys is now much faster.
|
||||||
@item
|
@item
|
||||||
Optimised queries of type:
|
Optimised queries of type:
|
||||||
@code{SELECT DISTINCT * from table_name ORDER by key_part1 LIMIT #}
|
@code{SELECT DISTINCT * from table_name ORDER by key_part1 LIMIT #}.
|
||||||
@item
|
@item
|
||||||
@code{SHOW CREATE TABLE} now shows all table attributes.
|
@code{SHOW CREATE TABLE} now shows all table attributes.
|
||||||
@item
|
@item
|
||||||
@code{ORDER BY ... DESC} can now use keys.
|
@code{ORDER BY ... DESC} can now use keys.
|
||||||
@item
|
@item
|
||||||
@code{LOAD DATA FROM MASTER} "auto-magically" sets up a slave.
|
@code{LOAD DATA FROM MASTER} ``auto-magically'' sets up a slave.
|
||||||
@item
|
@item
|
||||||
Renamed @code{safe_mysqld} to @code{mysqld_safe}.
|
Renamed @code{safe_mysqld} to @code{mysqld_safe}.
|
||||||
@item
|
@item
|
||||||
Added support for symbolic links to @code{MyISAM} tables. Symlink handling is
|
Added support for symbolic links to @code{MyISAM} tables. Symlink handling is
|
||||||
now enabled by default for Windows.
|
now enabled by default for Windows.
|
||||||
@item
|
@item
|
||||||
@code{LOAD DATA FROM MASTER} "auto-magically" sets up a slave.
|
@code{LOAD DATA FROM MASTER} ``auto-magically'' sets up a slave.
|
||||||
@item
|
@item
|
||||||
Added @code{SQL_CALC_FOUND_ROWS} and @code{FOUND_ROWS()}. This makes it
|
Added @code{SQL_CALC_FOUND_ROWS} and @code{FOUND_ROWS()}. This makes it
|
||||||
possible to know how many rows a query would have returned
|
possible to know how many rows a query would have returned
|
||||||
@ -48486,15 +48486,15 @@ Added @code{ORDER BY} syntax to @code{UPDATE} and @code{DELETE}.
|
|||||||
Added @code{ALTER TABLE table_name DISABLE KEYS} and
|
Added @code{ALTER TABLE table_name DISABLE KEYS} and
|
||||||
@code{ALTER TABLE table_name ENABLE KEYS} commands.
|
@code{ALTER TABLE table_name ENABLE KEYS} commands.
|
||||||
@item
|
@item
|
||||||
Allow one to use @code{IN} instead of @code{FROM} in @code{SHOW} commands.
|
Allow use of @code{IN} as a synonym for @code{FROM} in @code{SHOW} commands.
|
||||||
@item
|
@item
|
||||||
Implemented ``repair by sort'' for @code{FULLTEXT} indexes.
|
Implemented ``repair by sort'' for @code{FULLTEXT} indexes.
|
||||||
@code{REPAIR TABLE}, @code{ALTER TABLE}, and @code{OPTIMIZE TABLE}
|
@code{REPAIR TABLE}, @code{ALTER TABLE}, and @code{OPTIMIZE TABLE}
|
||||||
for tables with @code{FULLTEXT} indexes are now up to 100 times faster.
|
for tables with @code{FULLTEXT} indexes are now up to 100 times faster.
|
||||||
@item
|
@item
|
||||||
Allow ANSI SQL syntax @code{X'hexadecimal-number'}
|
Allow ANSI SQL syntax @code{X'hexadecimal-number'}.
|
||||||
@item
|
@item
|
||||||
Cleaned up global lock handling for @code{FLUSH TABLES WITH READ LOCK}
|
Cleaned up global lock handling for @code{FLUSH TABLES WITH READ LOCK}.
|
||||||
@item
|
@item
|
||||||
Fixed problem with @code{DATETIME = constant} in @code{WHERE} optimisation.
|
Fixed problem with @code{DATETIME = constant} in @code{WHERE} optimisation.
|
||||||
@item
|
@item
|
||||||
@ -48610,13 +48610,13 @@ Restrict InnoDB keys to 500 bytes.
|
|||||||
@item
|
@item
|
||||||
InnoDB now supports @code{NULL} in keys.
|
InnoDB now supports @code{NULL} in keys.
|
||||||
@item
|
@item
|
||||||
Fixed shutdown problem on HPUX. (Introduced in 3.23.46)
|
Fixed shutdown problem on HP-UX. (Introduced in 3.23.46)
|
||||||
@item
|
@item
|
||||||
Fixed core-dump bug in replication when using SELECT RELEASE_LOCK();
|
Fixed core-dump bug in replication when using @code{SELECT RELEASE_LOCK()}.
|
||||||
@item
|
@item
|
||||||
Added new command: @code{DO expression,[expression]}
|
Added new command: @code{DO expression,[expression]}
|
||||||
@item
|
@item
|
||||||
Added @code{slave-skip-errors} option
|
Added @code{slave-skip-errors} option.
|
||||||
@item
|
@item
|
||||||
Added statistics variables for all MySQL commands. (@code{SHOW STATUS} is
|
Added statistics variables for all MySQL commands. (@code{SHOW STATUS} is
|
||||||
now much longer).
|
now much longer).
|
||||||
@ -48627,7 +48627,7 @@ Fixed that @code{GROUP BY expr DESC} works.
|
|||||||
@item
|
@item
|
||||||
Fixed bug when using @code{t1 LEFT JOIN t2 ON t2.key=constant}.
|
Fixed bug when using @code{t1 LEFT JOIN t2 ON t2.key=constant}.
|
||||||
@item
|
@item
|
||||||
@code{mysql_config} now also work with binary (relocated) distributions.
|
@code{mysql_config} now also works with binary (relocated) distributions.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@node News-3.23.46, News-3.23.45, News-3.23.47, News-3.23.x
|
@node News-3.23.46, News-3.23.45, News-3.23.47, News-3.23.x
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
/* mysqltest test tool
|
/* mysqltest test tool
|
||||||
* See man page for more information.
|
* See the manual for more information
|
||||||
|
* TODO: document better how mysqltest works
|
||||||
*
|
*
|
||||||
* Written by:
|
* Written by:
|
||||||
* Sasha Pachev <sasha@mysql.com>
|
* Sasha Pachev <sasha@mysql.com>
|
||||||
@ -26,9 +27,6 @@
|
|||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
TODO:
|
TODO:
|
||||||
|
|
||||||
- Print also the queries that returns a result to the log file; This makes
|
|
||||||
it much easier to find out what's wrong.
|
|
||||||
|
|
||||||
- Do comparison line by line, instead of doing a full comparison of
|
- Do comparison line by line, instead of doing a full comparison of
|
||||||
the text file. This will save space as we don't need to keep many
|
the text file. This will save space as we don't need to keep many
|
||||||
results in memory. It will also make it possible to do simple
|
results in memory. It will also make it possible to do simple
|
||||||
@ -43,7 +41,7 @@
|
|||||||
|
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
#define MTEST_VERSION "1.13"
|
#define MTEST_VERSION "1.14"
|
||||||
|
|
||||||
#include <my_global.h>
|
#include <my_global.h>
|
||||||
#include <mysql_embed.h>
|
#include <mysql_embed.h>
|
||||||
@ -88,6 +86,12 @@
|
|||||||
#define CON_RETRY_SLEEP 2
|
#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 */
|
||||||
|
#else
|
||||||
|
#defile SLAVE_POLL_INTERVAL 0.3
|
||||||
|
#endif
|
||||||
|
|
||||||
enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
|
enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
|
||||||
OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT};
|
OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT};
|
||||||
|
|
||||||
@ -187,6 +191,7 @@ Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT,
|
|||||||
Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
|
Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
|
||||||
Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG,
|
Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG,
|
||||||
Q_SERVER_START, Q_SERVER_STOP,Q_REQUIRE_MANAGER,
|
Q_SERVER_START, Q_SERVER_STOP,Q_REQUIRE_MANAGER,
|
||||||
|
Q_WAIT_FOR_SLAVE_TO_STOP,
|
||||||
Q_UNKNOWN, /* Unknown command. */
|
Q_UNKNOWN, /* Unknown command. */
|
||||||
Q_COMMENT, /* Comments, ignored. */
|
Q_COMMENT, /* Comments, ignored. */
|
||||||
Q_COMMENT_WITH_COMMAND
|
Q_COMMENT_WITH_COMMAND
|
||||||
@ -222,7 +227,7 @@ const char *command_names[] = {
|
|||||||
"enable_query_log", "disable_query_log",
|
"enable_query_log", "disable_query_log",
|
||||||
"enable_result_log", "disable_result_log",
|
"enable_result_log", "disable_result_log",
|
||||||
"server_start", "server_stop",
|
"server_start", "server_stop",
|
||||||
"require_manager",
|
"require_manager", "wait_for_slave_to_stop",
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -653,6 +658,45 @@ int open_file(const char* name)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ugly long name, but we are following the convention */
|
||||||
|
int do_wait_for_slave_to_stop(struct st_query* __attribute__((unused)) q)
|
||||||
|
{
|
||||||
|
MYSQL* mysql = &cur_con->mysql;
|
||||||
|
#ifndef OS2
|
||||||
|
struct timeval t;
|
||||||
|
#endif
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
MYSQL_RES* res;
|
||||||
|
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",
|
||||||
|
mysql_error(mysql));
|
||||||
|
if (!(row=mysql_fetch_row(res)) || !row[1])
|
||||||
|
{
|
||||||
|
mysql_free_result(res);
|
||||||
|
die("Strange result from query while probing slave for stop");
|
||||||
|
}
|
||||||
|
done = !strcmp(row[1],"OFF");
|
||||||
|
mysql_free_result(res);
|
||||||
|
if (done)
|
||||||
|
break;
|
||||||
|
#ifndef OS2
|
||||||
|
t.tv_sec=0;
|
||||||
|
t.tv_usec=SLAVE_POLL_INTERVAL;
|
||||||
|
select(0,0,0,0,&t); /* sleep */
|
||||||
|
#else
|
||||||
|
DosSleep(OS2_SLAVE_POLL_INTERVAL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int do_require_manager(struct st_query* __attribute__((unused)) q)
|
int do_require_manager(struct st_query* __attribute__((unused)) q)
|
||||||
{
|
{
|
||||||
if (!manager)
|
if (!manager)
|
||||||
@ -2335,6 +2379,7 @@ int main(int argc, char** argv)
|
|||||||
case Q_DISABLE_RESULT_LOG: disable_result_log=1; break;
|
case Q_DISABLE_RESULT_LOG: disable_result_log=1; break;
|
||||||
case Q_SOURCE: do_source(q); break;
|
case Q_SOURCE: do_source(q); break;
|
||||||
case Q_SLEEP: do_sleep(q); break;
|
case Q_SLEEP: do_sleep(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;
|
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_START: do_server_start(q); break;
|
||||||
|
@ -28,7 +28,7 @@ noinst_HEADERS = config-win.h \
|
|||||||
my_dir.h mysys_err.h my_base.h \
|
my_dir.h mysys_err.h my_base.h \
|
||||||
my_nosys.h my_alarm.h queues.h \
|
my_nosys.h my_alarm.h queues.h \
|
||||||
my_tree.h hash.h thr_alarm.h thr_lock.h \
|
my_tree.h hash.h thr_alarm.h thr_lock.h \
|
||||||
getopt.h t_ctype.h violite.h md5.h \
|
getopt.h my_getopt.h t_ctype.h violite.h md5.h \
|
||||||
mysql_version.h.in
|
mysql_version.h.in
|
||||||
|
|
||||||
# mysql_version.h are generated
|
# mysql_version.h are generated
|
||||||
|
46
include/my_getopt.h
Normal file
46
include/my_getopt.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/* Copyright (C) 2000 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 */
|
||||||
|
|
||||||
|
struct my_optarg
|
||||||
|
{
|
||||||
|
char *arg; /* option argument */
|
||||||
|
int pos; /* next element in ARGV */
|
||||||
|
int verbose; /* 0 = inhibit warnings of unrecognized options */
|
||||||
|
int unrecognized; /* position of the unrecognized option */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum get_opt_var_type { GET_NO_ARG, GET_INT, GET_LL, GET_STR };
|
||||||
|
enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG };
|
||||||
|
|
||||||
|
struct my_option
|
||||||
|
{
|
||||||
|
const char *name; /* Name of the option */
|
||||||
|
const char *comment; /* option comment, for autom. --help */
|
||||||
|
char *value; /* The variable value */
|
||||||
|
const char **str_values; /* Pointer to possible values */
|
||||||
|
enum get_opt_var_type var_type;
|
||||||
|
enum get_opt_arg_type arg_type;
|
||||||
|
int id; /* unique id or short option */
|
||||||
|
long long def_value; /* Default value */
|
||||||
|
long long min_value; /* Min allowed value */
|
||||||
|
long long max_value; /* Max allowed value */
|
||||||
|
long long sub_size; /* Subtract this from given value */
|
||||||
|
long block_size; /* Value should be a mult. of this */
|
||||||
|
int app_type; /* To be used by an application */
|
||||||
|
my_bool changeable_var; /* If true, the option is a variable */
|
||||||
|
};
|
||||||
|
|
@ -643,7 +643,10 @@ extern int _my_b_write(IO_CACHE *info,const byte *Buffer,uint Count);
|
|||||||
extern int my_b_append(IO_CACHE *info,const byte *Buffer,uint Count);
|
extern int my_b_append(IO_CACHE *info,const byte *Buffer,uint Count);
|
||||||
extern int my_block_write(IO_CACHE *info, const byte *Buffer,
|
extern int my_block_write(IO_CACHE *info, const byte *Buffer,
|
||||||
uint Count, my_off_t pos);
|
uint Count, my_off_t pos);
|
||||||
extern int flush_io_cache(IO_CACHE *info);
|
extern int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock);
|
||||||
|
|
||||||
|
#define flush_io_cache(info) _flush_io_cache((info),1)
|
||||||
|
|
||||||
extern int end_io_cache(IO_CACHE *info);
|
extern int end_io_cache(IO_CACHE *info);
|
||||||
extern uint my_b_fill(IO_CACHE *info);
|
extern uint my_b_fill(IO_CACHE *info);
|
||||||
extern void my_b_seek(IO_CACHE *info,my_off_t pos);
|
extern void my_b_seek(IO_CACHE *info,my_off_t pos);
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <getopt.h>
|
#include <my_getopt.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#ifdef HAVE_SYS_VADVICE_H
|
#ifdef HAVE_SYS_VADVICE_H
|
||||||
#include <sys/vadvise.h>
|
#include <sys/vadvise.h>
|
||||||
@ -169,58 +169,75 @@ static CHANGEABLE_VAR changeable_vars[] = {
|
|||||||
|
|
||||||
enum options {
|
enum options {
|
||||||
OPT_CHARSETS_DIR=256, OPT_SET_CHARSET,OPT_START_CHECK_POS,
|
OPT_CHARSETS_DIR=256, OPT_SET_CHARSET,OPT_START_CHECK_POS,
|
||||||
OPT_CORRECT_CHECKSUM
|
OPT_CORRECT_CHECKSUM, OPT_KEY_BUFFER_SIZE, OPT_MYISAM_BLOCK_SIZE,
|
||||||
|
OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE,
|
||||||
|
OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN,
|
||||||
|
OPT_FT_MAX_WORD_LEN, OPT_FT_MAX_WORD_LEN_FOR_SORT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct my_option my_long_options[] =
|
||||||
static struct option long_options[] =
|
|
||||||
{
|
{
|
||||||
{"analyze", no_argument, 0, 'a'},
|
{"analyze", "", 0, 0, GET_NO_ARG, NO_ARG, 'a', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"block-search", required_argument,0, 'b'},
|
{"block-search", "", 0, 0, GET_LL, REQUIRED_ARG, 'b', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"backup", no_argument, 0, 'B'},
|
{"backup", "", 0, 0, GET_NO_ARG, NO_ARG, 'B', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR},
|
{"character-sets-dir", "", 0, 0, GET_STR, REQUIRED_ARG, OPT_CHARSETS_DIR, 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"check", no_argument, 0, 'c'},
|
|
||||||
{"check-only-changed",no_argument, 0, 'C'},
|
{"check", "", 0, 0, GET_NO_ARG, NO_ARG, 'c', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"correct-checksum", no_argument, 0, OPT_CORRECT_CHECKSUM},
|
{"check-only-changed", "", 0, 0, GET_NO_ARG, NO_ARG, 'C', 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
|
||||||
|
{"correct-checksum", "", 0, 0, GET_NO_ARG, NO_ARG, OPT_CORRECT_CHECKSUM, 0, 0, 0, 0, 0, 0, 0},
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
{"debug", optional_argument, 0, '#'},
|
{"debug", "", 0, 0, GET_STR, OPT_ARG, '#', 0, 0, 0, 0, 0, 0, 0},
|
||||||
#endif
|
#endif
|
||||||
{"description", no_argument, 0, 'd'},
|
{"description", "", 0, 0, GET_NO_ARG, NO_ARG, 'd', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"data-file-length", required_argument, 0, 'D'},
|
{"data-file-length", "", 0, 0, GET_LL, REQUIRED_ARG, 'D', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"extend-check", no_argument, 0, 'e'},
|
{"extend-check", "", 0, 0, GET_NO_ARG, NO_ARG, 'e', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"fast", no_argument, 0, 'F'},
|
{"fast", "", 0, 0, GET_NO_ARG, NO_ARG, 'F', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"force", no_argument, 0, 'f'},
|
{"force", "", 0, 0, GET_NO_ARG, NO_ARG, 'f', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"help", no_argument, 0, '?'},
|
{"help", "", 0, 0, GET_NO_ARG, NO_ARG, '?', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"information", no_argument, 0, 'i'},
|
{"information", "", 0, 0, GET_NO_ARG, NO_ARG, 'i', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"keys-used", required_argument, 0, 'k'},
|
{"keys-used", "", 0, 0, GET_LL, REQUIRED_ARG, 'k', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"medium-check", no_argument, 0, 'm'},
|
{"medium-check", "", 0, 0, GET_NO_ARG, NO_ARG, 'm', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"quick", no_argument, 0, 'q'},
|
{"quick", "", 0, 0, GET_NO_ARG, NO_ARG, 'q', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"read-only", no_argument, 0, 'T'},
|
{"read-only", "", 0, 0, GET_NO_ARG, NO_ARG, 'T', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"recover", no_argument, 0, 'r'},
|
{"recover", "", 0, 0, GET_NO_ARG, NO_ARG, 'r', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"safe-recover", no_argument, 0, 'o'},
|
{"safe-recover", "", 0, 0, GET_NO_ARG, NO_ARG, 'o', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"start-check-pos", required_argument, 0, OPT_START_CHECK_POS},
|
{"start-check-pos", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_START_CHECK_POS, 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"set-auto-increment",optional_argument, 0, 'A'},
|
{"set-auto-increment", "", 0, 0, GET_LL, OPT_ARG, 'A', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"set-character-set",required_argument,0,OPT_SET_CHARSET},
|
{"set-character-set", "", 0, 0, GET_STR, REQUIRED_ARG, OPT_SET_CHARSET, 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"set-variable", required_argument, 0, 'O'},
|
{"set-variable", "", 0, 0, GET_STR, REQUIRED_ARG, 'O', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"silent", no_argument, 0, 's'},
|
{"silent", "", 0, 0, GET_NO_ARG, NO_ARG, 's', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"sort-index", no_argument, 0, 'S'},
|
{"sort-index", "", 0, 0, GET_NO_ARG, NO_ARG, 'S', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"sort-records", required_argument, 0, 'R'},
|
{"sort-records", "", 0, 0, GET_INT, REQUIRED_ARG, 'R', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"sort-recover", no_argument, 0, 'n'},
|
{"sort-recover", "", 0, 0, GET_NO_ARG, NO_ARG, 'n', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"tmpdir", required_argument, 0, 't'},
|
{"tmpdir", "", 0, 0, GET_STR, REQUIRED_ARG, 't', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"update-state", no_argument, 0, 'U'},
|
{"update-state", "", 0, 0, GET_NO_ARG, NO_ARG, 'U', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"unpack", no_argument, 0, 'u'},
|
{"unpack", "", 0, 0, GET_NO_ARG, NO_ARG, 'u', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"verbose", no_argument, 0, 'v'},
|
{"verbose", "", 0, 0, GET_NO_ARG, NO_ARG, 'v', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"version", no_argument, 0, 'V'},
|
{"version", "", 0, 0, GET_NO_ARG, NO_ARG, 'V', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{"wait", no_argument, 0, 'w'},
|
{"wait", "", 0, 0, GET_NO_ARG, NO_ARG, 'w', 0, 0, 0, 0, 0, 0, 0},
|
||||||
{0, 0, 0, 0}
|
/* variables begin here */
|
||||||
|
{ "key_buffer_size", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_KEY_BUFFER_SIZE, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
{ "myisam_block_size", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_MYISAM_BLOCK_SIZE, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
{ "read_buffer_size", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_READ_BUFFER_SIZE, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
{ "write_buffer_size", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_WRITE_BUFFER_SIZE, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
{ "sort_buffer_size", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_SORT_BUFFER_SIZE, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
{ "sort_key_blocks", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_SORT_KEY_BLOCKS, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
{ "decode_bits", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_DECODE_BITS, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
{ "ft_min_word_len", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_FT_MIN_WORD_LEN, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
{ "ft_max_word_len", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_FT_MAX_WORD_LEN, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
{ "ft_max_word_len_for_sort", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_FT_MAX_WORD_LEN_FOR_SORT, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void print_version(void)
|
static void print_version(void)
|
||||||
{
|
{
|
||||||
printf("%s Ver 2.0 for %s at %s\n",my_progname,SYSTEM_TYPE,
|
printf("%s Ver 2.1 for %s at %s\n", my_progname, SYSTEM_TYPE,
|
||||||
MACHINE_TYPE);
|
MACHINE_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
@ -315,163 +332,182 @@ static void usage(void)
|
|||||||
|
|
||||||
/* Read options */
|
/* Read options */
|
||||||
|
|
||||||
|
static my_bool get_one_option(int optid, const struct my_option *opt,
|
||||||
|
char *argument)
|
||||||
|
{
|
||||||
|
uint old_testflag;
|
||||||
|
char buff[255], *end;
|
||||||
|
|
||||||
|
switch(optid) {
|
||||||
|
case 'a':
|
||||||
|
check_param.testflag|= T_STATISTICS;
|
||||||
|
break;
|
||||||
|
case 'A':
|
||||||
|
if (argument)
|
||||||
|
check_param.auto_increment_value=strtoull(argument, NULL, 0);
|
||||||
|
else
|
||||||
|
check_param.auto_increment_value=0; /* Set to max used value */
|
||||||
|
check_param.testflag|= T_AUTO_INC;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
check_param.search_after_block=strtoul(argument, NULL, 10);
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
check_param.testflag|= T_BACKUP_DATA;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
check_param.testflag|= T_CHECK;
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
check_param.testflag|= T_CHECK | T_CHECK_ONLY_CHANGED;
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
check_param.max_data_file_length=strtoll(argument, NULL, 10);
|
||||||
|
break;
|
||||||
|
case 's': /* silent */
|
||||||
|
if (check_param.testflag & T_SILENT)
|
||||||
|
check_param.testflag|=T_VERY_SILENT;
|
||||||
|
check_param.testflag|= T_SILENT;
|
||||||
|
check_param.testflag&= ~T_WRITE_LOOP;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
check_param.testflag|= T_WAIT_FOREVER;
|
||||||
|
break;
|
||||||
|
case 'd': /* description if isam-file */
|
||||||
|
check_param.testflag|= T_DESCRIPT;
|
||||||
|
break;
|
||||||
|
case 'e': /* extend check */
|
||||||
|
check_param.testflag|= T_EXTEND;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
check_param.testflag|= T_INFO;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
check_param.tmpfile_createflag= O_RDWR | O_TRUNC;
|
||||||
|
check_param.testflag|= T_FORCE_CREATE | T_UPDATE_STATE;
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
check_param.testflag|=T_FAST;
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
check_param.keys_in_use= (ulonglong) strtoll(argument, NULL, 10);
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
check_param.testflag|= T_MEDIUM; /* Medium check */
|
||||||
|
break;
|
||||||
|
case 'r': /* Repair table */
|
||||||
|
check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
check_param.testflag= (check_param.testflag & ~T_REP_BY_SORT) | T_REP;
|
||||||
|
check_param.force_sort=0;
|
||||||
|
my_disable_async_io=1; /* More safety */
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
|
||||||
|
check_param.force_sort=1;
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
check_param.opt_rep_quick++;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
check_param.testflag|= T_UNPACK | T_REP_BY_SORT;
|
||||||
|
break;
|
||||||
|
case 'v': /* Verbose */
|
||||||
|
check_param.testflag|= T_VERBOSE;
|
||||||
|
check_param.verbose++;
|
||||||
|
break;
|
||||||
|
case 'O':
|
||||||
|
/* this is a temporary fix for variables to work until my_getopt */
|
||||||
|
/* can my_set_changeable_vars */
|
||||||
|
case OPT_KEY_BUFFER_SIZE:
|
||||||
|
case OPT_MYISAM_BLOCK_SIZE:
|
||||||
|
case OPT_READ_BUFFER_SIZE:
|
||||||
|
case OPT_WRITE_BUFFER_SIZE:
|
||||||
|
case OPT_SORT_BUFFER_SIZE:
|
||||||
|
case OPT_SORT_KEY_BLOCKS:
|
||||||
|
case OPT_DECODE_BITS:
|
||||||
|
case OPT_FT_MIN_WORD_LEN:
|
||||||
|
case OPT_FT_MAX_WORD_LEN:
|
||||||
|
case OPT_FT_MAX_WORD_LEN_FOR_SORT:
|
||||||
|
end= buff;
|
||||||
|
end= strmov(strmov(strmov(end, opt->name), "="), argument);
|
||||||
|
if (set_changeable_var(buff, changeable_vars))
|
||||||
|
{
|
||||||
|
usage();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'R': /* Sort records */
|
||||||
|
old_testflag=check_param.testflag;
|
||||||
|
check_param.testflag|= T_SORT_RECORDS;
|
||||||
|
check_param.opt_sort_key=(uint) atoi(argument) - 1;
|
||||||
|
if (check_param.opt_sort_key >= MI_MAX_KEY)
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"The value of the sort key is bigger than max key: %d.\n",
|
||||||
|
MI_MAX_KEY);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'S': /* Sort index */
|
||||||
|
old_testflag=check_param.testflag;
|
||||||
|
check_param.testflag|= T_SORT_INDEX;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
check_param.tmpdir=argument;
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
check_param.testflag|= T_READONLY;
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
check_param.testflag|= T_UPDATE_STATE;
|
||||||
|
break;
|
||||||
|
case '#':
|
||||||
|
DBUG_PUSH(argument ? argument : "d:t:o,/tmp/myisamchk.trace");
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
print_version();
|
||||||
|
exit(0);
|
||||||
|
case OPT_CORRECT_CHECKSUM:
|
||||||
|
check_param.testflag|=T_CALC_CHECKSUM;
|
||||||
|
break;
|
||||||
|
case OPT_CHARSETS_DIR:
|
||||||
|
charsets_dir= argument;
|
||||||
|
break;
|
||||||
|
case OPT_SET_CHARSET:
|
||||||
|
set_charset_name= argument;
|
||||||
|
break;
|
||||||
|
#ifdef DEBUG /* Only useful if debugging */
|
||||||
|
case OPT_START_CHECK_POS:
|
||||||
|
check_param.start_check_pos=strtoull(argument, NULL, 0);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case '?':
|
||||||
|
usage();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void get_options(register int *argc,register char ***argv)
|
static void get_options(register int *argc,register char ***argv)
|
||||||
{
|
{
|
||||||
int c,option_index=0;
|
int c,option_index=0;
|
||||||
uint old_testflag;
|
|
||||||
|
|
||||||
load_defaults("my",load_default_groups,argc,argv);
|
load_defaults("my",load_default_groups,argc,argv);
|
||||||
default_argv= *argv;
|
default_argv= *argv;
|
||||||
set_all_changeable_vars(changeable_vars);
|
set_all_changeable_vars(changeable_vars);
|
||||||
if (isatty(fileno(stdout)))
|
if (isatty(fileno(stdout)))
|
||||||
check_param.testflag|=T_WRITE_LOOP;
|
check_param.testflag|=T_WRITE_LOOP;
|
||||||
while ((c=getopt_long(*argc,*argv,
|
|
||||||
"aBcCdeifF?lqrmnosSTuUvVw#:b:D:k:O:R:A::t:",
|
if (handle_options(argc, argv, my_long_options, get_one_option))
|
||||||
long_options, &option_index)) != EOF)
|
exit(1);
|
||||||
{
|
|
||||||
switch(c) {
|
|
||||||
case 'a':
|
|
||||||
check_param.testflag|= T_STATISTICS;
|
|
||||||
break;
|
|
||||||
case 'A':
|
|
||||||
if (optarg)
|
|
||||||
check_param.auto_increment_value=strtoull(optarg,NULL,0);
|
|
||||||
else
|
|
||||||
check_param.auto_increment_value=0; /* Set to max used value */
|
|
||||||
check_param.testflag|= T_AUTO_INC;
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
check_param.search_after_block=strtoul(optarg,NULL,10);
|
|
||||||
break;
|
|
||||||
case 'B':
|
|
||||||
check_param.testflag|= T_BACKUP_DATA;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
check_param.testflag|= T_CHECK;
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
check_param.testflag|= T_CHECK | T_CHECK_ONLY_CHANGED;
|
|
||||||
break;
|
|
||||||
case 'D':
|
|
||||||
check_param.max_data_file_length=strtoll(optarg,NULL,10);
|
|
||||||
break;
|
|
||||||
case 's': /* silent */
|
|
||||||
if (check_param.testflag & T_SILENT)
|
|
||||||
check_param.testflag|=T_VERY_SILENT;
|
|
||||||
check_param.testflag|= T_SILENT;
|
|
||||||
check_param.testflag&= ~T_WRITE_LOOP;
|
|
||||||
break;
|
|
||||||
case 'w':
|
|
||||||
check_param.testflag|= T_WAIT_FOREVER;
|
|
||||||
break;
|
|
||||||
case 'd': /* description if isam-file */
|
|
||||||
check_param.testflag|= T_DESCRIPT;
|
|
||||||
break;
|
|
||||||
case 'e': /* extend check */
|
|
||||||
check_param.testflag|= T_EXTEND;
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
check_param.testflag|= T_INFO;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
check_param.tmpfile_createflag= O_RDWR | O_TRUNC;
|
|
||||||
check_param.testflag|= T_FORCE_CREATE | T_UPDATE_STATE;
|
|
||||||
break;
|
|
||||||
case 'F':
|
|
||||||
check_param.testflag|=T_FAST;
|
|
||||||
break;
|
|
||||||
case 'k':
|
|
||||||
check_param.keys_in_use= (ulonglong) strtoll(optarg,NULL,10);
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
check_param.testflag|= T_MEDIUM; /* Medium check */
|
|
||||||
break;
|
|
||||||
case 'r': /* Repair table */
|
|
||||||
check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
check_param.testflag= (check_param.testflag & ~T_REP_BY_SORT) | T_REP;
|
|
||||||
check_param.force_sort=0;
|
|
||||||
my_disable_async_io=1; /* More safety */
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
|
|
||||||
check_param.force_sort=1;
|
|
||||||
break;
|
|
||||||
case 'q':
|
|
||||||
check_param.opt_rep_quick++;
|
|
||||||
break;
|
|
||||||
case 'u':
|
|
||||||
check_param.testflag|= T_UNPACK | T_REP_BY_SORT;
|
|
||||||
break;
|
|
||||||
case 'v': /* Verbose */
|
|
||||||
check_param.testflag|= T_VERBOSE;
|
|
||||||
check_param.verbose++;
|
|
||||||
break;
|
|
||||||
case 'O':
|
|
||||||
if (set_changeable_var(optarg, changeable_vars))
|
|
||||||
{
|
|
||||||
usage();
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'R': /* Sort records */
|
|
||||||
old_testflag=check_param.testflag;
|
|
||||||
check_param.testflag|= T_SORT_RECORDS;
|
|
||||||
check_param.opt_sort_key=(uint) atoi(optarg)-1;
|
|
||||||
if (check_param.opt_sort_key >= MI_MAX_KEY)
|
|
||||||
{
|
|
||||||
fprintf(stderr,
|
|
||||||
"The value of the sort key is bigger than max key: %d.\n",
|
|
||||||
MI_MAX_KEY);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'S': /* Sort index */
|
|
||||||
old_testflag=check_param.testflag;
|
|
||||||
check_param.testflag|= T_SORT_INDEX;
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
check_param.tmpdir=optarg;
|
|
||||||
break;
|
|
||||||
case 'T':
|
|
||||||
check_param.testflag|= T_READONLY;
|
|
||||||
break;
|
|
||||||
case 'U':
|
|
||||||
check_param.testflag|= T_UPDATE_STATE;
|
|
||||||
break;
|
|
||||||
case '#':
|
|
||||||
DBUG_PUSH(optarg ? optarg : "d:t:o,/tmp/myisamchk.trace");
|
|
||||||
break;
|
|
||||||
case 'V':
|
|
||||||
print_version();
|
|
||||||
exit(0);
|
|
||||||
case OPT_CORRECT_CHECKSUM:
|
|
||||||
check_param.testflag|=T_CALC_CHECKSUM;
|
|
||||||
break;
|
|
||||||
case OPT_CHARSETS_DIR:
|
|
||||||
charsets_dir = optarg;
|
|
||||||
break;
|
|
||||||
case OPT_SET_CHARSET:
|
|
||||||
set_charset_name=optarg;
|
|
||||||
break;
|
|
||||||
#ifdef DEBUG /* Only useful if debugging */
|
|
||||||
case OPT_START_CHECK_POS:
|
|
||||||
check_param.start_check_pos=strtoull(optarg,NULL,0);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case '?':
|
|
||||||
usage();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* If using repair, then update checksum if one uses --update-state */
|
/* If using repair, then update checksum if one uses --update-state */
|
||||||
if ((check_param.testflag & T_UPDATE_STATE) &&
|
if ((check_param.testflag & T_UPDATE_STATE) &&
|
||||||
(check_param.testflag & (T_REP | T_REP_BY_SORT)))
|
(check_param.testflag & (T_REP | T_REP_BY_SORT)))
|
||||||
check_param.testflag|= T_CALC_CHECKSUM;
|
check_param.testflag|= T_CALC_CHECKSUM;
|
||||||
|
|
||||||
(*argc)-=optind;
|
|
||||||
(*argv)+=optind;
|
|
||||||
if (*argc == 0)
|
if (*argc == 0)
|
||||||
{
|
{
|
||||||
usage();
|
usage();
|
||||||
|
@ -33,7 +33,6 @@ master-bin.003
|
|||||||
insert into t2 values(1234);
|
insert into t2 values(1234);
|
||||||
set insert_id=1234;
|
set insert_id=1234;
|
||||||
insert into t2 values(NULL);
|
insert into t2 values(NULL);
|
||||||
slave stop;
|
|
||||||
set sql_slave_skip_counter=1;
|
set sql_slave_skip_counter=1;
|
||||||
slave start;
|
slave start;
|
||||||
purge master logs to 'master-bin.003';
|
purge master logs to 'master-bin.003';
|
||||||
@ -66,7 +65,7 @@ slave stop;
|
|||||||
slave start;
|
slave start;
|
||||||
show slave status;
|
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
|
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
|
||||||
127.0.0.1 root MASTER_PORT 60 master-bin.006 445 mysql-relay-bin.004 1312 master-bin.006 Yes Yes 0 0 445
|
127.0.0.1 root MASTER_PORT 60 master-bin.006 445 mysql-relay-bin.004 1376 master-bin.006 Yes Yes 0 0 445
|
||||||
lock tables t3 read;
|
lock tables t3 read;
|
||||||
select count(*) from t3 where n >= 4;
|
select count(*) from t3 where n >= 4;
|
||||||
count(*)
|
count(*)
|
||||||
|
@ -51,9 +51,7 @@ insert into t2 values(NULL);
|
|||||||
connection slave;
|
connection slave;
|
||||||
sync_with_master;
|
sync_with_master;
|
||||||
|
|
||||||
#the slave may have already stopped, so we ignore the error
|
wait_for_slave_to_stop;
|
||||||
--error 0,1199
|
|
||||||
!slave stop;
|
|
||||||
|
|
||||||
#restart slave skipping one event
|
#restart slave skipping one event
|
||||||
set sql_slave_skip_counter=1;
|
set sql_slave_skip_counter=1;
|
||||||
|
@ -44,7 +44,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
|
|||||||
my_delete.c my_rename.c my_redel.c my_tempnam.c \
|
my_delete.c my_rename.c my_redel.c my_tempnam.c \
|
||||||
my_chsize.c my_lread.c my_lwrite.c my_clock.c \
|
my_chsize.c my_lread.c my_lwrite.c my_clock.c \
|
||||||
my_quick.c my_lockmem.c my_static.c \
|
my_quick.c my_lockmem.c my_static.c \
|
||||||
getopt.c getopt1.c getvar.c my_mkdir.c \
|
getopt.c getopt1.c my_getopt.c getvar.c my_mkdir.c \
|
||||||
default.c my_compress.c checksum.c raid.cc my_net.c \
|
default.c my_compress.c checksum.c raid.cc my_net.c \
|
||||||
my_vsnprintf.c charset.c my_bitmap.c my_bit.c md5.c
|
my_vsnprintf.c charset.c my_bitmap.c my_bit.c md5.c
|
||||||
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
|
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#include "mysys_priv.h"
|
#include "mysys_priv.h"
|
||||||
#include <m_string.h>
|
#include <m_string.h>
|
||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
|
#include <my_getopt.h>
|
||||||
/* set all changeable variables */
|
/* set all changeable variables */
|
||||||
|
|
||||||
void set_all_changeable_vars(CHANGEABLE_VAR *vars)
|
void set_all_changeable_vars(CHANGEABLE_VAR *vars)
|
||||||
@ -109,3 +109,78 @@ my_bool set_changeable_var(my_string str,CHANGEABLE_VAR *vars)
|
|||||||
}
|
}
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my_bool my_set_changeable_var(my_string str, const struct my_option *vars)
|
||||||
|
{
|
||||||
|
char endchar;
|
||||||
|
my_string end;
|
||||||
|
DBUG_ENTER("my_set_changeable_var");
|
||||||
|
DBUG_PRINT("enter",("%s",str));
|
||||||
|
|
||||||
|
if (str)
|
||||||
|
{
|
||||||
|
if (!(end=strchr(str,'=')))
|
||||||
|
fprintf(stderr,"Can't find '=' in expression '%s' to option -O\n",str);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint length,found_count=0;
|
||||||
|
const struct my_option *var, *found;
|
||||||
|
my_string var_end;
|
||||||
|
const char *name;
|
||||||
|
longlong num;
|
||||||
|
|
||||||
|
/* Skip end space from variable */
|
||||||
|
for (var_end=end ; end > str && isspace(var_end[-1]) ; var_end--) ;
|
||||||
|
length=(uint) (var_end-str);
|
||||||
|
/* Skip start space from argument */
|
||||||
|
for (end++ ; isspace(*end) ; end++) ;
|
||||||
|
|
||||||
|
for (var= vars, found= 0; (name= var->name); var++)
|
||||||
|
{
|
||||||
|
if (var->changeable_var)
|
||||||
|
{
|
||||||
|
if (!my_casecmp(name, str, length))
|
||||||
|
{
|
||||||
|
found= var; found_count++;
|
||||||
|
if (!name[length])
|
||||||
|
{
|
||||||
|
found_count=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found_count == 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr,"No variable match for: -O '%s'\n",str);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
if (found_count > 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr,"Variable prefix '%*s' is not unique\n",length,str);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
num=strtoll(end, (char **)NULL, 10); endchar=strend(end)[-1];
|
||||||
|
if (endchar == 'k' || endchar == 'K')
|
||||||
|
num*=1024;
|
||||||
|
else if (endchar == 'm' || endchar == 'M')
|
||||||
|
num*=1024L*1024L;
|
||||||
|
else if (endchar == 'g' || endchar == 'G')
|
||||||
|
num*=1024L*1024L*1024L;
|
||||||
|
else if (!isdigit(endchar))
|
||||||
|
{
|
||||||
|
fprintf(stderr,"Unknown prefix used for variable value '%s'\n",str);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
if (num < (longlong) found->min_value)
|
||||||
|
num=(longlong) found->min_value;
|
||||||
|
else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) found->max_value)
|
||||||
|
num=(longlong) (ulong) found->max_value;
|
||||||
|
num=((num- (longlong) found->sub_size) / (ulonglong) found->block_size);
|
||||||
|
/* (*found->varptr)= (long) (num*(ulonglong) found->block_size);*/
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
@ -808,13 +808,19 @@ int my_b_append(register IO_CACHE *info, const byte *Buffer, uint Count)
|
|||||||
Buffer+=rest_length;
|
Buffer+=rest_length;
|
||||||
Count-=rest_length;
|
Count-=rest_length;
|
||||||
info->write_pos+=rest_length;
|
info->write_pos+=rest_length;
|
||||||
if (flush_io_cache(info))
|
if (_flush_io_cache(info,0))
|
||||||
|
{
|
||||||
|
unlock_append_buffer(info);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
if (Count >= IO_SIZE)
|
if (Count >= IO_SIZE)
|
||||||
{ /* Fill first intern buffer */
|
{ /* Fill first intern buffer */
|
||||||
length=Count & (uint) ~(IO_SIZE-1);
|
length=Count & (uint) ~(IO_SIZE-1);
|
||||||
if (my_write(info->file,Buffer,(uint) length,info->myflags | MY_NABP))
|
if (my_write(info->file,Buffer,(uint) length,info->myflags | MY_NABP))
|
||||||
|
{
|
||||||
|
unlock_append_buffer(info);
|
||||||
return info->error= -1;
|
return info->error= -1;
|
||||||
|
}
|
||||||
Count-=length;
|
Count-=length;
|
||||||
Buffer+=length;
|
Buffer+=length;
|
||||||
}
|
}
|
||||||
@ -883,14 +889,16 @@ int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count,
|
|||||||
|
|
||||||
/* Flush write cache */
|
/* Flush write cache */
|
||||||
|
|
||||||
int flush_io_cache(IO_CACHE *info)
|
int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
|
||||||
{
|
{
|
||||||
uint length;
|
uint length;
|
||||||
my_bool append_cache;
|
my_bool append_cache;
|
||||||
my_off_t pos_in_file;
|
my_off_t pos_in_file;
|
||||||
DBUG_ENTER("flush_io_cache");
|
DBUG_ENTER("flush_io_cache");
|
||||||
|
|
||||||
append_cache = (info->type == SEQ_READ_APPEND);
|
if (!(append_cache = (info->type == SEQ_READ_APPEND)))
|
||||||
|
need_append_buffer_lock=0;
|
||||||
|
|
||||||
if (info->type == WRITE_CACHE || append_cache)
|
if (info->type == WRITE_CACHE || append_cache)
|
||||||
{
|
{
|
||||||
if (info->file == -1)
|
if (info->file == -1)
|
||||||
@ -898,6 +906,8 @@ int flush_io_cache(IO_CACHE *info)
|
|||||||
if (real_open_cached_file(info))
|
if (real_open_cached_file(info))
|
||||||
DBUG_RETURN((info->error= -1));
|
DBUG_RETURN((info->error= -1));
|
||||||
}
|
}
|
||||||
|
if (need_append_buffer_lock)
|
||||||
|
lock_append_buffer(info);
|
||||||
if ((length=(uint) (info->write_pos - info->write_buffer)))
|
if ((length=(uint) (info->write_pos - info->write_buffer)))
|
||||||
{
|
{
|
||||||
pos_in_file=info->pos_in_file;
|
pos_in_file=info->pos_in_file;
|
||||||
@ -909,6 +919,8 @@ int flush_io_cache(IO_CACHE *info)
|
|||||||
if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) ==
|
if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) ==
|
||||||
MY_FILEPOS_ERROR)
|
MY_FILEPOS_ERROR)
|
||||||
{
|
{
|
||||||
|
if (need_append_buffer_lock)
|
||||||
|
unlock_append_buffer(info);
|
||||||
DBUG_RETURN((info->error= -1));
|
DBUG_RETURN((info->error= -1));
|
||||||
}
|
}
|
||||||
if (!append_cache)
|
if (!append_cache)
|
||||||
@ -932,6 +944,8 @@ int flush_io_cache(IO_CACHE *info)
|
|||||||
info->end_of_file+=(info->write_pos-info->append_read_pos);
|
info->end_of_file+=(info->write_pos-info->append_read_pos);
|
||||||
|
|
||||||
info->append_read_pos=info->write_pos=info->write_buffer;
|
info->append_read_pos=info->write_pos=info->write_buffer;
|
||||||
|
if (need_append_buffer_lock)
|
||||||
|
unlock_append_buffer(info);
|
||||||
DBUG_RETURN(info->error);
|
DBUG_RETURN(info->error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -942,6 +956,8 @@ int flush_io_cache(IO_CACHE *info)
|
|||||||
info->inited=0;
|
info->inited=0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (need_append_buffer_lock)
|
||||||
|
unlock_append_buffer(info);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
313
mysys/my_getopt.c
Normal file
313
mysys/my_getopt.c
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
/* Copyright (C) 2000 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 */
|
||||||
|
|
||||||
|
#include <my_config.h>
|
||||||
|
#include <my_global.h>
|
||||||
|
#include <m_string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <my_getopt.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
static int sortopt (int *argc, char ***argv);
|
||||||
|
static int findopt (char *optpat, uint length,
|
||||||
|
const struct my_option **opt_res,
|
||||||
|
char **ffname);
|
||||||
|
|
||||||
|
#define DISABLE_OPTION_COUNT 2
|
||||||
|
|
||||||
|
static char *special_opt_prefix[] = {"skip", "disable", "enable", 0};
|
||||||
|
|
||||||
|
|
||||||
|
/* function: handle_options
|
||||||
|
Sort options; put options first, until special end of options (--), or
|
||||||
|
until end of argv. Parse options; check that the given option matches with
|
||||||
|
one of the options in struct 'my_option', return error in case of ambiguous
|
||||||
|
or unknown option. Check that option was given an argument if it requires
|
||||||
|
one. Call function 'get_one_option()' once for each option.
|
||||||
|
*/
|
||||||
|
extern int handle_options (int *argc, char ***argv,
|
||||||
|
const struct my_option *longopts,
|
||||||
|
my_bool (*get_one_option)(int,
|
||||||
|
const struct my_option *,
|
||||||
|
char *))
|
||||||
|
{
|
||||||
|
uint opt_found, argvpos = 0, length, spec_len, i;
|
||||||
|
my_bool end_of_options = 0, must_be_var = 0;
|
||||||
|
char *progname = *(*argv), **pos, *optend, *prev_found;
|
||||||
|
const struct my_option *optp;
|
||||||
|
|
||||||
|
(*argc)--;
|
||||||
|
(*argv)++;
|
||||||
|
for (pos = *argv; *pos; pos++)
|
||||||
|
{
|
||||||
|
char *cur_arg= *pos;
|
||||||
|
if (*cur_arg == '-' && *(cur_arg + 1) && !end_of_options) // must be opt.
|
||||||
|
{
|
||||||
|
char *argument = 0;
|
||||||
|
must_be_var= 0;
|
||||||
|
|
||||||
|
// check for long option, or --set-variable (-O)
|
||||||
|
if (*(cur_arg + 1) == '-' || *(cur_arg + 1) == 'O')
|
||||||
|
{
|
||||||
|
if (*(cur_arg + 1) == 'O' || !strncmp(cur_arg, "--set-variable", 14))
|
||||||
|
{
|
||||||
|
must_be_var= 1;
|
||||||
|
|
||||||
|
if (*(cur_arg + 1) == 'O')
|
||||||
|
{
|
||||||
|
cur_arg+= 2;
|
||||||
|
if (!(*cur_arg))
|
||||||
|
{
|
||||||
|
// the argument must be in next argv
|
||||||
|
if (!(*(pos + 1)))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: Option '-O' requires an argument\n",
|
||||||
|
progname);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
cur_arg= *pos;
|
||||||
|
(*argc)--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Option argument begins with string '--set-variable'
|
||||||
|
{
|
||||||
|
cur_arg+= 14;
|
||||||
|
if (*cur_arg == '=')
|
||||||
|
{
|
||||||
|
cur_arg++;
|
||||||
|
if (!(*cur_arg))
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: Option '--set-variable' requires an argument\n",
|
||||||
|
progname);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*cur_arg) // garbage, or another option. break out
|
||||||
|
{
|
||||||
|
cur_arg-= 14;
|
||||||
|
must_be_var= 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// the argument must be in next argv
|
||||||
|
if (!(*(pos + 1)))
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: Option '--set-variable' requires an argument\n",
|
||||||
|
progname);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
cur_arg= *pos;
|
||||||
|
(*argc)--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!must_be_var)
|
||||||
|
{
|
||||||
|
if (!*(cur_arg + 2)) // '--' means end of options, look no further
|
||||||
|
{
|
||||||
|
end_of_options = 1;
|
||||||
|
(*argc)--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cur_arg+= 2; // skip the double dash
|
||||||
|
}
|
||||||
|
for (optend = cur_arg; *optend && *optend != '='; optend++) ;
|
||||||
|
length = optend - cur_arg;
|
||||||
|
/*
|
||||||
|
Find first the right option. Return error in case of an ambiguous,
|
||||||
|
or unknown option
|
||||||
|
*/
|
||||||
|
optp = longopts;
|
||||||
|
if (!(opt_found = findopt(cur_arg, length, &optp, &prev_found)))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Didn't find any matching option. Let's see if someone called
|
||||||
|
option with a special option prefix
|
||||||
|
*/
|
||||||
|
if (*optend != '=' && !must_be_var)
|
||||||
|
{
|
||||||
|
for (i = 0; special_opt_prefix[i]; i++)
|
||||||
|
{
|
||||||
|
spec_len = strlen(special_opt_prefix[i]);
|
||||||
|
if (!strncmp(special_opt_prefix[i], cur_arg, spec_len) &&
|
||||||
|
cur_arg[spec_len] == '-')
|
||||||
|
{
|
||||||
|
// We were called with a special prefix, we can reuse opt_found
|
||||||
|
cur_arg += (spec_len + 1);
|
||||||
|
if ((opt_found = findopt(cur_arg, length - (spec_len + 1),
|
||||||
|
&optp, &prev_found)))
|
||||||
|
{
|
||||||
|
if (opt_found > 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: ambiguous option '--%s-%s' (--%s-%s)\n",
|
||||||
|
progname, special_opt_prefix[i], cur_arg,
|
||||||
|
special_opt_prefix[i], prev_found);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if (i < DISABLE_OPTION_COUNT)
|
||||||
|
optend= "=0";
|
||||||
|
else // enable
|
||||||
|
optend= "=1";
|
||||||
|
break; // note break from the inner loop, main loop continues
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!opt_found)
|
||||||
|
{
|
||||||
|
if (must_be_var)
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: unknown variable '%s'\n", progname, cur_arg);
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: unknown option '--%s'\n", progname, cur_arg);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (opt_found > 1)
|
||||||
|
{
|
||||||
|
if (must_be_var)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: variable prefix '%s' is not unique\n",
|
||||||
|
progname, cur_arg);
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: ambiguous option '--%s' (%s, %s)\n",
|
||||||
|
progname, cur_arg, prev_found, optp->name);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (must_be_var && !optp->changeable_var)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: the argument to -O must be a variable\n",
|
||||||
|
progname);
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
if (optp->arg_type == NO_ARG && *optend == '=')
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: option '--%s' cannot take an argument\n",
|
||||||
|
progname, optp->name);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
else if (optp->arg_type == REQUIRED_ARG && !*optend)
|
||||||
|
{
|
||||||
|
/* Check if there are more arguments after this one */
|
||||||
|
if (!(*(pos + 1)))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: option '--%s' requires an argument\n",
|
||||||
|
progname, optp->name);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
argument = *pos;
|
||||||
|
(*argc)--;
|
||||||
|
}
|
||||||
|
else if (*optend == '=')
|
||||||
|
argument = *(optend + 1) ? optend + 1 : "";
|
||||||
|
}
|
||||||
|
else // must be short option
|
||||||
|
{
|
||||||
|
my_bool skip;
|
||||||
|
for (skip = 0, optend = (cur_arg + 1); *optend && !skip; optend++)
|
||||||
|
{
|
||||||
|
for (optp = longopts; optp->id ; optp++)
|
||||||
|
{
|
||||||
|
if (optp->id == (int) (uchar) *optend)
|
||||||
|
{
|
||||||
|
/* Option recognized. Find next what to do with it */
|
||||||
|
if (optp->arg_type == REQUIRED_ARG || optp->arg_type == OPT_ARG)
|
||||||
|
{
|
||||||
|
if (*(optend + 1))
|
||||||
|
{
|
||||||
|
argument = (optend + 1);
|
||||||
|
/*
|
||||||
|
The rest of the option is option argument
|
||||||
|
This is in effect a jump out of this loop
|
||||||
|
*/
|
||||||
|
skip = 1;
|
||||||
|
}
|
||||||
|
else if (optp->arg_type == REQUIRED_ARG)
|
||||||
|
{
|
||||||
|
/* Check if there are more arguments after this one */
|
||||||
|
if (!(*(pos + 1)))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: option '-%c' requires an argument\n",
|
||||||
|
progname, optp->id);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
argument = *pos;
|
||||||
|
(*argc)--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*(optend + 1)) // we are hitting many options in 1 argv
|
||||||
|
get_one_option(optp->id, optp, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get_one_option(optp->id, optp, argument);
|
||||||
|
(*argc)--; // option handled (short<72>or<6F>long), decrease argument count
|
||||||
|
}
|
||||||
|
else // non-option found
|
||||||
|
(*argv)[argvpos++] = cur_arg;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* function: findopt
|
||||||
|
Arguments: opt_pattern, length of opt_pattern, opt_struct, first found
|
||||||
|
name (ffname)
|
||||||
|
|
||||||
|
Go through all options in the my_option struct. Return number
|
||||||
|
of options found that match the pattern and in the argument
|
||||||
|
list the option found, if any. In case of ambiguous option, store
|
||||||
|
the name in ffname argument
|
||||||
|
*/
|
||||||
|
static int findopt (char *optpat, uint length,
|
||||||
|
const struct my_option **opt_res,
|
||||||
|
char **ffname)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
struct my_option *opt= (struct my_option *) *opt_res;
|
||||||
|
|
||||||
|
for (count = 0; opt->id; opt++)
|
||||||
|
{
|
||||||
|
if (!strncmp(opt->name, optpat, length)) // match found
|
||||||
|
{
|
||||||
|
(*opt_res) = opt;
|
||||||
|
if (!count)
|
||||||
|
*ffname = (char *) opt->name; // we only need to know one prev
|
||||||
|
if (length == strlen(opt->name)) // exact match
|
||||||
|
return 1;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
25
sql/log.cc
25
sql/log.cc
@ -703,12 +703,37 @@ void MYSQL_LOG::new_file(bool inside_mutex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MYSQL_LOG::append(Log_event* ev)
|
||||||
|
{
|
||||||
|
bool error = 0;
|
||||||
|
pthread_mutex_lock(&LOCK_log);
|
||||||
|
|
||||||
|
DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
|
||||||
|
// Log_event::write() is smart enough to use my_b_write() or
|
||||||
|
// my_b_append() depending on the kind of cache we have
|
||||||
|
if (ev->write(&log_file))
|
||||||
|
{
|
||||||
|
error=1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if ((uint)my_b_append_tell(&log_file) > max_binlog_size)
|
||||||
|
{
|
||||||
|
new_file(1);
|
||||||
|
}
|
||||||
|
signal_update();
|
||||||
|
err:
|
||||||
|
pthread_mutex_unlock(&LOCK_log);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
bool MYSQL_LOG::appendv(const char* buf, uint len,...)
|
bool MYSQL_LOG::appendv(const char* buf, uint len,...)
|
||||||
{
|
{
|
||||||
bool error = 0;
|
bool error = 0;
|
||||||
va_list(args);
|
va_list(args);
|
||||||
va_start(args,len);
|
va_start(args,len);
|
||||||
|
|
||||||
|
DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_log);
|
pthread_mutex_lock(&LOCK_log);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,18 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
inline int my_b_safe_write(IO_CACHE* file, const char* buf,
|
||||||
|
int len)
|
||||||
|
{
|
||||||
|
// Sasha: We are not writing this with the ? operator to avoid hitting
|
||||||
|
// a possible compiler bug. At least gcc 2.95 cannot deal with
|
||||||
|
// several layers of ternary operators that evaluated comma(,) operator
|
||||||
|
// expressions inside - I do have a test case if somebody wants it
|
||||||
|
if (file->type == SEQ_READ_APPEND)
|
||||||
|
return my_b_append(file,buf,len);
|
||||||
|
return my_b_write(file,buf,len);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
static void pretty_print_str(FILE* file, char* str, int len)
|
static void pretty_print_str(FILE* file, char* str, int len)
|
||||||
{
|
{
|
||||||
@ -403,7 +415,7 @@ int Log_event::write_header(IO_CACHE* file)
|
|||||||
pos += 4;
|
pos += 4;
|
||||||
int2store(pos, flags);
|
int2store(pos, flags);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
return (my_b_write(file, (byte*) buf, (uint) (pos - buf)));
|
return (my_b_safe_write(file, (byte*) buf, (uint) (pos - buf)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
@ -677,7 +689,7 @@ int Start_log_event::write_data(IO_CACHE* file)
|
|||||||
int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
|
int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
|
||||||
memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
|
memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
|
||||||
int4store(buff + ST_CREATED_OFFSET,created);
|
int4store(buff + ST_CREATED_OFFSET,created);
|
||||||
return (my_b_write(file, (byte*) buff, sizeof(buff)) ? -1 : 0);
|
return (my_b_safe_write(file, (byte*) buff, sizeof(buff)) ? -1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rotate_log_event::Rotate_log_event(const char* buf, int event_len,
|
Rotate_log_event::Rotate_log_event(const char* buf, int event_len,
|
||||||
@ -714,8 +726,8 @@ int Rotate_log_event::write_data(IO_CACHE* file)
|
|||||||
{
|
{
|
||||||
char buf[ROTATE_HEADER_LEN];
|
char buf[ROTATE_HEADER_LEN];
|
||||||
int8store(buf, pos + R_POS_OFFSET);
|
int8store(buf, pos + R_POS_OFFSET);
|
||||||
return my_b_write(file, (byte*)buf, ROTATE_HEADER_LEN) ||
|
return my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) ||
|
||||||
my_b_write(file, (byte*)new_log_ident, (uint) ident_len);
|
my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
@ -812,9 +824,9 @@ int Query_log_event::write_data(IO_CACHE* file)
|
|||||||
buf[Q_DB_LEN_OFFSET] = (char)db_len;
|
buf[Q_DB_LEN_OFFSET] = (char)db_len;
|
||||||
int2store(buf + Q_ERR_CODE_OFFSET, error_code);
|
int2store(buf + Q_ERR_CODE_OFFSET, error_code);
|
||||||
|
|
||||||
return (my_b_write(file, (byte*) buf, QUERY_HEADER_LEN) ||
|
return (my_b_safe_write(file, (byte*) buf, QUERY_HEADER_LEN) ||
|
||||||
my_b_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) ||
|
my_b_safe_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) ||
|
||||||
my_b_write(file, (byte*) query, q_len)) ? -1 : 0;
|
my_b_safe_write(file, (byte*) query, q_len)) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Intvar_log_event::Intvar_log_event(const char* buf, bool old_format):
|
Intvar_log_event::Intvar_log_event(const char* buf, bool old_format):
|
||||||
@ -840,7 +852,7 @@ int Intvar_log_event::write_data(IO_CACHE* file)
|
|||||||
char buf[9];
|
char buf[9];
|
||||||
buf[I_TYPE_OFFSET] = type;
|
buf[I_TYPE_OFFSET] = type;
|
||||||
int8store(buf + I_VAL_OFFSET, val);
|
int8store(buf + I_VAL_OFFSET, val);
|
||||||
return my_b_write(file, (byte*) buf, sizeof(buf));
|
return my_b_safe_write(file, (byte*) buf, sizeof(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
@ -878,7 +890,7 @@ int Load_log_event::write_data_header(IO_CACHE* file)
|
|||||||
buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
|
buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
|
||||||
buf[L_DB_LEN_OFFSET] = (char)db_len;
|
buf[L_DB_LEN_OFFSET] = (char)db_len;
|
||||||
int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
|
int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
|
||||||
return my_b_write(file, (byte*)buf, LOAD_HEADER_LEN);
|
return my_b_safe_write(file, (byte*)buf, LOAD_HEADER_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Load_log_event::write_data_body(IO_CACHE* file)
|
int Load_log_event::write_data_body(IO_CACHE* file)
|
||||||
@ -886,20 +898,20 @@ int Load_log_event::write_data_body(IO_CACHE* file)
|
|||||||
if (sql_ex.write_data(file)) return 1;
|
if (sql_ex.write_data(file)) return 1;
|
||||||
if (num_fields && fields && field_lens)
|
if (num_fields && fields && field_lens)
|
||||||
{
|
{
|
||||||
if (my_b_write(file, (byte*)field_lens, num_fields) ||
|
if (my_b_safe_write(file, (byte*)field_lens, num_fields) ||
|
||||||
my_b_write(file, (byte*)fields, field_block_len))
|
my_b_safe_write(file, (byte*)fields, field_block_len))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return (my_b_write(file, (byte*)table_name, table_name_len + 1) ||
|
return (my_b_safe_write(file, (byte*)table_name, table_name_len + 1) ||
|
||||||
my_b_write(file, (byte*)db, db_len + 1) ||
|
my_b_safe_write(file, (byte*)db, db_len + 1) ||
|
||||||
my_b_write(file, (byte*)fname, fname_len));
|
my_b_safe_write(file, (byte*)fname, fname_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool write_str(IO_CACHE *file, char *str, byte length)
|
static bool write_str(IO_CACHE *file, char *str, byte length)
|
||||||
{
|
{
|
||||||
return (my_b_write(file, &length, 1) ||
|
return (my_b_safe_write(file, &length, 1) ||
|
||||||
my_b_write(file, (byte*) str, (int) length));
|
my_b_safe_write(file, (byte*) str, (int) length));
|
||||||
}
|
}
|
||||||
|
|
||||||
int sql_ex_info::write_data(IO_CACHE* file)
|
int sql_ex_info::write_data(IO_CACHE* file)
|
||||||
@ -911,7 +923,7 @@ int sql_ex_info::write_data(IO_CACHE* file)
|
|||||||
write_str(file, line_term, line_term_len) ||
|
write_str(file, line_term, line_term_len) ||
|
||||||
write_str(file, line_start, line_start_len) ||
|
write_str(file, line_start, line_start_len) ||
|
||||||
write_str(file, escaped, escaped_len) ||
|
write_str(file, escaped, escaped_len) ||
|
||||||
my_b_write(file,(byte*) &opt_flags,1));
|
my_b_safe_write(file,(byte*) &opt_flags,1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -923,7 +935,7 @@ int sql_ex_info::write_data(IO_CACHE* file)
|
|||||||
old_ex.escaped= *escaped;
|
old_ex.escaped= *escaped;
|
||||||
old_ex.opt_flags= opt_flags;
|
old_ex.opt_flags= opt_flags;
|
||||||
old_ex.empty_flags=empty_flags;
|
old_ex.empty_flags=empty_flags;
|
||||||
return my_b_write(file, (byte*) &old_ex, sizeof(old_ex));
|
return my_b_safe_write(file, (byte*) &old_ex, sizeof(old_ex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1280,7 +1292,7 @@ int Slave_log_event::write_data(IO_CACHE* file)
|
|||||||
int8store(mem_pool + SL_MASTER_POS_OFFSET, master_pos);
|
int8store(mem_pool + SL_MASTER_POS_OFFSET, master_pos);
|
||||||
int2store(mem_pool + SL_MASTER_PORT_OFFSET, master_port);
|
int2store(mem_pool + SL_MASTER_PORT_OFFSET, master_port);
|
||||||
// log and host are already there
|
// log and host are already there
|
||||||
return my_b_write(file, (byte*)mem_pool, get_data_size());
|
return my_b_safe_write(file, (byte*)mem_pool, get_data_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Slave_log_event::init_from_mem_pool(int data_size)
|
void Slave_log_event::init_from_mem_pool(int data_size)
|
||||||
@ -1330,8 +1342,8 @@ int Create_file_log_event::write_data_body(IO_CACHE* file)
|
|||||||
int res;
|
int res;
|
||||||
if ((res = Load_log_event::write_data_body(file)) || fake_base)
|
if ((res = Load_log_event::write_data_body(file)) || fake_base)
|
||||||
return res;
|
return res;
|
||||||
return (my_b_write(file, (byte*) "", 1) ||
|
return (my_b_safe_write(file, (byte*) "", 1) ||
|
||||||
my_b_write(file, (byte*) block, block_len));
|
my_b_safe_write(file, (byte*) block, block_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
int Create_file_log_event::write_data_header(IO_CACHE* file)
|
int Create_file_log_event::write_data_header(IO_CACHE* file)
|
||||||
@ -1341,7 +1353,7 @@ int Create_file_log_event::write_data_header(IO_CACHE* file)
|
|||||||
return res;
|
return res;
|
||||||
byte buf[CREATE_FILE_HEADER_LEN];
|
byte buf[CREATE_FILE_HEADER_LEN];
|
||||||
int4store(buf + CF_FILE_ID_OFFSET, file_id);
|
int4store(buf + CF_FILE_ID_OFFSET, file_id);
|
||||||
return my_b_write(file, buf, CREATE_FILE_HEADER_LEN);
|
return my_b_safe_write(file, buf, CREATE_FILE_HEADER_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Create_file_log_event::write_base(IO_CACHE* file)
|
int Create_file_log_event::write_base(IO_CACHE* file)
|
||||||
@ -1423,8 +1435,8 @@ int Append_block_log_event::write_data(IO_CACHE* file)
|
|||||||
{
|
{
|
||||||
byte buf[APPEND_BLOCK_HEADER_LEN];
|
byte buf[APPEND_BLOCK_HEADER_LEN];
|
||||||
int4store(buf + AB_FILE_ID_OFFSET, file_id);
|
int4store(buf + AB_FILE_ID_OFFSET, file_id);
|
||||||
return (my_b_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
|
return (my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
|
||||||
my_b_write(file, (byte*) block, block_len));
|
my_b_safe_write(file, (byte*) block, block_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
@ -1473,7 +1485,7 @@ int Delete_file_log_event::write_data(IO_CACHE* file)
|
|||||||
{
|
{
|
||||||
byte buf[DELETE_FILE_HEADER_LEN];
|
byte buf[DELETE_FILE_HEADER_LEN];
|
||||||
int4store(buf + DF_FILE_ID_OFFSET, file_id);
|
int4store(buf + DF_FILE_ID_OFFSET, file_id);
|
||||||
return my_b_write(file, buf, DELETE_FILE_HEADER_LEN);
|
return my_b_safe_write(file, buf, DELETE_FILE_HEADER_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
@ -1520,7 +1532,7 @@ int Execute_load_log_event::write_data(IO_CACHE* file)
|
|||||||
{
|
{
|
||||||
byte buf[EXEC_LOAD_HEADER_LEN];
|
byte buf[EXEC_LOAD_HEADER_LEN];
|
||||||
int4store(buf + EL_FILE_ID_OFFSET, file_id);
|
int4store(buf + EL_FILE_ID_OFFSET, file_id);
|
||||||
return my_b_write(file, buf, EXEC_LOAD_HEADER_LEN);
|
return my_b_safe_write(file, buf, EXEC_LOAD_HEADER_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
|
95
sql/slave.cc
95
sql/slave.cc
@ -54,6 +54,9 @@ static int stuck_count = 0;
|
|||||||
typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE;
|
typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE;
|
||||||
|
|
||||||
void skip_load_data_infile(NET* net);
|
void skip_load_data_infile(NET* net);
|
||||||
|
static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev);
|
||||||
|
static int queue_old_event(MASTER_INFO* mi, const char* buf,
|
||||||
|
uint event_len);
|
||||||
static inline bool slave_killed(THD* thd,MASTER_INFO* mi);
|
static inline bool slave_killed(THD* thd,MASTER_INFO* mi);
|
||||||
static inline bool slave_killed(THD* thd,RELAY_LOG_INFO* rli);
|
static inline bool slave_killed(THD* thd,RELAY_LOG_INFO* rli);
|
||||||
static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type);
|
static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type);
|
||||||
@ -1918,26 +1921,15 @@ the slave SQL thread with \"mysqladmin start-slave\". We stopped at log \
|
|||||||
DBUG_RETURN(0); // Can't return anything here
|
DBUG_RETURN(0); // Can't return anything here
|
||||||
}
|
}
|
||||||
|
|
||||||
int queue_event(MASTER_INFO* mi,const char* buf,uint event_len)
|
static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev)
|
||||||
{
|
{
|
||||||
int error;
|
if (!rev->is_valid())
|
||||||
bool inc_pos = 1;
|
return 1;
|
||||||
if (mi->old_format)
|
DBUG_ASSERT(rev->ident_len<sizeof(mi->master_log_name));
|
||||||
return 1; // TODO: deal with old format
|
memcpy(mi->master_log_name,rev->new_log_ident,
|
||||||
|
rev->ident_len);
|
||||||
switch (buf[EVENT_TYPE_OFFSET])
|
mi->master_log_name[rev->ident_len] = 0;
|
||||||
{
|
mi->master_log_pos = rev->pos;
|
||||||
case ROTATE_EVENT:
|
|
||||||
{
|
|
||||||
Rotate_log_event rev(buf,event_len,0);
|
|
||||||
if (!rev.is_valid())
|
|
||||||
return 1;
|
|
||||||
DBUG_ASSERT(rev.ident_len<sizeof(mi->master_log_name));
|
|
||||||
memcpy(mi->master_log_name,rev.new_log_ident,
|
|
||||||
rev.ident_len);
|
|
||||||
mi->master_log_name[rev.ident_len] = 0;
|
|
||||||
mi->master_log_pos = rev.pos;
|
|
||||||
inc_pos = 0;
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
/* if we do not do this, we will be getting the first
|
/* if we do not do this, we will be getting the first
|
||||||
rotate event forever, so
|
rotate event forever, so
|
||||||
@ -1945,7 +1937,70 @@ int queue_event(MASTER_INFO* mi,const char* buf,uint event_len)
|
|||||||
*/
|
*/
|
||||||
if (disconnect_slave_event_count)
|
if (disconnect_slave_event_count)
|
||||||
events_till_disconnect++;
|
events_till_disconnect++;
|
||||||
#endif
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int queue_old_event(MASTER_INFO* mi, const char* buf,
|
||||||
|
uint event_len)
|
||||||
|
{
|
||||||
|
const char* errmsg = 0;
|
||||||
|
bool inc_pos = 1;
|
||||||
|
Log_event* ev = Log_event::read_log_event(buf,event_len, &errmsg,
|
||||||
|
1/*old format*/);
|
||||||
|
if (!ev)
|
||||||
|
{
|
||||||
|
sql_print_error("Read invalid event from master: '%s',\
|
||||||
|
master could be corrupt but a more likely cause of this is a bug",
|
||||||
|
errmsg);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ev->log_pos = mi->master_log_pos;
|
||||||
|
switch (ev->get_type_code())
|
||||||
|
{
|
||||||
|
case ROTATE_EVENT:
|
||||||
|
if (process_io_rotate(mi,(Rotate_log_event*)ev))
|
||||||
|
{
|
||||||
|
delete ev;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
inc_pos = 0;
|
||||||
|
break;
|
||||||
|
case LOAD_EVENT:
|
||||||
|
// TODO: actually process it
|
||||||
|
mi->master_log_pos += event_len;
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (mi->rli.relay_log.append(ev))
|
||||||
|
{
|
||||||
|
delete ev;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
delete ev;
|
||||||
|
if (inc_pos)
|
||||||
|
mi->master_log_pos += event_len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int queue_event(MASTER_INFO* mi,const char* buf,uint event_len)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
bool inc_pos = 1;
|
||||||
|
if (mi->old_format)
|
||||||
|
return queue_old_event(mi,buf,event_len);
|
||||||
|
// TODO: figure out if other events in addition to Rotate
|
||||||
|
// require special processing
|
||||||
|
switch (buf[EVENT_TYPE_OFFSET])
|
||||||
|
{
|
||||||
|
case ROTATE_EVENT:
|
||||||
|
{
|
||||||
|
Rotate_log_event rev(buf,event_len,0);
|
||||||
|
if (process_io_rotate(mi,&rev))
|
||||||
|
return 1;
|
||||||
|
inc_pos=0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -108,6 +108,7 @@ public:
|
|||||||
//v stands for vector
|
//v stands for vector
|
||||||
//invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
|
//invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
|
||||||
bool appendv(const char* buf,uint len,...);
|
bool appendv(const char* buf,uint len,...);
|
||||||
|
bool append(Log_event* ev);
|
||||||
|
|
||||||
int generate_new_name(char *new_name,const char *old_name);
|
int generate_new_name(char *new_name,const char *old_name);
|
||||||
void make_log_name(char* buf, const char* log_ident);
|
void make_log_name(char* buf, const char* log_ident);
|
||||||
|
Reference in New Issue
Block a user