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
|
||||
mwagner@cash.mwagner.org
|
||||
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}.
|
||||
@item
|
||||
@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
|
||||
Fixed bug with empty expression for boolean fulltext search.
|
||||
@item
|
||||
Fixed core dump bug in updating fulltext key from/to @code{NULL}.
|
||||
@item
|
||||
ODBC compatibility: Added @code{BIT_LENGTH()}
|
||||
ODBC compatibility: Added @code{BIT_LENGTH()}.
|
||||
@item
|
||||
Fixed core dump bug in @code{GROUP BY BINARY column}.
|
||||
@item
|
||||
@ -48315,7 +48315,7 @@ For more information, read @ref{Cast Functions}.
|
||||
@code{CREATE ... SELECT} on @code{DATE} and @code{TIME} functions now
|
||||
create columns of the expected type.
|
||||
@item
|
||||
Changed order of how keys are created in tables.
|
||||
Changed order in which keys are created in tables.
|
||||
@item
|
||||
Added a new columns @code{Null} and @code{Index_type} to @code{SHOW INDEX}.
|
||||
@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{ALTER TABLE table_name DISABLE KEYS} in the sql dump.
|
||||
@item
|
||||
Added @code{mysql_fix_extensions} script
|
||||
Added @code{mysql_fix_extensions} script.
|
||||
@item
|
||||
Fixed stack overrun problem @code{LOAD DATA FROM MASTER} on OSF1.
|
||||
@item
|
||||
Fixed shutdown problem on HPUX.
|
||||
Fixed shutdown problem on HP-UX.
|
||||
@item
|
||||
Added functions @code{des_encrypt()} and @code{des_decrypt()}.
|
||||
@item
|
||||
Added statement @code{FLUSH DES_KEY_FILE}.
|
||||
@item
|
||||
Added mysqld option @code{--des-key-file}.
|
||||
Added @code{mysqld} option @code{--des-key-file}.
|
||||
@item
|
||||
@code{HEX(string)} now returns the characters in string converted to
|
||||
hexadecimal.
|
||||
@ -48352,7 +48352,7 @@ Changed @code{SELECT ... IN SHARE MODE} to
|
||||
@item
|
||||
A new query cache to cache results from identical @code{SELECT} queries.
|
||||
@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.
|
||||
@item
|
||||
@code{MATCH ... AGAINST(... IN BOOLEAN MODE)} can now work
|
||||
@ -48370,7 +48370,7 @@ of @code{FULLTEXT} indexes.
|
||||
Fixed bug in @code{DELETE ... WHERE ... MATCH ...}.
|
||||
@item
|
||||
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
|
||||
able to use boolean fulltext search}.
|
||||
@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
|
||||
the @code{AFTER} keyword.
|
||||
@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
|
||||
|
||||
@node News-4.0.0, , News-4.0.1, News-4.0.x
|
||||
@ -48446,28 +48446,28 @@ Speed up all internal list handling.
|
||||
@item
|
||||
Speed up @code{IS NULL}, @code{ISNULL()} and some other internal primitives.
|
||||
@item
|
||||
Creating full text indexes are now much faster.
|
||||
Full text index creation now is much faster.
|
||||
@item
|
||||
Tree-like cache to speed up bulk inserts and
|
||||
@code{myisam_bulk_insert_tree_size} variable.
|
||||
@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
|
||||
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
|
||||
@code{SHOW CREATE TABLE} now shows all table attributes.
|
||||
@item
|
||||
@code{ORDER BY ... DESC} can now use keys.
|
||||
@item
|
||||
@code{LOAD DATA FROM MASTER} "auto-magically" sets up a slave.
|
||||
@code{LOAD DATA FROM MASTER} ``auto-magically'' sets up a slave.
|
||||
@item
|
||||
Renamed @code{safe_mysqld} to @code{mysqld_safe}.
|
||||
@item
|
||||
Added support for symbolic links to @code{MyISAM} tables. Symlink handling is
|
||||
now enabled by default for Windows.
|
||||
@item
|
||||
@code{LOAD DATA FROM MASTER} "auto-magically" sets up a slave.
|
||||
@code{LOAD DATA FROM MASTER} ``auto-magically'' sets up a slave.
|
||||
@item
|
||||
Added @code{SQL_CALC_FOUND_ROWS} and @code{FOUND_ROWS()}. This makes it
|
||||
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
|
||||
@code{ALTER TABLE table_name ENABLE KEYS} commands.
|
||||
@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
|
||||
Implemented ``repair by sort'' for @code{FULLTEXT} indexes.
|
||||
@code{REPAIR TABLE}, @code{ALTER TABLE}, and @code{OPTIMIZE TABLE}
|
||||
for tables with @code{FULLTEXT} indexes are now up to 100 times faster.
|
||||
@item
|
||||
Allow ANSI SQL syntax @code{X'hexadecimal-number'}
|
||||
Allow ANSI SQL syntax @code{X'hexadecimal-number'}.
|
||||
@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
|
||||
Fixed problem with @code{DATETIME = constant} in @code{WHERE} optimisation.
|
||||
@item
|
||||
@ -48610,13 +48610,13 @@ Restrict InnoDB keys to 500 bytes.
|
||||
@item
|
||||
InnoDB now supports @code{NULL} in keys.
|
||||
@item
|
||||
Fixed shutdown problem on HPUX. (Introduced in 3.23.46)
|
||||
Fixed shutdown problem on HP-UX. (Introduced in 3.23.46)
|
||||
@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
|
||||
Added new command: @code{DO expression,[expression]}
|
||||
@item
|
||||
Added @code{slave-skip-errors} option
|
||||
Added @code{slave-skip-errors} option.
|
||||
@item
|
||||
Added statistics variables for all MySQL commands. (@code{SHOW STATUS} is
|
||||
now much longer).
|
||||
@ -48627,7 +48627,7 @@ Fixed that @code{GROUP BY expr DESC} works.
|
||||
@item
|
||||
Fixed bug when using @code{t1 LEFT JOIN t2 ON t2.key=constant}.
|
||||
@item
|
||||
@code{mysql_config} now also work with binary (relocated) distributions.
|
||||
@code{mysql_config} now also works with binary (relocated) distributions.
|
||||
@end itemize
|
||||
|
||||
@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 */
|
||||
|
||||
/* mysqltest test tool
|
||||
* See man page for more information.
|
||||
* See the manual for more information
|
||||
* TODO: document better how mysqltest works
|
||||
*
|
||||
* Written by:
|
||||
* Sasha Pachev <sasha@mysql.com>
|
||||
@ -26,9 +27,6 @@
|
||||
/**********************************************************************
|
||||
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
|
||||
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
|
||||
@ -43,7 +41,7 @@
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#define MTEST_VERSION "1.13"
|
||||
#define MTEST_VERSION "1.14"
|
||||
|
||||
#include <my_global.h>
|
||||
#include <mysql_embed.h>
|
||||
@ -88,6 +86,12 @@
|
||||
#define CON_RETRY_SLEEP 2
|
||||
#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,
|
||||
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_RESULT_LOG, Q_DISABLE_RESULT_LOG,
|
||||
Q_SERVER_START, Q_SERVER_STOP,Q_REQUIRE_MANAGER,
|
||||
Q_WAIT_FOR_SLAVE_TO_STOP,
|
||||
Q_UNKNOWN, /* Unknown command. */
|
||||
Q_COMMENT, /* Comments, ignored. */
|
||||
Q_COMMENT_WITH_COMMAND
|
||||
@ -222,7 +227,7 @@ const char *command_names[] = {
|
||||
"enable_query_log", "disable_query_log",
|
||||
"enable_result_log", "disable_result_log",
|
||||
"server_start", "server_stop",
|
||||
"require_manager",
|
||||
"require_manager", "wait_for_slave_to_stop",
|
||||
0
|
||||
};
|
||||
|
||||
@ -653,6 +658,45 @@ int open_file(const char* name)
|
||||
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)
|
||||
{
|
||||
if (!manager)
|
||||
@ -2335,6 +2379,7 @@ int main(int argc, char** argv)
|
||||
case Q_DISABLE_RESULT_LOG: disable_result_log=1; break;
|
||||
case Q_SOURCE: do_source(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;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
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_nosys.h my_alarm.h queues.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 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_block_write(IO_CACHE *info, const byte *Buffer,
|
||||
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 uint my_b_fill(IO_CACHE *info);
|
||||
extern void my_b_seek(IO_CACHE *info,my_off_t pos);
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include <m_ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <getopt.h>
|
||||
#include <my_getopt.h>
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_SYS_VADVICE_H
|
||||
#include <sys/vadvise.h>
|
||||
@ -169,58 +169,75 @@ static CHANGEABLE_VAR changeable_vars[] = {
|
||||
|
||||
enum options {
|
||||
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 option long_options[] =
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
{"analyze", no_argument, 0, 'a'},
|
||||
{"block-search", required_argument,0, 'b'},
|
||||
{"backup", no_argument, 0, 'B'},
|
||||
{"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR},
|
||||
{"check", no_argument, 0, 'c'},
|
||||
{"check-only-changed",no_argument, 0, 'C'},
|
||||
{"correct-checksum", no_argument, 0, OPT_CORRECT_CHECKSUM},
|
||||
{"analyze", "", 0, 0, GET_NO_ARG, NO_ARG, 'a', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"block-search", "", 0, 0, GET_LL, REQUIRED_ARG, 'b', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"backup", "", 0, 0, GET_NO_ARG, NO_ARG, 'B', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"character-sets-dir", "", 0, 0, GET_STR, REQUIRED_ARG, OPT_CHARSETS_DIR, 0, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
{"check", "", 0, 0, GET_NO_ARG, NO_ARG, 'c', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"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
|
||||
{"debug", optional_argument, 0, '#'},
|
||||
{"debug", "", 0, 0, GET_STR, OPT_ARG, '#', 0, 0, 0, 0, 0, 0, 0},
|
||||
#endif
|
||||
{"description", no_argument, 0, 'd'},
|
||||
{"data-file-length", required_argument, 0, 'D'},
|
||||
{"extend-check", no_argument, 0, 'e'},
|
||||
{"fast", no_argument, 0, 'F'},
|
||||
{"force", no_argument, 0, 'f'},
|
||||
{"help", no_argument, 0, '?'},
|
||||
{"information", no_argument, 0, 'i'},
|
||||
{"keys-used", required_argument, 0, 'k'},
|
||||
{"medium-check", no_argument, 0, 'm'},
|
||||
{"quick", no_argument, 0, 'q'},
|
||||
{"read-only", no_argument, 0, 'T'},
|
||||
{"recover", no_argument, 0, 'r'},
|
||||
{"safe-recover", no_argument, 0, 'o'},
|
||||
{"start-check-pos", required_argument, 0, OPT_START_CHECK_POS},
|
||||
{"set-auto-increment",optional_argument, 0, 'A'},
|
||||
{"set-character-set",required_argument,0,OPT_SET_CHARSET},
|
||||
{"set-variable", required_argument, 0, 'O'},
|
||||
{"silent", no_argument, 0, 's'},
|
||||
{"sort-index", no_argument, 0, 'S'},
|
||||
{"sort-records", required_argument, 0, 'R'},
|
||||
{"sort-recover", no_argument, 0, 'n'},
|
||||
{"tmpdir", required_argument, 0, 't'},
|
||||
{"update-state", no_argument, 0, 'U'},
|
||||
{"unpack", no_argument, 0, 'u'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"wait", no_argument, 0, 'w'},
|
||||
{0, 0, 0, 0}
|
||||
{"description", "", 0, 0, GET_NO_ARG, NO_ARG, 'd', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"data-file-length", "", 0, 0, GET_LL, REQUIRED_ARG, 'D', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"extend-check", "", 0, 0, GET_NO_ARG, NO_ARG, 'e', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"fast", "", 0, 0, GET_NO_ARG, NO_ARG, 'F', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"force", "", 0, 0, GET_NO_ARG, NO_ARG, 'f', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"help", "", 0, 0, GET_NO_ARG, NO_ARG, '?', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"information", "", 0, 0, GET_NO_ARG, NO_ARG, 'i', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"keys-used", "", 0, 0, GET_LL, REQUIRED_ARG, 'k', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"medium-check", "", 0, 0, GET_NO_ARG, NO_ARG, 'm', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"quick", "", 0, 0, GET_NO_ARG, NO_ARG, 'q', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"read-only", "", 0, 0, GET_NO_ARG, NO_ARG, 'T', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"recover", "", 0, 0, GET_NO_ARG, NO_ARG, 'r', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"safe-recover", "", 0, 0, GET_NO_ARG, NO_ARG, 'o', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"start-check-pos", "", 0, 0, GET_LL, REQUIRED_ARG, OPT_START_CHECK_POS, 0, 0, 0, 0, 0, 0, 0},
|
||||
{"set-auto-increment", "", 0, 0, GET_LL, OPT_ARG, 'A', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"set-character-set", "", 0, 0, GET_STR, REQUIRED_ARG, OPT_SET_CHARSET, 0, 0, 0, 0, 0, 0, 0},
|
||||
{"set-variable", "", 0, 0, GET_STR, REQUIRED_ARG, 'O', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"silent", "", 0, 0, GET_NO_ARG, NO_ARG, 's', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"sort-index", "", 0, 0, GET_NO_ARG, NO_ARG, 'S', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"sort-records", "", 0, 0, GET_INT, REQUIRED_ARG, 'R', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"sort-recover", "", 0, 0, GET_NO_ARG, NO_ARG, 'n', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"tmpdir", "", 0, 0, GET_STR, REQUIRED_ARG, 't', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"update-state", "", 0, 0, GET_NO_ARG, NO_ARG, 'U', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"unpack", "", 0, 0, GET_NO_ARG, NO_ARG, 'u', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"verbose", "", 0, 0, GET_NO_ARG, NO_ARG, 'v', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"version", "", 0, 0, GET_NO_ARG, NO_ARG, 'V', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"wait", "", 0, 0, GET_NO_ARG, NO_ARG, 'w', 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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
uint i;
|
||||
@ -315,163 +332,182 @@ static void usage(void)
|
||||
|
||||
/* 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)
|
||||
{
|
||||
int c,option_index=0;
|
||||
uint old_testflag;
|
||||
|
||||
load_defaults("my",load_default_groups,argc,argv);
|
||||
default_argv= *argv;
|
||||
set_all_changeable_vars(changeable_vars);
|
||||
if (isatty(fileno(stdout)))
|
||||
check_param.testflag|=T_WRITE_LOOP;
|
||||
while ((c=getopt_long(*argc,*argv,
|
||||
"aBcCdeifF?lqrmnosSTuUvVw#:b:D:k:O:R:A::t:",
|
||||
long_options, &option_index)) != EOF)
|
||||
{
|
||||
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 (handle_options(argc, argv, my_long_options, get_one_option))
|
||||
exit(1);
|
||||
|
||||
/* If using repair, then update checksum if one uses --update-state */
|
||||
if ((check_param.testflag & T_UPDATE_STATE) &&
|
||||
(check_param.testflag & (T_REP | T_REP_BY_SORT)))
|
||||
check_param.testflag|= T_CALC_CHECKSUM;
|
||||
|
||||
(*argc)-=optind;
|
||||
(*argv)+=optind;
|
||||
if (*argc == 0)
|
||||
{
|
||||
usage();
|
||||
|
@ -33,7 +33,6 @@ master-bin.003
|
||||
insert into t2 values(1234);
|
||||
set insert_id=1234;
|
||||
insert into t2 values(NULL);
|
||||
slave stop;
|
||||
set sql_slave_skip_counter=1;
|
||||
slave start;
|
||||
purge master logs to 'master-bin.003';
|
||||
@ -66,7 +65,7 @@ slave stop;
|
||||
slave start;
|
||||
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
|
||||
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;
|
||||
select count(*) from t3 where n >= 4;
|
||||
count(*)
|
||||
|
@ -51,9 +51,7 @@ insert into t2 values(NULL);
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
|
||||
#the slave may have already stopped, so we ignore the error
|
||||
--error 0,1199
|
||||
!slave stop;
|
||||
wait_for_slave_to_stop;
|
||||
|
||||
#restart slave skipping one event
|
||||
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_chsize.c my_lread.c my_lwrite.c my_clock.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 \
|
||||
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 \
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
#include <m_ctype.h>
|
||||
|
||||
#include <my_getopt.h>
|
||||
/* set all changeable variables */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
Count-=rest_length;
|
||||
info->write_pos+=rest_length;
|
||||
if (flush_io_cache(info))
|
||||
if (_flush_io_cache(info,0))
|
||||
{
|
||||
unlock_append_buffer(info);
|
||||
return 1;
|
||||
}
|
||||
if (Count >= IO_SIZE)
|
||||
{ /* Fill first intern buffer */
|
||||
length=Count & (uint) ~(IO_SIZE-1);
|
||||
if (my_write(info->file,Buffer,(uint) length,info->myflags | MY_NABP))
|
||||
{
|
||||
unlock_append_buffer(info);
|
||||
return info->error= -1;
|
||||
}
|
||||
Count-=length;
|
||||
Buffer+=length;
|
||||
}
|
||||
@ -883,14 +889,16 @@ int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count,
|
||||
|
||||
/* Flush write cache */
|
||||
|
||||
int flush_io_cache(IO_CACHE *info)
|
||||
int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
|
||||
{
|
||||
uint length;
|
||||
my_bool append_cache;
|
||||
my_off_t pos_in_file;
|
||||
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->file == -1)
|
||||
@ -898,6 +906,8 @@ int flush_io_cache(IO_CACHE *info)
|
||||
if (real_open_cached_file(info))
|
||||
DBUG_RETURN((info->error= -1));
|
||||
}
|
||||
if (need_append_buffer_lock)
|
||||
lock_append_buffer(info);
|
||||
if ((length=(uint) (info->write_pos - info->write_buffer)))
|
||||
{
|
||||
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)) ==
|
||||
MY_FILEPOS_ERROR)
|
||||
{
|
||||
if (need_append_buffer_lock)
|
||||
unlock_append_buffer(info);
|
||||
DBUG_RETURN((info->error= -1));
|
||||
}
|
||||
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->append_read_pos=info->write_pos=info->write_buffer;
|
||||
if (need_append_buffer_lock)
|
||||
unlock_append_buffer(info);
|
||||
DBUG_RETURN(info->error);
|
||||
}
|
||||
}
|
||||
@ -942,6 +956,8 @@ int flush_io_cache(IO_CACHE *info)
|
||||
info->inited=0;
|
||||
}
|
||||
#endif
|
||||
if (need_append_buffer_lock)
|
||||
unlock_append_buffer(info);
|
||||
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 error = 0;
|
||||
va_list(args);
|
||||
va_start(args,len);
|
||||
|
||||
DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
|
||||
|
||||
pthread_mutex_lock(&LOCK_log);
|
||||
do
|
||||
{
|
||||
|
@ -26,6 +26,18 @@
|
||||
|
||||
#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
|
||||
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;
|
||||
int2store(pos, flags);
|
||||
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
|
||||
@ -677,7 +689,7 @@ int Start_log_event::write_data(IO_CACHE* file)
|
||||
int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
|
||||
memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
|
||||
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,
|
||||
@ -714,8 +726,8 @@ int Rotate_log_event::write_data(IO_CACHE* file)
|
||||
{
|
||||
char buf[ROTATE_HEADER_LEN];
|
||||
int8store(buf, pos + R_POS_OFFSET);
|
||||
return my_b_write(file, (byte*)buf, ROTATE_HEADER_LEN) ||
|
||||
my_b_write(file, (byte*)new_log_ident, (uint) ident_len);
|
||||
return my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) ||
|
||||
my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len);
|
||||
}
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
@ -812,9 +824,9 @@ int Query_log_event::write_data(IO_CACHE* file)
|
||||
buf[Q_DB_LEN_OFFSET] = (char)db_len;
|
||||
int2store(buf + Q_ERR_CODE_OFFSET, error_code);
|
||||
|
||||
return (my_b_write(file, (byte*) buf, QUERY_HEADER_LEN) ||
|
||||
my_b_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) ||
|
||||
my_b_write(file, (byte*) query, q_len)) ? -1 : 0;
|
||||
return (my_b_safe_write(file, (byte*) buf, QUERY_HEADER_LEN) ||
|
||||
my_b_safe_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) ||
|
||||
my_b_safe_write(file, (byte*) query, q_len)) ? -1 : 0;
|
||||
}
|
||||
|
||||
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];
|
||||
buf[I_TYPE_OFFSET] = type;
|
||||
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
|
||||
@ -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_DB_LEN_OFFSET] = (char)db_len;
|
||||
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)
|
||||
@ -886,20 +898,20 @@ int Load_log_event::write_data_body(IO_CACHE* file)
|
||||
if (sql_ex.write_data(file)) return 1;
|
||||
if (num_fields && fields && field_lens)
|
||||
{
|
||||
if (my_b_write(file, (byte*)field_lens, num_fields) ||
|
||||
my_b_write(file, (byte*)fields, field_block_len))
|
||||
if (my_b_safe_write(file, (byte*)field_lens, num_fields) ||
|
||||
my_b_safe_write(file, (byte*)fields, field_block_len))
|
||||
return 1;
|
||||
}
|
||||
return (my_b_write(file, (byte*)table_name, table_name_len + 1) ||
|
||||
my_b_write(file, (byte*)db, db_len + 1) ||
|
||||
my_b_write(file, (byte*)fname, fname_len));
|
||||
return (my_b_safe_write(file, (byte*)table_name, table_name_len + 1) ||
|
||||
my_b_safe_write(file, (byte*)db, db_len + 1) ||
|
||||
my_b_safe_write(file, (byte*)fname, fname_len));
|
||||
}
|
||||
|
||||
|
||||
static bool write_str(IO_CACHE *file, char *str, byte length)
|
||||
{
|
||||
return (my_b_write(file, &length, 1) ||
|
||||
my_b_write(file, (byte*) str, (int) length));
|
||||
return (my_b_safe_write(file, &length, 1) ||
|
||||
my_b_safe_write(file, (byte*) str, (int) length));
|
||||
}
|
||||
|
||||
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_start, line_start_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
|
||||
{
|
||||
@ -923,7 +935,7 @@ int sql_ex_info::write_data(IO_CACHE* file)
|
||||
old_ex.escaped= *escaped;
|
||||
old_ex.opt_flags= opt_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);
|
||||
int2store(mem_pool + SL_MASTER_PORT_OFFSET, master_port);
|
||||
// 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)
|
||||
@ -1330,8 +1342,8 @@ int Create_file_log_event::write_data_body(IO_CACHE* file)
|
||||
int res;
|
||||
if ((res = Load_log_event::write_data_body(file)) || fake_base)
|
||||
return res;
|
||||
return (my_b_write(file, (byte*) "", 1) ||
|
||||
my_b_write(file, (byte*) block, block_len));
|
||||
return (my_b_safe_write(file, (byte*) "", 1) ||
|
||||
my_b_safe_write(file, (byte*) block, block_len));
|
||||
}
|
||||
|
||||
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;
|
||||
byte buf[CREATE_FILE_HEADER_LEN];
|
||||
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)
|
||||
@ -1423,8 +1435,8 @@ int Append_block_log_event::write_data(IO_CACHE* file)
|
||||
{
|
||||
byte buf[APPEND_BLOCK_HEADER_LEN];
|
||||
int4store(buf + AB_FILE_ID_OFFSET, file_id);
|
||||
return (my_b_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
|
||||
my_b_write(file, (byte*) block, block_len));
|
||||
return (my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
|
||||
my_b_safe_write(file, (byte*) block, block_len));
|
||||
}
|
||||
|
||||
#ifdef MYSQL_CLIENT
|
||||
@ -1473,7 +1485,7 @@ int Delete_file_log_event::write_data(IO_CACHE* file)
|
||||
{
|
||||
byte buf[DELETE_FILE_HEADER_LEN];
|
||||
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
|
||||
@ -1520,7 +1532,7 @@ int Execute_load_log_event::write_data(IO_CACHE* file)
|
||||
{
|
||||
byte buf[EXEC_LOAD_HEADER_LEN];
|
||||
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
|
||||
|
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;
|
||||
|
||||
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,RELAY_LOG_INFO* rli);
|
||||
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
|
||||
}
|
||||
|
||||
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;
|
||||
bool inc_pos = 1;
|
||||
if (mi->old_format)
|
||||
return 1; // TODO: deal with old format
|
||||
|
||||
switch (buf[EVENT_TYPE_OFFSET])
|
||||
{
|
||||
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;
|
||||
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;
|
||||
#ifndef DBUG_OFF
|
||||
/* if we do not do this, we will be getting the first
|
||||
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)
|
||||
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;
|
||||
}
|
||||
default:
|
||||
|
@ -108,6 +108,7 @@ public:
|
||||
//v stands for vector
|
||||
//invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
|
||||
bool appendv(const char* buf,uint len,...);
|
||||
bool append(Log_event* ev);
|
||||
|
||||
int generate_new_name(char *new_name,const char *old_name);
|
||||
void make_log_name(char* buf, const char* log_ident);
|
||||
|
Reference in New Issue
Block a user