Merge with 4.0
BitKeeper/etc/logging_ok: auto-union BitKeeper/deleted/.del-apply-patch: Delete: netware/BUILD/apply-patch BitKeeper/deleted/.del-save-patch: Delete: netware/BUILD/save-patch BitKeeper/deleted/.del-mini_client.cc~8677895ec8169183: Auto merged BitKeeper/triggers/post-commit: Auto merged VC++Files/mysys/mysys.dsp: Auto merged client/mysqlbinlog.cc: Auto merged extra/resolveip.c: Auto merged include/config-win.h: Auto merged include/my_global.h: Auto merged include/my_sys.h: Auto merged include/mysql_com.h: Auto merged innobase/include/os0thread.h: Auto merged innobase/os/os0file.c: Auto merged innobase/srv/srv0start.c: Auto merged innobase/thr/thr0loc.c: Auto merged libmysql/manager.c: Auto merged libmysqld/Makefile.am: Auto merged libmysqld/lib_sql.cc: Auto merged myisam/ft_boolean_search.c: Auto merged myisam/mi_extra.c: Auto merged myisam/mi_locking.c: Auto merged mysql-test/mysql-test-run.sh: Auto merged mysql-test/r/fulltext.result: Auto merged mysql-test/r/myisam.result: Auto merged mysql-test/r/select.result: Auto merged mysql-test/t/fulltext.test: Auto merged mysql-test/t/myisam.test: Auto merged mysql-test/t/rpl_reset_slave.test: Auto merged mysql-test/t/rpl_trunc_binlog.test: Auto merged mysys/Makefile.am: Auto merged mysys/errors.c: Auto merged mysys/my_symlink.c: Auto merged mysys/my_thr_init.c: Auto merged scripts/mysql_install_db.sh: Auto merged sql/item_func.cc: Auto merged sql/log_event.h: Auto merged sql/mysqld.cc: Auto merged sql/slave.cc: Auto merged sql/sql_cache.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_repl.cc: Auto merged sql/sql_test.cc: Auto merged sql/unireg.h: Auto merged client/mysqldump.c: merge with 4.0 (quoted names) configure.in: use local file include/my_pthread.h: Use local file innobase/include/srv0srv.h: Use local file innobase/row/row0sel.c: Use local file innobase/srv/srv0srv.c: Use local file libmysql/libmysql.c: Use local file myisam/myisamchk.c: merge fixes mysql-test/r/func_crypt.result: update results mysql-test/r/order_by.result: update results mysql-test/r/query_cache.result: update results mysql-test/r/range.result: update results mysql-test/r/rpl_reset_slave.result: update results mysql-test/r/rpl_trunc_binlog.result: update results mysql-test/t/func_crypt.test: Added disable_warnings/enable warnings mysql-test/t/query_cache.test: merge tests mysql-test/t/range.test: merge tests mysys/charset.c: use local file (will merge patch separately) sql/ha_innodb.cc: use local file sql/log_event.cc: new slave_proxy_id handling sql/slave.h: merge sql/sql_base.cc: merge sql/sql_parse.cc: Fixes for counting user connect resourses Added function comments for involved functions sql/sql_select.cc: Fix for not doing sort with LIMIT when OPTION_FOUND_ROWS is used sql/unireg.cc: merge fixes support-files/mysql.server.sh: merge fixes
This commit is contained in:
commit
f97f48acaf
@ -19,7 +19,7 @@ BK_STATUS=$BK_STATUS$BK_COMMIT
|
|||||||
if [ "$BK_STATUS" = OK ]
|
if [ "$BK_STATUS" = OK ]
|
||||||
then
|
then
|
||||||
|
|
||||||
CHANGESET=`bk -R prs -r+ -h -d':I:' ChangeSet`
|
CHANGESET=`bk -R prs -r+ -h -d':P:::I:' ChangeSet`
|
||||||
|
|
||||||
#++
|
#++
|
||||||
# dev-public@
|
# dev-public@
|
||||||
|
@ -430,6 +430,10 @@ SOURCE=.\my_symlink2.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\my_sync.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\my_tempnam.c
|
SOURCE=.\my_tempnam.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
@ -52,7 +52,7 @@ static const char* host = 0;
|
|||||||
static int port = MYSQL_PORT;
|
static int port = MYSQL_PORT;
|
||||||
static const char* sock= 0;
|
static const char* sock= 0;
|
||||||
static const char* user = 0;
|
static const char* user = 0;
|
||||||
static const char* pass = "";
|
static char* pass = 0;
|
||||||
static ulonglong position = 0;
|
static ulonglong position = 0;
|
||||||
static short binlog_flags = 0;
|
static short binlog_flags = 0;
|
||||||
static MYSQL* mysql = NULL;
|
static MYSQL* mysql = NULL;
|
||||||
@ -226,7 +226,7 @@ static struct my_option my_long_options[] =
|
|||||||
{"offset", 'o', "Skip the first N entries.", (gptr*) &offset, (gptr*) &offset,
|
{"offset", 'o', "Skip the first N entries.", (gptr*) &offset, (gptr*) &offset,
|
||||||
0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"password", 'p', "Password to connect to remote server.",
|
{"password", 'p', "Password to connect to remote server.",
|
||||||
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"port", 'P', "Use port to connect to the remote server.",
|
{"port", 'P', "Use port to connect to the remote server.",
|
||||||
(gptr*) &port, (gptr*) &port, 0, GET_INT, REQUIRED_ARG, MYSQL_PORT, 0, 0,
|
(gptr*) &port, (gptr*) &port, 0, GET_INT, REQUIRED_ARG, MYSQL_PORT, 0, 0,
|
||||||
0, 0, 0},
|
0, 0, 0},
|
||||||
@ -266,6 +266,11 @@ void sql_print_error(const char *format,...)
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cleanup()
|
||||||
|
{
|
||||||
|
my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
|
}
|
||||||
|
|
||||||
static void die(const char* fmt, ...)
|
static void die(const char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
@ -274,6 +279,7 @@ static void die(const char* fmt, ...)
|
|||||||
vfprintf(stderr, fmt, args);
|
vfprintf(stderr, fmt, args);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
cleanup();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,6 +339,7 @@ extern "C" my_bool
|
|||||||
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||||
char *argument)
|
char *argument)
|
||||||
{
|
{
|
||||||
|
bool tty_password=0;
|
||||||
switch (optid) {
|
switch (optid) {
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
case '#':
|
case '#':
|
||||||
@ -343,7 +350,17 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||||||
one_database = 1;
|
one_database = 1;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
pass = my_strdup(argument, MYF(0));
|
if (argument)
|
||||||
|
{
|
||||||
|
my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
|
char *start=argument;
|
||||||
|
pass= my_strdup(argument,MYF(MY_FAE));
|
||||||
|
while (*argument) *argument++= 'x'; /* Destroy argument */
|
||||||
|
if (*start)
|
||||||
|
start[1]=0; /* Cut length of argument */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tty_password=1;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
if (!(result_file = my_fopen(argument, O_WRONLY | O_BINARY, MYF(MY_WME))))
|
if (!(result_file = my_fopen(argument, O_WRONLY | O_BINARY, MYF(MY_WME))))
|
||||||
@ -359,6 +376,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||||||
usage();
|
usage();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
if (tty_password)
|
||||||
|
pass= get_tty_password(NullS);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,6 +727,7 @@ int main(int argc, char** argv)
|
|||||||
my_fclose(result_file, MYF(0));
|
my_fclose(result_file, MYF(0));
|
||||||
if (remote_opt)
|
if (remote_opt)
|
||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
|
cleanup();
|
||||||
free_defaults(defaults_argv);
|
free_defaults(defaults_argv);
|
||||||
my_end(0);
|
my_end(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -632,6 +632,7 @@ static my_bool test_if_special_chars(const char *str)
|
|||||||
} /* test_if_special_chars */
|
} /* test_if_special_chars */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static char *quote_name(const char *name, char *buff, my_bool force)
|
static char *quote_name(const char *name, char *buff, my_bool force)
|
||||||
{
|
{
|
||||||
char *to= buff;
|
char *to= buff;
|
||||||
@ -789,7 +790,8 @@ static uint getTableStructure(char *table, char* db)
|
|||||||
if (verbose)
|
if (verbose)
|
||||||
fprintf(stderr, "-- Retrieving table structure for table %s...\n", table);
|
fprintf(stderr, "-- Retrieving table structure for table %s...\n", table);
|
||||||
|
|
||||||
sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", (opt_quoted || opt_keywords));
|
sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
|
||||||
|
(opt_quoted || opt_keywords));
|
||||||
result_table= quote_name(table, table_buff, 1);
|
result_table= quote_name(table, table_buff, 1);
|
||||||
opt_quoted_table= quote_name(table, table_buff2, 0);
|
opt_quoted_table= quote_name(table, table_buff2, 0);
|
||||||
if (!opt_xml && !mysql_query(sock,insert_pat))
|
if (!opt_xml && !mysql_query(sock,insert_pat))
|
||||||
@ -1041,7 +1043,8 @@ static uint getTableStructure(char *table, char* db)
|
|||||||
else if (keynr == primary_key)
|
else if (keynr == primary_key)
|
||||||
fputs(",\n PRIMARY KEY (",sql_file); /* First UNIQUE is primary */
|
fputs(",\n PRIMARY KEY (",sql_file); /* First UNIQUE is primary */
|
||||||
else
|
else
|
||||||
fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff,0));
|
fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff,
|
||||||
|
0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
putc(',', sql_file);
|
putc(',', sql_file);
|
||||||
@ -1520,23 +1523,28 @@ static int init_dumping(char *database)
|
|||||||
{
|
{
|
||||||
if (opt_databases || opt_alldbs)
|
if (opt_databases || opt_alldbs)
|
||||||
{
|
{
|
||||||
fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", database);
|
/*
|
||||||
|
length of table name * 2 (if name contain quotas), 2 quotas and 0
|
||||||
|
*/
|
||||||
|
char quoted_database_buf[64*2+3];
|
||||||
|
char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
|
||||||
|
|
||||||
|
fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase);
|
||||||
if (!opt_create_db)
|
if (!opt_create_db)
|
||||||
{
|
{
|
||||||
char qbuf[128];
|
char qbuf[256];
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
MYSQL_RES *dbinfo;
|
MYSQL_RES *dbinfo;
|
||||||
|
|
||||||
sprintf(qbuf,"SHOW CREATE DATABASE WITH IF NOT EXISTS %s",database);
|
sprintf(qbuf,"SHOW CREATE DATABASE WITH IF NOT EXISTS %s",
|
||||||
|
qdatabase);
|
||||||
|
|
||||||
if (mysql_query(sock, qbuf) || !(dbinfo = mysql_store_result(sock)))
|
if (mysql_query(sock, qbuf) || !(dbinfo = mysql_store_result(sock)))
|
||||||
{
|
{
|
||||||
/* Old server version, dump generic CREATE DATABASE */
|
/* Old server version, dump generic CREATE DATABASE */
|
||||||
fprintf(md_result_file,
|
fprintf(md_result_file,
|
||||||
"\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s%s%s;\n",
|
"\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n",
|
||||||
(opt_quoted ? "`" : ""),
|
qdatabase);
|
||||||
database,
|
|
||||||
(opt_quoted ? "`" : ""));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1547,18 +1555,16 @@ static int init_dumping(char *database)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(md_result_file,"\nUSE %s%s%s;\n", (opt_quoted ? "`" : ""),
|
fprintf(md_result_file,"\nUSE %s;\n", qdatabase);
|
||||||
database,
|
|
||||||
(opt_quoted ? "`" : ""));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (extended_insert)
|
if (extended_insert && init_dynamic_string(&extended_row, "", 1024, 1024))
|
||||||
if (init_dynamic_string(&extended_row, "", 1024, 1024))
|
exit(EX_EOM);
|
||||||
exit(EX_EOM);
|
|
||||||
return 0;
|
return 0;
|
||||||
} /* init_dumping */
|
} /* init_dumping */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int dump_all_tables_in_db(char *database)
|
static int dump_all_tables_in_db(char *database)
|
||||||
{
|
{
|
||||||
char *table;
|
char *table;
|
||||||
|
@ -731,7 +731,7 @@ AC_CHECK_HEADERS(fcntl.h float.h floatingpoint.h ieeefp.h limits.h \
|
|||||||
strings.h string.h synch.h sys/mman.h sys/socket.h netinet/in.h arpa/inet.h \
|
strings.h string.h synch.h sys/mman.h sys/socket.h netinet/in.h arpa/inet.h \
|
||||||
sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
|
sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
|
||||||
unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \
|
unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \
|
||||||
sys/ioctl.h)
|
sys/ioctl.h malloc.h sys/malloc.h)
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# Check for system libraries. Adds the library to $LIBS
|
# Check for system libraries. Adds the library to $LIBS
|
||||||
@ -1832,7 +1832,7 @@ AC_CHECK_FUNCS(alarm bmove \
|
|||||||
pthread_attr_create pthread_getsequence_np pthread_attr_setstacksize \
|
pthread_attr_create pthread_getsequence_np pthread_attr_setstacksize \
|
||||||
pthread_attr_getstacksize \
|
pthread_attr_getstacksize \
|
||||||
pthread_condattr_create rwlock_init pthread_rwlock_rdlock \
|
pthread_condattr_create rwlock_init pthread_rwlock_rdlock \
|
||||||
fchmod getpass getpassphrase initgroups mlockall)
|
fsync fdatasync fchmod getpass getpassphrase initgroups mlockall)
|
||||||
|
|
||||||
CFLAGS="$ORG_CFLAGS"
|
CFLAGS="$ORG_CFLAGS"
|
||||||
|
|
||||||
|
@ -36,10 +36,6 @@
|
|||||||
extern int h_errno;
|
extern int h_errno;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_IN_ADDR_T
|
|
||||||
#define in_addr_t ulong
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static my_bool silent;
|
static my_bool silent;
|
||||||
|
|
||||||
static struct my_option my_long_options[] =
|
static struct my_option my_long_options[] =
|
||||||
|
@ -183,8 +183,8 @@ inline double rint(double nr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
#define ulonglong2double(A) ((double) (A))
|
#define ulonglong2double(A) ((double) (ulonglong) (A))
|
||||||
#define my_off_t2double(A) ((double) (A))
|
#define my_off_t2double(A) ((double) (my_off_t) (A))
|
||||||
|
|
||||||
#else
|
#else
|
||||||
inline double ulonglong2double(ulonglong value)
|
inline double ulonglong2double(ulonglong value)
|
||||||
|
@ -594,8 +594,8 @@ extern double my_atof(const char*);
|
|||||||
#define closesocket(A) close(A)
|
#define closesocket(A) close(A)
|
||||||
#endif
|
#endif
|
||||||
#ifndef ulonglong2double
|
#ifndef ulonglong2double
|
||||||
#define ulonglong2double(A) ((double) (A))
|
#define ulonglong2double(A) ((double) (ulonglong) (A))
|
||||||
#define my_off_t2double(A) ((double) (A))
|
#define my_off_t2double(A) ((double) (my_off_t) (A))
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -63,6 +63,15 @@ C_MODE_START
|
|||||||
#define O_NONBLOCK 1 /* For emulation of fcntl() */
|
#define O_NONBLOCK 1 /* For emulation of fcntl() */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
On OSes which don't have the in_addr_t, we guess that using uint32 is the best
|
||||||
|
possible choice. We guess this from the fact that on HP-UX64bit & FreeBSD64bit
|
||||||
|
& Solaris64bit, in_addr_t is equivalent to uint32. And on Linux32bit too.
|
||||||
|
*/
|
||||||
|
#ifndef HAVE_IN_ADDR_T
|
||||||
|
#define in_addr_t uint32
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Thread safe or portable version of some functions */
|
/* Thread safe or portable version of some functions */
|
||||||
|
|
||||||
void my_inet_ntoa(struct in_addr in, char *buf);
|
void my_inet_ntoa(struct in_addr in, char *buf);
|
||||||
|
@ -645,6 +645,7 @@ struct st_my_thread_var
|
|||||||
long id;
|
long id;
|
||||||
int cmp_length;
|
int cmp_length;
|
||||||
int volatile abort;
|
int volatile abort;
|
||||||
|
my_bool init;
|
||||||
struct st_my_thread_var *next,**prev;
|
struct st_my_thread_var *next,**prev;
|
||||||
void *opt_info;
|
void *opt_info;
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
|
@ -614,6 +614,7 @@ extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags);
|
|||||||
extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
|
extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
|
||||||
extern int my_fclose(FILE *fd,myf MyFlags);
|
extern int my_fclose(FILE *fd,myf MyFlags);
|
||||||
extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
|
extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
|
||||||
|
extern int my_sync(File fd, myf my_flags);
|
||||||
extern int my_error _VARARGS((int nr,myf MyFlags, ...));
|
extern int my_error _VARARGS((int nr,myf MyFlags, ...));
|
||||||
extern int my_printf_error _VARARGS((uint my_err, const char *format,
|
extern int my_printf_error _VARARGS((uint my_err, const char *format,
|
||||||
myf MyFlags, ...)
|
myf MyFlags, ...)
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
#if defined(__WIN__) && !defined( _CUSTOMCONFIG_)
|
#if defined(__WIN__) && !defined( _CUSTOMCONFIG_)
|
||||||
#define MYSQL_NAMEDPIPE "MySQL"
|
#define MYSQL_NAMEDPIPE "MySQL"
|
||||||
#define MYSQL_SERVICENAME "MySql"
|
#define MYSQL_SERVICENAME "MySQL"
|
||||||
#endif /* __WIN__ */
|
#endif /* __WIN__ */
|
||||||
|
|
||||||
enum enum_server_command
|
enum enum_server_command
|
||||||
|
@ -21,7 +21,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GLOB 0 /* Error maps */
|
#define GLOB 0 /* Error maps */
|
||||||
#define GLOBERRS 27 /* Max number of error messages in map's */
|
#define GLOBERRS 28 /* Max number of error messages in map's */
|
||||||
#define EE(X) globerrs[ X ] /* Defines to add error to right map */
|
#define EE(X) globerrs[ X ] /* Defines to add error to right map */
|
||||||
|
|
||||||
extern const char * NEAR globerrs[]; /* my_error_messages is here */
|
extern const char * NEAR globerrs[]; /* my_error_messages is here */
|
||||||
@ -53,6 +53,7 @@ extern const char * NEAR globerrs[]; /* my_error_messages is here */
|
|||||||
#define EE_CANT_READLINK 24
|
#define EE_CANT_READLINK 24
|
||||||
#define EE_CANT_SYMLINK 25
|
#define EE_CANT_SYMLINK 25
|
||||||
#define EE_REALPATH 26
|
#define EE_REALPATH 26
|
||||||
|
#define EE_SYNC 27
|
||||||
|
|
||||||
/* exit codes for all MySQL programs */
|
/* exit codes for all MySQL programs */
|
||||||
|
|
||||||
|
@ -3095,7 +3095,15 @@ consecutive_loop:
|
|||||||
/* Do the i/o with ordinary, synchronous i/o functions: */
|
/* Do the i/o with ordinary, synchronous i/o functions: */
|
||||||
if (slot->type == OS_FILE_WRITE) {
|
if (slot->type == OS_FILE_WRITE) {
|
||||||
if (array == os_aio_write_array) {
|
if (array == os_aio_write_array) {
|
||||||
|
if ((total_len % UNIV_PAGE_SIZE != 0)
|
||||||
|
|| (slot->offset % UNIV_PAGE_SIZE != 0)) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"InnoDB: Error: trying a displaced write to %s %lu %lu, len %lu\n",
|
||||||
|
slot->name, slot->offset_high,
|
||||||
|
slot->offset, total_len);
|
||||||
|
ut_a(0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Do a 'last millisecond' check that the page end
|
/* Do a 'last millisecond' check that the page end
|
||||||
is sensible; reported page checksum errors from
|
is sensible; reported page checksum errors from
|
||||||
Linux seem to wipe over the page end */
|
Linux seem to wipe over the page end */
|
||||||
|
@ -3287,14 +3287,14 @@ rec_loop:
|
|||||||
latest version of the record */
|
latest version of the record */
|
||||||
|
|
||||||
} else if (index == clust_index) {
|
} else if (index == clust_index) {
|
||||||
|
|
||||||
/* Fetch a previous version of the row if the current
|
/* Fetch a previous version of the row if the current
|
||||||
one is not visible in the snapshot; if we have a very
|
one is not visible in the snapshot; if we have a very
|
||||||
high force recovery level set, we try to avoid crashes
|
high force recovery level set, we try to avoid crashes
|
||||||
by skipping this lookup */
|
by skipping this lookup */
|
||||||
|
|
||||||
if (srv_force_recovery < 5
|
if (srv_force_recovery < 5
|
||||||
&& !lock_clust_rec_cons_read_sees(rec, index,
|
&& !lock_clust_rec_cons_read_sees(rec, index,
|
||||||
trx->read_view)) {
|
trx->read_view)) {
|
||||||
|
|
||||||
err = row_sel_build_prev_vers_for_mysql(
|
err = row_sel_build_prev_vers_for_mysql(
|
||||||
|
@ -1717,7 +1717,7 @@ srv_init(void)
|
|||||||
os_fast_mutex_init(&srv_conc_mutex);
|
os_fast_mutex_init(&srv_conc_mutex);
|
||||||
|
|
||||||
UT_LIST_INIT(srv_conc_queue);
|
UT_LIST_INIT(srv_conc_queue);
|
||||||
|
|
||||||
srv_conc_slots = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_conc_slot_t));
|
srv_conc_slots = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_conc_slot_t));
|
||||||
|
|
||||||
for (i = 0; i < OS_THREAD_MAX_N; i++) {
|
for (i = 0; i < OS_THREAD_MAX_N; i++) {
|
||||||
|
@ -1164,6 +1164,28 @@ NetWare. */
|
|||||||
/* Note that the call srv_boot() also changes the values of
|
/* Note that the call srv_boot() also changes the values of
|
||||||
srv_pool_size etc. to the units used by InnoDB internally */
|
srv_pool_size etc. to the units used by InnoDB internally */
|
||||||
|
|
||||||
|
/* Set the maximum number of threads which can wait for a semaphore
|
||||||
|
inside InnoDB */
|
||||||
|
#if defined(__WIN__) || defined(__NETWARE__)
|
||||||
|
|
||||||
|
/* Create less event semaphores because Win 98/ME had difficulty creating
|
||||||
|
40000 event semaphores.
|
||||||
|
Comment from Novell, Inc.: also, these just take a lot of memory on
|
||||||
|
NetWare. */
|
||||||
|
srv_max_n_threads = 1000;
|
||||||
|
#else
|
||||||
|
if (srv_pool_size >= 8 * 1024 * 1024) {
|
||||||
|
/* Here we still have srv_pool_size counted
|
||||||
|
in bytes, srv_boot converts the value to
|
||||||
|
pages; if buffer pool is less than 8 MB,
|
||||||
|
assume fewer threads. */
|
||||||
|
srv_max_n_threads = 10000;
|
||||||
|
} else {
|
||||||
|
srv_max_n_threads = 1000; /* saves several MB of memory,
|
||||||
|
especially in 64-bit
|
||||||
|
computers */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
err = srv_boot();
|
err = srv_boot();
|
||||||
|
|
||||||
if (err != DB_SUCCESS) {
|
if (err != DB_SUCCESS) {
|
||||||
|
10
isam/extra.c
10
isam/extra.c
@ -250,17 +250,15 @@ int nisam_extra(N_INFO *info, enum ha_extra_function function)
|
|||||||
pthread_mutex_unlock(&THR_LOCK_isam);
|
pthread_mutex_unlock(&THR_LOCK_isam);
|
||||||
break;
|
break;
|
||||||
case HA_EXTRA_FLUSH:
|
case HA_EXTRA_FLUSH:
|
||||||
#ifdef __WIN__
|
|
||||||
if (info->s->not_flushed)
|
if (info->s->not_flushed)
|
||||||
{
|
{
|
||||||
info->s->not_flushed=0;
|
info->s->not_flushed=0;
|
||||||
if (_commit(info->s->kfile))
|
if (my_sync(info->s->kfile, MYF(0)))
|
||||||
error=errno;
|
error= my_errno;
|
||||||
if (_commit(info->dfile))
|
if (my_sync(info->dfile, MYF(0)))
|
||||||
error=errno;
|
error= my_errno;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
case HA_EXTRA_NORMAL: /* Theese isn't in use */
|
case HA_EXTRA_NORMAL: /* Theese isn't in use */
|
||||||
case HA_EXTRA_QUICK:
|
case HA_EXTRA_QUICK:
|
||||||
case HA_EXTRA_KEY_CACHE:
|
case HA_EXTRA_KEY_CACHE:
|
||||||
|
@ -90,7 +90,7 @@ MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con,
|
|||||||
{
|
{
|
||||||
my_socket sock;
|
my_socket sock;
|
||||||
struct sockaddr_in sock_addr;
|
struct sockaddr_in sock_addr;
|
||||||
uint32 ip_addr;
|
in_addr_t ip_addr;
|
||||||
char msg_buf[MAX_MYSQL_MANAGER_MSG];
|
char msg_buf[MAX_MYSQL_MANAGER_MSG];
|
||||||
int msg_len;
|
int msg_len;
|
||||||
Vio* vio;
|
Vio* vio;
|
||||||
|
@ -92,10 +92,10 @@ libmysqld.a: libmysqld_int.a $(INC_LIB)
|
|||||||
ar x $$file; \
|
ar x $$file; \
|
||||||
for obj in *.o ; do mv $$obj $${bfile}_$$obj ; done ; \
|
for obj in *.o ; do mv $$obj $${bfile}_$$obj ; done ; \
|
||||||
ar q ../libmysqld_int2.a *.o ; \
|
ar q ../libmysqld_int2.a *.o ; \
|
||||||
rm *.o ; \
|
rm -f *.o ; \
|
||||||
done
|
done
|
||||||
mv libmysqld_int2.a libmysqld.a
|
mv libmysqld_int2.a libmysqld.a
|
||||||
rm tmp/*
|
rm -f tmp/*
|
||||||
$(RANLIB) libmysqld.a
|
$(RANLIB) libmysqld.a
|
||||||
|
|
||||||
## XXX: any time the client interface changes, we'll need to bump
|
## XXX: any time the client interface changes, we'll need to bump
|
||||||
|
@ -362,7 +362,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
|
|||||||
Hack: instead of init_queue, we'll use reinit queue to be able
|
Hack: instead of init_queue, we'll use reinit queue to be able
|
||||||
to alloc queue with alloc_root()
|
to alloc queue with alloc_root()
|
||||||
*/
|
*/
|
||||||
res=ftb->queue.max_elements=1+query_len/(ft_min_word_len+1);
|
res=ftb->queue.max_elements=1+query_len/(min(ft_min_word_len,2)+1);
|
||||||
ftb->queue.root=(byte **)alloc_root(&ftb->mem_root, (res+1)*sizeof(void*));
|
ftb->queue.root=(byte **)alloc_root(&ftb->mem_root, (res+1)*sizeof(void*));
|
||||||
reinit_queue(& ftb->queue, res, 0, 0,
|
reinit_queue(& ftb->queue, res, 0, 0,
|
||||||
(int (*)(void*,byte*,byte*))FTB_WORD_cmp, 0);
|
(int (*)(void*,byte*,byte*))FTB_WORD_cmp, 0);
|
||||||
|
@ -336,22 +336,10 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
|
|||||||
if (share->not_flushed)
|
if (share->not_flushed)
|
||||||
{
|
{
|
||||||
share->not_flushed=0;
|
share->not_flushed=0;
|
||||||
#if defined(__WIN__)
|
if (my_sync(share->kfile, MYF(0)))
|
||||||
if (_commit(share->kfile))
|
error= my_errno;
|
||||||
error=errno;
|
if (my_sync(info->dfile, MYF(0)))
|
||||||
if (_commit(info->dfile))
|
error= my_errno;
|
||||||
error=errno;
|
|
||||||
#elif defined(HAVE_FDATASYNC)
|
|
||||||
if (fdatasync(share->kfile))
|
|
||||||
error=errno;
|
|
||||||
if (fdatasync(share->dfile))
|
|
||||||
error=errno;
|
|
||||||
#elif defined(HAVE_FSYNC)
|
|
||||||
if ( fsync(share->kfile))
|
|
||||||
error=errno;
|
|
||||||
if (fsync(share->dfile))
|
|
||||||
error=errno;
|
|
||||||
#endif
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
share->changed=1;
|
share->changed=1;
|
||||||
|
@ -98,22 +98,10 @@ int mi_lock_database(MI_INFO *info, int lock_type)
|
|||||||
share->changed=0;
|
share->changed=0;
|
||||||
if (myisam_flush)
|
if (myisam_flush)
|
||||||
{
|
{
|
||||||
#if defined(__WIN__)
|
if (my_sync(share->kfile, MYF(0)))
|
||||||
if (_commit(share->kfile))
|
error= my_errno;
|
||||||
error=errno;
|
if (my_sync(info->dfile, MYF(0)))
|
||||||
if (_commit(info->dfile))
|
error= my_errno;
|
||||||
error=errno;
|
|
||||||
#elif defined(HAVE_FDATASYNC)
|
|
||||||
if (fdatasync(share->kfile))
|
|
||||||
error=errno;
|
|
||||||
if (fdatasync(share->dfile))
|
|
||||||
error=errno;
|
|
||||||
#elif defined(HAVE_FSYNC)
|
|
||||||
if (fsync(share->kfile))
|
|
||||||
error=errno;
|
|
||||||
if (fsync(share->dfile))
|
|
||||||
error=errno;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
share->not_flushed=1;
|
share->not_flushed=1;
|
||||||
|
@ -411,6 +411,8 @@ static void usage(void)
|
|||||||
-q, --quick Faster repair by not modifying the data file.\n\
|
-q, --quick Faster repair by not modifying the data file.\n\
|
||||||
One can give a second '-q' to force myisamchk to\n\
|
One can give a second '-q' to force myisamchk to\n\
|
||||||
modify the original datafile in case of duplicate keys.\n\
|
modify the original datafile in case of duplicate keys.\n\
|
||||||
|
NOTE: Tables where the data file is currupted can't be\n\
|
||||||
|
fixed with this option.\n\
|
||||||
-u, --unpack Unpack file packed with myisampack.\n\
|
-u, --unpack Unpack file packed with myisampack.\n\
|
||||||
");
|
");
|
||||||
|
|
||||||
@ -1109,7 +1111,7 @@ end2:
|
|||||||
filename));
|
filename));
|
||||||
if (param->testflag & T_REP_ANY)
|
if (param->testflag & T_REP_ANY)
|
||||||
VOID(fprintf(stderr,
|
VOID(fprintf(stderr,
|
||||||
"Try fixing it by using the --safe-recover (-o) or the --force (-f) option\n"));
|
"Try fixing it by using the --safe-recover (-o), the --force (-f) option or by not using the --quick (-q) flag\n"));
|
||||||
}
|
}
|
||||||
else if (!(param->error_printed & 2) &&
|
else if (!(param->error_printed & 2) &&
|
||||||
!(param->testflag & T_FORCE_CREATE))
|
!(param->testflag & T_FORCE_CREATE))
|
||||||
|
@ -338,7 +338,13 @@ while test $# -gt 0; do
|
|||||||
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --gdb"
|
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --gdb"
|
||||||
;;
|
;;
|
||||||
--valgrind)
|
--valgrind)
|
||||||
VALGRIND="valgrind --alignment=8 --leak-check=yes --num-callers=16"
|
VALGRIND=`which valgrind` # this will print an error if not found
|
||||||
|
# Give good warning to the user and stop
|
||||||
|
if [ -z "$VALGRIND" ] ; then
|
||||||
|
$ECHO "You need to have the 'valgrind' program in your PATH to run mysql-test-run with option --valgrind. Valgrind's home page is http://developer.kde.org/~sewardj ."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
VALGRIND="$VALGRIND --alignment=8 --leak-check=yes --num-callers=16"
|
||||||
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-safemalloc --skip-bdb"
|
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-safemalloc --skip-bdb"
|
||||||
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-safemalloc --skip-bdb"
|
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-safemalloc --skip-bdb"
|
||||||
SLEEP_TIME_AFTER_RESTART=10
|
SLEEP_TIME_AFTER_RESTART=10
|
||||||
@ -349,6 +355,9 @@ while test $# -gt 0; do
|
|||||||
TMP=`$ECHO "$1" | $SED -e "s;--valgrind-options=;;"`
|
TMP=`$ECHO "$1" | $SED -e "s;--valgrind-options=;;"`
|
||||||
VALGRIND="$VALGRIND $TMP"
|
VALGRIND="$VALGRIND $TMP"
|
||||||
;;
|
;;
|
||||||
|
--valgrind-all)
|
||||||
|
VALGRIND="$VALGRIND -v --show-reachable=yes"
|
||||||
|
;;
|
||||||
--skip-*)
|
--skip-*)
|
||||||
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT $1"
|
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT $1"
|
||||||
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT $1"
|
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT $1"
|
||||||
@ -1163,7 +1172,7 @@ run_testcase ()
|
|||||||
echo $tname > $CURRENT_TEST
|
echo $tname > $CURRENT_TEST
|
||||||
SKIP_SLAVE=`$EXPR \( $tname : rpl \) = 0`
|
SKIP_SLAVE=`$EXPR \( $tname : rpl \) = 0`
|
||||||
if [ $USE_MANAGER = 1 ] ; then
|
if [ $USE_MANAGER = 1 ] ; then
|
||||||
many_slaves=`$EXPR \( $tname : rpl_failsafe \) != 0`
|
many_slaves=`$EXPR \( \( $tname : rpl_failsafe \) != 0 \) \| \( \( $tname : rpl_chain_temp_table \) != 0 \)`
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$SKIP_TEST" ] ; then
|
if [ -n "$SKIP_TEST" ] ; then
|
||||||
|
@ -297,6 +297,8 @@ insert into t2 values (3, 1, 'xxbuz');
|
|||||||
select * from t1 join t2 using(`t1_id`) where match (t1.name, t2.name) against('xxfoo' in boolean mode);
|
select * from t1 join t2 using(`t1_id`) where match (t1.name, t2.name) against('xxfoo' in boolean mode);
|
||||||
t1_id name t2_id t1_id name
|
t1_id name t2_id t1_id name
|
||||||
1 data1 1 1 xxfoo
|
1 data1 1 1 xxfoo
|
||||||
|
select * from t2 where match name against ('a* b* c* d* e* f*' in boolean mode);
|
||||||
|
t2_id t1_id name
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
SET NAMES latin1;
|
SET NAMES latin1;
|
||||||
CREATE TABLE t1 (t text character set utf8 not null, fulltext(t));
|
CREATE TABLE t1 (t text character set utf8 not null, fulltext(t));
|
||||||
|
@ -1,6 +1,16 @@
|
|||||||
|
drop table if exists t1;
|
||||||
select length(encrypt('foo', 'ff')) <> 0;
|
select length(encrypt('foo', 'ff')) <> 0;
|
||||||
length(encrypt('foo', 'ff')) <> 0
|
length(encrypt('foo', 'ff')) <> 0
|
||||||
1
|
1
|
||||||
|
create table t1 (name varchar(50), pw varchar(16));
|
||||||
|
insert into t1 values ('tom', password('my_pass'));
|
||||||
|
set @pass='my_pass';
|
||||||
|
select name from t1 where name='tom' and pw=password(@pass);
|
||||||
|
name
|
||||||
|
tom
|
||||||
|
select name from t1 where name='tom' and pw=password(@undefined);
|
||||||
|
name
|
||||||
|
drop table t1;
|
||||||
select password('abc');
|
select password('abc');
|
||||||
password('abc')
|
password('abc')
|
||||||
*0D3CED9BEC10A777AEC23CCC353A8C08A633045E
|
*0D3CED9BEC10A777AEC23CCC353A8C08A633045E
|
||||||
|
@ -306,17 +306,17 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE t1 range a a 9 NULL 8 Using where; Using index
|
1 SIMPLE t1 range a a 9 NULL 8 Using where; Using index
|
||||||
explain select * from t1 where a = 2 and b >0 order by a desc,b desc;
|
explain select * from t1 where a = 2 and b >0 order by a desc,b desc;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range a a 9 NULL 5 Using where; Using index
|
1 SIMPLE t1 range a a 9 NULL 4 Using where; Using index
|
||||||
explain select * from t1 where a = 2 and b is null order by a desc,b desc;
|
explain select * from t1 where a = 2 and b is null order by a desc,b desc;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 ref a a 9 const,const 1 Using where; Using index; Using filesort
|
1 SIMPLE t1 ref a a 9 const,const 1 Using where; Using index; Using filesort
|
||||||
explain select * from t1 where a = 2 and (b is null or b > 0) order by a
|
explain select * from t1 where a = 2 and (b is null or b > 0) order by a
|
||||||
desc,b desc;
|
desc,b desc;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range a a 9 NULL 6 Using where; Using index
|
1 SIMPLE t1 range a a 9 NULL 5 Using where; Using index
|
||||||
explain select * from t1 where a = 2 and b > 0 order by a desc,b desc;
|
explain select * from t1 where a = 2 and b > 0 order by a desc,b desc;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range a a 9 NULL 5 Using where; Using index
|
1 SIMPLE t1 range a a 9 NULL 4 Using where; Using index
|
||||||
explain select * from t1 where a = 2 and b < 2 order by a desc,b desc;
|
explain select * from t1 where a = 2 and b < 2 order by a desc,b desc;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range a a 9 NULL 2 Using where; Using index
|
1 SIMPLE t1 range a a 9 NULL 2 Using where; Using index
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
|
set GLOBAL query_cache_size=1355776;
|
||||||
flush query cache;
|
flush query cache;
|
||||||
flush query cache;
|
flush query cache;
|
||||||
reset query cache;
|
reset query cache;
|
||||||
flush status;
|
flush status;
|
||||||
drop table if exists t1,t2,t3;
|
drop table if exists t1,t2,t3,t4,t11,t21;
|
||||||
drop database if exists mysqltest;
|
drop database if exists mysqltest;
|
||||||
create table t1 (a int not null);
|
create table t1 (a int not null);
|
||||||
insert into t1 values (1),(2),(3);
|
insert into t1 values (1),(2),(3);
|
||||||
@ -722,6 +723,46 @@ Variable_name Value
|
|||||||
Qcache_queries_in_cache 2
|
Qcache_queries_in_cache 2
|
||||||
SET OPTION SQL_SELECT_LIMIT=DEFAULT;
|
SET OPTION SQL_SELECT_LIMIT=DEFAULT;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
flush query cache;
|
||||||
|
reset query cache;
|
||||||
|
flush status;
|
||||||
|
set GLOBAL query_cache_size=1048576;
|
||||||
|
create table t1 (a int not null);
|
||||||
|
insert into t1 values (1),(2),(3);
|
||||||
|
create table t2 (a text not null);
|
||||||
|
create table t3 (a text not null);
|
||||||
|
insert into t3 values("1111111111111111111111111111111111111111111111111111");
|
||||||
|
insert into t2 select * from t3;
|
||||||
|
insert into t3 select * from t2;
|
||||||
|
insert into t2 select * from t3;
|
||||||
|
insert into t3 select * from t2;
|
||||||
|
insert into t2 select * from t3;
|
||||||
|
insert into t3 select * from t2;
|
||||||
|
insert into t2 select * from t3;
|
||||||
|
insert into t3 select * from t2;
|
||||||
|
insert into t2 select * from t3;
|
||||||
|
insert into t3 select * from t2;
|
||||||
|
drop table t2;
|
||||||
|
create table t2 (a int not null);
|
||||||
|
insert into t2 values (1),(2),(3);
|
||||||
|
create table t4 (a int not null);
|
||||||
|
insert into t4 values (1),(2),(3);
|
||||||
|
select * from t4;
|
||||||
|
select * from t2;
|
||||||
|
select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
|
||||||
|
select * from t2;
|
||||||
|
select * from t4;
|
||||||
|
select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
|
||||||
|
select * from t2;
|
||||||
|
select * from t4;
|
||||||
|
select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
|
||||||
|
delete from t2 where a=1;
|
||||||
|
flush query cache;
|
||||||
|
select * from t3;
|
||||||
|
delete from t4 where a=1;
|
||||||
|
flush query cache;
|
||||||
|
drop table t1,t2,t3,t4;
|
||||||
|
set GLOBAL query_cache_size=0;
|
||||||
SET NAMES koi8r;
|
SET NAMES koi8r;
|
||||||
CREATE TABLE t1 (a char(1) character set koi8r);
|
CREATE TABLE t1 (a char(1) character set koi8r);
|
||||||
INSERT INTO t1 VALUES (_koi8r'á'),(_koi8r'Á');
|
INSERT INTO t1 VALUES (_koi8r'á'),(_koi8r'Á');
|
||||||
|
@ -262,6 +262,23 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE t2 ref j1 j1 4 const 1 Using where; Using index
|
1 SIMPLE t2 ref j1 j1 4 const 1 Using where; Using index
|
||||||
1 SIMPLE t1 ALL i2 NULL NULL NULL 4 Range checked for each record (index map: 0x2)
|
1 SIMPLE t1 ALL i2 NULL NULL NULL 4 Range checked for each record (index map: 0x2)
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a int(11) default NULL,
|
||||||
|
b int(11) default NULL,
|
||||||
|
KEY a (a),
|
||||||
|
KEY b (b)
|
||||||
|
) TYPE=MyISAM;
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
(1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,2),(10,2),
|
||||||
|
(13,2),(14,2),(15,2),(16,2),(17,3),(17,3),(16,3),(17,3),(19,3),(20,3),
|
||||||
|
(21,4),(22,5),(23,5),(24,5),(25,5),(26,5),(30,5),(31,5),(32,5),(33,5),
|
||||||
|
(33,5),(33,5),(33,5),(33,5),(34,5),(35,5);
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
|
||||||
|
table type possible_keys key key_len ref rows Extra
|
||||||
|
t1 range a,b a 5 NULL 2 Using where
|
||||||
|
SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
|
||||||
|
a b
|
||||||
|
DROP TABLE t1;
|
||||||
create table t1 (id int(10) primary key);
|
create table t1 (id int(10) primary key);
|
||||||
insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
|
insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
select id from t1 where id in (2,5,9) ;
|
select id from t1 where id in (2,5,9) ;
|
||||||
|
30
mysql-test/r/rpl_chain_temp_table.result
Normal file
30
mysql-test/r/rpl_chain_temp_table.result
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
slave stop;
|
||||||
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
|
reset master;
|
||||||
|
reset slave;
|
||||||
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
|
slave start;
|
||||||
|
reset master;
|
||||||
|
change master to master_host='127.0.0.1',master_port=9307, master_user='root';
|
||||||
|
start slave;
|
||||||
|
create temporary table t1 (a int);
|
||||||
|
create temporary table t1 (a int);
|
||||||
|
show status like 'slave_open_temp_tables';
|
||||||
|
Variable_name Value
|
||||||
|
Slave_open_temp_tables 2
|
||||||
|
create temporary table t1 (a int);
|
||||||
|
create temporary table t1 (a int);
|
||||||
|
show status like 'slave_open_temp_tables';
|
||||||
|
Variable_name Value
|
||||||
|
Slave_open_temp_tables 4
|
||||||
|
stop slave;
|
||||||
|
insert into t1 values(1);
|
||||||
|
create table t2 as select * from t1;
|
||||||
|
start slave;
|
||||||
|
show status like 'slave_open_temp_tables';
|
||||||
|
Variable_name Value
|
||||||
|
Slave_open_temp_tables 4
|
||||||
|
select * from t2;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
drop table t2;
|
@ -20,3 +20,13 @@ start slave;
|
|||||||
show slave status;
|
show slave status;
|
||||||
Slave_IO_State 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 Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master
|
Slave_IO_State 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 Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master
|
||||||
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000002 123 master-bin.000001 Yes Yes 0 0 79 123 None 0 No #
|
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000002 123 master-bin.000001 Yes Yes 0 0 79 123 None 0 No #
|
||||||
|
stop slave;
|
||||||
|
reset slave;
|
||||||
|
start slave;
|
||||||
|
create temporary table t1 (a int);
|
||||||
|
stop slave;
|
||||||
|
reset slave;
|
||||||
|
start slave;
|
||||||
|
show status like 'slave_open_temp_tables';
|
||||||
|
Variable_name Value
|
||||||
|
Slave_open_temp_tables 1
|
||||||
|
@ -8,7 +8,8 @@ stop slave;
|
|||||||
flush logs;
|
flush logs;
|
||||||
reset slave;
|
reset slave;
|
||||||
start slave;
|
start slave;
|
||||||
show slave status;
|
|
||||||
Slave_IO_State 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 Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master
|
Slave_IO_State 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 Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master
|
||||||
# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 4 slave-relay-bin.000002 123 master-bin.000001 Yes No 0 Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. Probably cause is that the master died while writing the transaction to it's binary log. 0 79 326 None 0 No #
|
# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 4 slave-relay-bin.000002 123 master-bin.000001 Yes No 0 Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. Probably cause is that the master died while writing the transaction to it's binary log. 0 79 326 None 0 No #
|
||||||
reset master;
|
show slave status;
|
||||||
|
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
|
||||||
|
127.0.0.1 root MASTER_PORT 1 master-bin.002 4 slave-relay-bin.002 161 master-bin.001 Yes No 0 Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. Probably cause is that the master died while writing the transaction to it's binary log. 0 79 317
|
||||||
|
@ -2150,10 +2150,10 @@ a a a
|
|||||||
select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 on t1.a>1;
|
select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 on t1.a>1;
|
||||||
a a a
|
a a a
|
||||||
1 1 2
|
1 1 2
|
||||||
2 2 2
|
|
||||||
3 3 2
|
|
||||||
1 1 3
|
1 1 3
|
||||||
|
2 2 2
|
||||||
2 2 3
|
2 2 3
|
||||||
|
3 3 2
|
||||||
3 3 3
|
3 3 3
|
||||||
select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
|
select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
|
||||||
a a a
|
a a a
|
||||||
|
@ -228,6 +228,12 @@ insert into t2 values (1, 1, 'xxfoo');
|
|||||||
insert into t2 values (2, 1, 'xxbar');
|
insert into t2 values (2, 1, 'xxbar');
|
||||||
insert into t2 values (3, 1, 'xxbuz');
|
insert into t2 values (3, 1, 'xxbuz');
|
||||||
select * from t1 join t2 using(`t1_id`) where match (t1.name, t2.name) against('xxfoo' in boolean mode);
|
select * from t1 join t2 using(`t1_id`) where match (t1.name, t2.name) against('xxfoo' in boolean mode);
|
||||||
|
|
||||||
|
#
|
||||||
|
# bug with many short (< ft_min_word_len) words in boolean search
|
||||||
|
#
|
||||||
|
select * from t2 where match name against ('a* b* c* d* e* f*' in boolean mode);
|
||||||
|
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -1,9 +1,21 @@
|
|||||||
-- source include/have_crypt.inc
|
-- source include/have_crypt.inc
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop table if exists t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
select length(encrypt('foo', 'ff')) <> 0;
|
select length(encrypt('foo', 'ff')) <> 0;
|
||||||
--replace_result $1$aa$4OSUA5cjdx0RUQ08opV27/ aaqPiZY5xR5l.
|
--replace_result $1$aa$4OSUA5cjdx0RUQ08opV27/ aaqPiZY5xR5l.
|
||||||
|
|
||||||
|
create table t1 (name varchar(50), pw varchar(16));
|
||||||
|
insert into t1 values ('tom', password('my_pass'));
|
||||||
|
set @pass='my_pass';
|
||||||
|
select name from t1 where name='tom' and pw=password(@pass);
|
||||||
|
select name from t1 where name='tom' and pw=password(@undefined);
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
# Test new and old password handling functions
|
# Test new and old password handling functions
|
||||||
|
|
||||||
select password('abc');
|
select password('abc');
|
||||||
select password('');
|
select password('');
|
||||||
select old_password('abc');
|
select old_password('abc');
|
||||||
|
@ -1 +0,0 @@
|
|||||||
--set-variable=query_cache_size=1355776
|
|
@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
# Tests with query cache
|
# Tests with query cache
|
||||||
#
|
#
|
||||||
|
set GLOBAL query_cache_size=1355776;
|
||||||
|
|
||||||
# Reset query cache variables.
|
# Reset query cache variables.
|
||||||
|
|
||||||
@ -11,7 +12,7 @@ flush query cache; # This crashed in some versions
|
|||||||
reset query cache;
|
reset query cache;
|
||||||
flush status;
|
flush status;
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
drop table if exists t1,t2,t3;
|
drop table if exists t1,t2,t3,t4,t11,t21;
|
||||||
drop database if exists mysqltest;
|
drop database if exists mysqltest;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
@ -489,6 +490,55 @@ show status like "Qcache_queries_in_cache";
|
|||||||
SET OPTION SQL_SELECT_LIMIT=DEFAULT;
|
SET OPTION SQL_SELECT_LIMIT=DEFAULT;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# query cache crash on using same table twice in one query test
|
||||||
|
#
|
||||||
|
flush query cache;
|
||||||
|
reset query cache;
|
||||||
|
flush status;
|
||||||
|
set GLOBAL query_cache_size=1048576;
|
||||||
|
|
||||||
|
create table t1 (a int not null);
|
||||||
|
insert into t1 values (1),(2),(3);
|
||||||
|
create table t2 (a text not null);
|
||||||
|
create table t3 (a text not null);
|
||||||
|
insert into t3 values("1111111111111111111111111111111111111111111111111111");
|
||||||
|
insert into t2 select * from t3;
|
||||||
|
insert into t3 select * from t2;
|
||||||
|
insert into t2 select * from t3;
|
||||||
|
insert into t3 select * from t2;
|
||||||
|
insert into t2 select * from t3;
|
||||||
|
insert into t3 select * from t2;
|
||||||
|
insert into t2 select * from t3;
|
||||||
|
insert into t3 select * from t2;
|
||||||
|
insert into t2 select * from t3;
|
||||||
|
insert into t3 select * from t2;
|
||||||
|
drop table t2;
|
||||||
|
create table t2 (a int not null);
|
||||||
|
insert into t2 values (1),(2),(3);
|
||||||
|
create table t4 (a int not null);
|
||||||
|
insert into t4 values (1),(2),(3);
|
||||||
|
|
||||||
|
disable_result_log;
|
||||||
|
select * from t4;
|
||||||
|
select * from t2;
|
||||||
|
select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
|
||||||
|
select * from t2;
|
||||||
|
select * from t4;
|
||||||
|
select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
|
||||||
|
select * from t2;
|
||||||
|
select * from t4;
|
||||||
|
select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
|
||||||
|
|
||||||
|
delete from t2 where a=1;
|
||||||
|
flush query cache;
|
||||||
|
select * from t3;
|
||||||
|
enable_result_log;
|
||||||
|
delete from t4 where a=1;
|
||||||
|
flush query cache;
|
||||||
|
|
||||||
|
drop table t1,t2,t3,t4;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test character set related variables:
|
# Test character set related variables:
|
||||||
# character_set_result
|
# character_set_result
|
||||||
@ -535,3 +585,4 @@ show status like "Qcache_queries_in_cache";
|
|||||||
# Keep things tidy
|
# Keep things tidy
|
||||||
#
|
#
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
SET GLOBAL query_cache_size=0;
|
||||||
|
@ -306,3 +306,28 @@ select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
|
|||||||
select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
|
select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
|
||||||
|
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# bug #1724: use RANGE on more selective column instead of REF on less
|
||||||
|
# selective
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a int(11) default NULL,
|
||||||
|
b int(11) default NULL,
|
||||||
|
KEY a (a),
|
||||||
|
KEY b (b)
|
||||||
|
) TYPE=MyISAM;
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
(1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,2),(10,2),
|
||||||
|
(13,2),(14,2),(15,2),(16,2),(17,3),(17,3),(16,3),(17,3),(19,3),(20,3),
|
||||||
|
(21,4),(22,5),(23,5),(24,5),(25,5),(26,5),(30,5),(31,5),(32,5),(33,5),
|
||||||
|
(33,5),(33,5),(33,5),(33,5),(34,5),(35,5);
|
||||||
|
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
|
||||||
|
SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
# we expect that optimizer will choose key on A
|
||||||
|
99
mysql-test/t/rpl_chain_temp_table.test
Normal file
99
mysql-test/t/rpl_chain_temp_table.test
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
# This test makes some assumptions about values of thread ids, which should be
|
||||||
|
# true if the servers have been restarted for this test. So we want to
|
||||||
|
# stop/restart servers. Note that if assumptions are wrong, the test will not
|
||||||
|
# fail; it will just fail to test the error-prone scenario.
|
||||||
|
# Using the manager is the only way to have more than one slave server.
|
||||||
|
# So you must run this test with --manager.
|
||||||
|
|
||||||
|
require_manager;
|
||||||
|
server_stop master;
|
||||||
|
server_start master;
|
||||||
|
server_stop slave;
|
||||||
|
server_start slave;
|
||||||
|
# no need for slave_sec (no assumptions on thread ids for this server).
|
||||||
|
|
||||||
|
source include/master-slave.inc;
|
||||||
|
connect (slave_sec,localhost,root,,test,0,slave.sock-1);
|
||||||
|
connection master;
|
||||||
|
save_master_pos;
|
||||||
|
connection slave;
|
||||||
|
sync_with_master;
|
||||||
|
reset master;
|
||||||
|
save_master_pos;
|
||||||
|
connection slave_sec;
|
||||||
|
eval change master to master_host='127.0.0.1',master_port=$SLAVE_MYPORT, master_user='root';
|
||||||
|
start slave;
|
||||||
|
sync_with_master;
|
||||||
|
|
||||||
|
# :P now we have a chain ready-to-test.
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
create temporary table t1 (a int);
|
||||||
|
save_master_pos;
|
||||||
|
connection slave;
|
||||||
|
sync_with_master;
|
||||||
|
connection master1;
|
||||||
|
create temporary table t1 (a int);
|
||||||
|
save_master_pos;
|
||||||
|
connection slave;
|
||||||
|
sync_with_master;
|
||||||
|
save_master_pos;
|
||||||
|
|
||||||
|
# First test:
|
||||||
|
|
||||||
|
connection slave_sec;
|
||||||
|
# Before BUG#1686 ("If 2 master threads with same-name temp table, slave makes
|
||||||
|
# bad binlog") was fixed, sync_with_master failed
|
||||||
|
sync_with_master;
|
||||||
|
show status like 'slave_open_temp_tables';
|
||||||
|
|
||||||
|
# 'master' and 'master1' usually have thread id 2-3 or 3-4.
|
||||||
|
# 'slave' and 'slave1' usually have thread id 2-3.
|
||||||
|
connection slave;
|
||||||
|
create temporary table t1 (a int);
|
||||||
|
connection slave1;
|
||||||
|
create temporary table t1 (a int);
|
||||||
|
# So it's likely that in the binlog of slave we get
|
||||||
|
# server_id=of_master thread_id=3 create temp...
|
||||||
|
# server_id=of_slave thread_id=3 create temp...
|
||||||
|
# which would confuse slave-sec unless slave-sec uses server id to distinguish
|
||||||
|
# between temp tables (here thread id is obviously not enough to distinguish).
|
||||||
|
|
||||||
|
save_master_pos;
|
||||||
|
|
||||||
|
# Second test:
|
||||||
|
|
||||||
|
connection slave_sec;
|
||||||
|
# If we did not use the server id to distinguish between temp tables,
|
||||||
|
# sync_with_master would fail
|
||||||
|
sync_with_master;
|
||||||
|
show status like 'slave_open_temp_tables';
|
||||||
|
|
||||||
|
# Third test (BUG#1240 "slave of slave breaks when STOP SLAVE was issud on
|
||||||
|
# parent slave and temp tables").
|
||||||
|
stop slave;
|
||||||
|
connection slave;
|
||||||
|
insert into t1 values(1);
|
||||||
|
create table t2 as select * from t1;
|
||||||
|
save_master_pos;
|
||||||
|
connection slave_sec;
|
||||||
|
start slave;
|
||||||
|
sync_with_master;
|
||||||
|
show status like 'slave_open_temp_tables';
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
# clean up
|
||||||
|
connection slave;
|
||||||
|
drop table t2;
|
||||||
|
save_master_pos;
|
||||||
|
connection slave_sec;
|
||||||
|
sync_with_master;
|
||||||
|
|
||||||
|
# On purpose, we don't delete the temporary tables explicitely.
|
||||||
|
# So temp tables remain on slave (remember they are not deleted when the slave
|
||||||
|
# SQL thread terminates). If you run this test with
|
||||||
|
# --valgrind --valgrind-options=--show-reachable=yes
|
||||||
|
# you will see if they get cleaned up at slave's shutdown (that is, if the
|
||||||
|
# memory they use is freed (it should) by mysqld before it terminates).
|
||||||
|
# If they wouldn't be cleaned up, you would see some "still reachable" blocks in
|
||||||
|
# Valgrind.
|
@ -2,6 +2,8 @@
|
|||||||
# --master-* options from mysqld, as this is what is going to be used next time
|
# --master-* options from mysqld, as this is what is going to be used next time
|
||||||
# slave threads will be started). In bug 985, it displayed old values (of before
|
# slave threads will be started). In bug 985, it displayed old values (of before
|
||||||
# RESET SLAVE).
|
# RESET SLAVE).
|
||||||
|
# See if slave crashes when doing a CREATE TEMPORARY TABLE twice, separated by
|
||||||
|
# RESET SLAVE.
|
||||||
|
|
||||||
source include/master-slave.inc;
|
source include/master-slave.inc;
|
||||||
connection master;
|
connection master;
|
||||||
@ -28,3 +30,19 @@ sync_with_master;
|
|||||||
--replace_result $MASTER_MYPORT MASTER_PORT
|
--replace_result $MASTER_MYPORT MASTER_PORT
|
||||||
--replace_column 1 # 33 #
|
--replace_column 1 # 33 #
|
||||||
show slave status;
|
show slave status;
|
||||||
|
|
||||||
|
# test of crash with temp tables & RESET SLAVE
|
||||||
|
# (test to see if RESET SLAVE clears temp tables in memory and disk)
|
||||||
|
stop slave;
|
||||||
|
reset slave;
|
||||||
|
start slave;
|
||||||
|
connection master;
|
||||||
|
create temporary table t1 (a int);
|
||||||
|
save_master_pos;
|
||||||
|
connection slave;
|
||||||
|
sync_with_master;
|
||||||
|
stop slave;
|
||||||
|
reset slave;
|
||||||
|
start slave;
|
||||||
|
sync_with_master;
|
||||||
|
show status like 'slave_open_temp_tables';
|
||||||
|
@ -23,5 +23,3 @@ sleep 3;
|
|||||||
--replace_result $MASTER_MYPORT MASTER_PORT
|
--replace_result $MASTER_MYPORT MASTER_PORT
|
||||||
--replace_column 1 # 33 #
|
--replace_column 1 # 33 #
|
||||||
show slave status;
|
show slave status;
|
||||||
connection master;
|
|
||||||
reset master;
|
|
||||||
|
@ -47,7 +47,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 \
|
||||||
my_getopt.c my_mkdir.c \
|
my_sync.c my_getopt.c my_mkdir.c \
|
||||||
default.c my_compress.c checksum.c raid.cc \
|
default.c my_compress.c checksum.c raid.cc \
|
||||||
my_net.c my_semaphore.c my_port.c my_sleep.c \
|
my_net.c my_semaphore.c my_port.c my_sleep.c \
|
||||||
charset.c charset-def.c my_bitmap.c my_bit.c md5.c \
|
charset.c charset-def.c my_bitmap.c my_bit.c md5.c \
|
||||||
|
@ -48,6 +48,7 @@ const char * NEAR globerrs[GLOBERRS]=
|
|||||||
"Can't read value for symlink '%s' (Error %d)",
|
"Can't read value for symlink '%s' (Error %d)",
|
||||||
"Can't create symlink '%s' pointing at '%s' (Error %d)",
|
"Can't create symlink '%s' pointing at '%s' (Error %d)",
|
||||||
"Error on realpath() on '%s' (Error %d)",
|
"Error on realpath() on '%s' (Error %d)",
|
||||||
|
"Can't sync file '%s' to disk (Errcode: %d)",
|
||||||
};
|
};
|
||||||
|
|
||||||
void init_glob_errs(void)
|
void init_glob_errs(void)
|
||||||
@ -84,8 +85,9 @@ void init_glob_errs()
|
|||||||
EE(EE_CANT_MKDIR) ="Can't create directory '%s' (Errcode: %d)";
|
EE(EE_CANT_MKDIR) ="Can't create directory '%s' (Errcode: %d)";
|
||||||
EE(EE_UNKNOWN_CHARSET)= "Character set '%s' is not a compiled character set and is not specified in the %s file";
|
EE(EE_UNKNOWN_CHARSET)= "Character set '%s' is not a compiled character set and is not specified in the %s file";
|
||||||
EE(EE_OUT_OF_FILERESOURCES)="Out of resources when opening file '%s' (Errcode: %d)";
|
EE(EE_OUT_OF_FILERESOURCES)="Out of resources when opening file '%s' (Errcode: %d)";
|
||||||
EE(EE_CANT_READLINK)="Can't read value for symlink '%s' (Error %d)";
|
EE(EE_CANT_READLINK)= "Can't read value for symlink '%s' (Error %d)";
|
||||||
EE(EE_CANT_SYMLINK)="Can't create symlink '%s' pointing at '%s' (Error %d)";
|
EE(EE_CANT_SYMLINK)= "Can't create symlink '%s' pointing at '%s' (Error %d)";
|
||||||
EE(EE_REALPATH)="Error on realpath() on '%s' (Error %d)";
|
EE(EE_REALPATH)= "Error on realpath() on '%s' (Error %d)";
|
||||||
|
EE(EE_SYNC)= "Can't sync file '%s' to disk (Errcode: %d)";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -25,12 +25,12 @@
|
|||||||
|
|
||||||
void *operator new (size_t sz)
|
void *operator new (size_t sz)
|
||||||
{
|
{
|
||||||
return (void *) malloc (sz ? sz+1 : sz);
|
return (void *) malloc (sz ? sz : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *operator new[] (size_t sz)
|
void *operator new[] (size_t sz)
|
||||||
{
|
{
|
||||||
return (void *) malloc (sz ? sz+1 : sz);
|
return (void *) malloc (sz ? sz : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete (void *ptr)
|
void operator delete (void *ptr)
|
||||||
|
60
mysys/my_sync.c
Normal file
60
mysys/my_sync.c
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/* Copyright (C) 2003 MySQL 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 "mysys_priv.h"
|
||||||
|
#include "mysys_err.h"
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sync data in file to disk
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_sync()
|
||||||
|
fd File descritor to sync
|
||||||
|
my_flags Flags (now only MY_WME is supported)
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
If file system supports its, only file data is synced, not inode date
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
-1 error
|
||||||
|
*/
|
||||||
|
|
||||||
|
int my_sync(File fd, myf my_flags)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
DBUG_ENTER("my_sync");
|
||||||
|
DBUG_PRINT("my",("Fd: %d my_flags: %d", fd, my_flags));
|
||||||
|
|
||||||
|
#if defined(HAVE_FDATASYNC)
|
||||||
|
res= fdatasync(fd);
|
||||||
|
#elif defined(HAVE_FSYNC)
|
||||||
|
res=fsync(fd);
|
||||||
|
#elif defined(__WIN__)
|
||||||
|
res= _commit(fd);
|
||||||
|
#else
|
||||||
|
res= 0; /* No sync (strange OS) */
|
||||||
|
#endif
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
if (!(my_errno= errno))
|
||||||
|
my_errno= -1; /* Unknown error */
|
||||||
|
if (my_flags & MY_WME)
|
||||||
|
my_error(EE_SYNC, MYF(ME_BELL+ME_WAITTANG), my_filename(fd), my_errno);
|
||||||
|
}
|
||||||
|
DBUG_RETURN(res);
|
||||||
|
} /* my_read */
|
@ -159,6 +159,7 @@ my_bool my_thread_init(void)
|
|||||||
tmp->id= ++thread_id;
|
tmp->id= ++thread_id;
|
||||||
pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
|
pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
|
||||||
pthread_cond_init(&tmp->suspend, NULL);
|
pthread_cond_init(&tmp->suspend, NULL);
|
||||||
|
tmp->init= 1;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
|
#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
|
||||||
@ -170,12 +171,14 @@ end:
|
|||||||
|
|
||||||
void my_thread_end(void)
|
void my_thread_end(void)
|
||||||
{
|
{
|
||||||
struct st_my_thread_var *tmp=my_thread_var;
|
struct st_my_thread_var *tmp;
|
||||||
|
tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
|
||||||
|
|
||||||
#ifdef EXTRA_DEBUG_THREADS
|
#ifdef EXTRA_DEBUG_THREADS
|
||||||
fprintf(stderr,"my_thread_end(): tmp=%p,thread_id=%ld\n",
|
fprintf(stderr,"my_thread_end(): tmp=%p,thread_id=%ld\n",
|
||||||
tmp,pthread_self());
|
tmp,pthread_self());
|
||||||
#endif
|
#endif
|
||||||
if (tmp)
|
if (tmp && tmp->init)
|
||||||
{
|
{
|
||||||
#if !defined(DBUG_OFF)
|
#if !defined(DBUG_OFF)
|
||||||
/* tmp->dbug is allocated inside DBUG library */
|
/* tmp->dbug is allocated inside DBUG library */
|
||||||
@ -191,6 +194,8 @@ void my_thread_end(void)
|
|||||||
pthread_mutex_destroy(&tmp->mutex);
|
pthread_mutex_destroy(&tmp->mutex);
|
||||||
#if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS)
|
#if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS)
|
||||||
free(tmp);
|
free(tmp);
|
||||||
|
#else
|
||||||
|
tmp->init= 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/* The following free has to be done, even if my_thread_var() is 0 */
|
/* The following free has to be done, even if my_thread_var() is 0 */
|
||||||
|
@ -714,6 +714,9 @@ void thr_alarm_info(ALARM_INFO *info)
|
|||||||
bzero((char*) info, sizeof(*info));
|
bzero((char*) info, sizeof(*info));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resize_thr_alarm(uint max_alarms)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
thr_alarm for win95
|
thr_alarm for win95
|
||||||
@ -793,6 +796,10 @@ void thr_alarm_info(ALARM_INFO *info)
|
|||||||
bzero((char*) info, sizeof(*info));
|
bzero((char*) info, sizeof(*info));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resize_thr_alarm(uint max_alarms)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __WIN__ */
|
#endif /* __WIN__ */
|
||||||
|
|
||||||
#endif /* THREAD */
|
#endif /* THREAD */
|
||||||
|
@ -167,7 +167,7 @@ then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$ip_only" ="1"
|
if test "$ip_only" = "1"
|
||||||
then
|
then
|
||||||
ip=`echo "$resolved" | awk '/ /{print $6}'`
|
ip=`echo "$resolved" | awk '/ /{print $6}'`
|
||||||
hostname=$ip
|
hostname=$ip
|
||||||
|
@ -85,9 +85,13 @@ set_root_password() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
do_query "SET PASSWORD FOR root=PASSWORD('$password1');"
|
do_query "UPDATE mysql.user SET Password=PASSWORD('$password1') WHERE User='root';"
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo "Password updated successfully!"
|
echo "Password updated successfully!"
|
||||||
|
echo "Reloading privilege tables.."
|
||||||
|
if ! reload_privilege_tables; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
echo
|
echo
|
||||||
rootpass=$password1
|
rootpass=$password1
|
||||||
make_config
|
make_config
|
||||||
@ -144,11 +148,11 @@ reload_privilege_tables() {
|
|||||||
do_query "FLUSH PRIVILEGES;"
|
do_query "FLUSH PRIVILEGES;"
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo " ... Success!"
|
echo " ... Success!"
|
||||||
|
return 0
|
||||||
else
|
else
|
||||||
echo " ... Failed!"
|
echo " ... Failed!"
|
||||||
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interrupt() {
|
interrupt() {
|
||||||
|
@ -37,7 +37,7 @@ WARNING: THIS PROGRAM IS STILL IN BETA. Comments/patches welcome.
|
|||||||
|
|
||||||
# Documentation continued at end of file
|
# Documentation continued at end of file
|
||||||
|
|
||||||
my $VERSION = "1.19";
|
my $VERSION = "1.20";
|
||||||
|
|
||||||
my $opt_tmpdir = $ENV{TMPDIR} || "/tmp";
|
my $opt_tmpdir = $ENV{TMPDIR} || "/tmp";
|
||||||
|
|
||||||
@ -235,10 +235,15 @@ else
|
|||||||
|
|
||||||
# --- resolve database names from regexp ---
|
# --- resolve database names from regexp ---
|
||||||
if ( defined $opt{regexp} ) {
|
if ( defined $opt{regexp} ) {
|
||||||
|
my $t_regex = '.*';
|
||||||
|
if ( $opt{regexp} =~ s{^/(.+)/\./(.+)/$}{$1} ) {
|
||||||
|
$t_regex = $2;
|
||||||
|
}
|
||||||
|
|
||||||
my $sth_dbs = $dbh->prepare("show databases");
|
my $sth_dbs = $dbh->prepare("show databases");
|
||||||
$sth_dbs->execute;
|
$sth_dbs->execute;
|
||||||
while ( my ($db_name) = $sth_dbs->fetchrow_array ) {
|
while ( my ($db_name) = $sth_dbs->fetchrow_array ) {
|
||||||
push @db_desc, { 'src' => $db_name } if ( $db_name =~ m/$opt{regexp}/o );
|
push @db_desc, { 'src' => $db_name, 't_regex' => $t_regex } if ( $db_name =~ m/$opt{regexp}/o );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,6 +418,8 @@ foreach my $rdb ( @db_desc ) {
|
|||||||
else {
|
else {
|
||||||
mkdir($tgt_dirpath, 0750) or die "Can't create '$tgt_dirpath': $!\n"
|
mkdir($tgt_dirpath, 0750) or die "Can't create '$tgt_dirpath': $!\n"
|
||||||
unless -d $tgt_dirpath;
|
unless -d $tgt_dirpath;
|
||||||
|
my @f_info= stat "$datadir/$rdb->{src}";
|
||||||
|
chown $f_info[4], $f_info[5], $tgt_dirpath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -938,6 +945,14 @@ server in a mutual replication setup.
|
|||||||
|
|
||||||
Copy all databases with names matching the pattern
|
Copy all databases with names matching the pattern
|
||||||
|
|
||||||
|
=item --regexp /pattern1/./pattern2/
|
||||||
|
|
||||||
|
Copy all tables with names matching pattern2 from all databases with
|
||||||
|
names matching pattern1. For example, to select all tables which
|
||||||
|
names begin with 'bar' from all databases which names end with 'foo':
|
||||||
|
|
||||||
|
mysqlhotcopy --indices --method=cp --regexp /foo$/./^bar/
|
||||||
|
|
||||||
=item db_name./pattern/
|
=item db_name./pattern/
|
||||||
|
|
||||||
Copy only tables matching pattern. Shell metacharacters ( (, ), |, !,
|
Copy only tables matching pattern. Shell metacharacters ( (, ), |, !,
|
||||||
|
@ -2571,7 +2571,7 @@ err:
|
|||||||
|
|
||||||
bool Item_func_get_user_var::const_item() const
|
bool Item_func_get_user_var::const_item() const
|
||||||
{
|
{
|
||||||
return var_entry && current_thd->query_id != var_entry->update_query_id;
|
return (!var_entry || current_thd->query_id != var_entry->update_query_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -768,11 +768,49 @@ int Query_log_event::write(IO_CACHE* file)
|
|||||||
|
|
||||||
int Query_log_event::write_data(IO_CACHE* file)
|
int Query_log_event::write_data(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
|
char buf[QUERY_HEADER_LEN];
|
||||||
|
|
||||||
if (!query)
|
if (!query)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
char buf[QUERY_HEADER_LEN];
|
/*
|
||||||
int4store(buf + Q_THREAD_ID_OFFSET, thread_id);
|
We want to store the thread id:
|
||||||
|
(- as an information for the user when he reads the binlog)
|
||||||
|
- if the query uses temporary table: for the slave SQL thread to know to
|
||||||
|
which master connection the temp table belongs.
|
||||||
|
Now imagine we (write_data()) are called by the slave SQL thread (we are
|
||||||
|
logging a query executed by this thread; the slave runs with
|
||||||
|
--log-slave-updates). Then this query will be logged with
|
||||||
|
thread_id=the_thread_id_of_the_SQL_thread. Imagine that 2 temp tables of
|
||||||
|
the same name were created simultaneously on the master (in the master
|
||||||
|
binlog you have
|
||||||
|
CREATE TEMPORARY TABLE t; (thread 1)
|
||||||
|
CREATE TEMPORARY TABLE t; (thread 2)
|
||||||
|
...)
|
||||||
|
then in the slave's binlog there will be
|
||||||
|
CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
|
||||||
|
CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
|
||||||
|
which is bad (same thread id!).
|
||||||
|
|
||||||
|
To avoid this, we log the thread's thread id EXCEPT for the SQL
|
||||||
|
slave thread for which we log the original (master's) thread id.
|
||||||
|
Now this moves the bug: what happens if the thread id on the
|
||||||
|
master was 10 and when the slave replicates the query, a
|
||||||
|
connection number 10 is opened by a normal client on the slave,
|
||||||
|
and updates a temp table of the same name? We get a problem
|
||||||
|
again. To avoid this, in the handling of temp tables (sql_base.cc)
|
||||||
|
we use thread_id AND server_id. TODO when this is merged into
|
||||||
|
4.1: in 4.1, slave_proxy_id has been renamed to pseudo_thread_id
|
||||||
|
and is a session variable: that's to make mysqlbinlog work with
|
||||||
|
temp tables. We probably need to introduce
|
||||||
|
|
||||||
|
SET PSEUDO_SERVER_ID
|
||||||
|
for mysqlbinlog in 4.1. mysqlbinlog would print:
|
||||||
|
SET PSEUDO_SERVER_ID=
|
||||||
|
SET PSEUDO_THREAD_ID=
|
||||||
|
for each query using temp tables.
|
||||||
|
*/
|
||||||
|
int4store(buf + Q_THREAD_ID_OFFSET, slave_proxy_id);
|
||||||
int4store(buf + Q_EXEC_TIME_OFFSET, exec_time);
|
int4store(buf + Q_EXEC_TIME_OFFSET, exec_time);
|
||||||
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);
|
||||||
@ -790,12 +828,14 @@ int Query_log_event::write_data(IO_CACHE* file)
|
|||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
||||||
ulong query_length, bool using_trans)
|
ulong query_length, bool using_trans)
|
||||||
:Log_event(thd_arg, !thd_arg->tmp_table_used ?
|
:Log_event(thd_arg, !thd_arg->tmp_table_used ?
|
||||||
0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans),
|
0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans),
|
||||||
data_buf(0), query(query_arg),
|
data_buf(0), query(query_arg),
|
||||||
db(thd_arg->db), q_len((uint32) query_length),
|
db(thd_arg->db), q_len((uint32) query_length),
|
||||||
error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno),
|
error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno),
|
||||||
thread_id(thd_arg->thread_id)
|
thread_id(thd_arg->thread_id),
|
||||||
|
/* save the original thread id; we already know the server id */
|
||||||
|
slave_proxy_id(thd_arg->slave_proxy_id)
|
||||||
{
|
{
|
||||||
time_t end_time;
|
time_t end_time;
|
||||||
time(&end_time);
|
time(&end_time);
|
||||||
@ -836,7 +876,7 @@ Query_log_event::Query_log_event(const char* buf, int event_len,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
memcpy(data_buf, buf + Q_DATA_OFFSET, data_len);
|
memcpy(data_buf, buf + Q_DATA_OFFSET, data_len);
|
||||||
thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
|
slave_proxy_id= thread_id= uint4korr(buf + Q_THREAD_ID_OFFSET);
|
||||||
db = data_buf;
|
db = data_buf;
|
||||||
db_len = (uint)buf[Q_DB_LEN_OFFSET];
|
db_len = (uint)buf[Q_DB_LEN_OFFSET];
|
||||||
query=data_buf + db_len + 1;
|
query=data_buf + db_len + 1;
|
||||||
@ -907,8 +947,8 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
|
|||||||
{
|
{
|
||||||
thd->set_time((time_t)when);
|
thd->set_time((time_t)when);
|
||||||
thd->query_length= q_len;
|
thd->query_length= q_len;
|
||||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
|
||||||
thd->query = (char*)query;
|
thd->query = (char*)query;
|
||||||
|
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||||
thd->query_id = query_id++;
|
thd->query_id = query_id++;
|
||||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||||
thd->query_error= 0; // clear error
|
thd->query_error= 0; // clear error
|
||||||
@ -1276,7 +1316,7 @@ void Load_log_event::pack_info(Protocol *protocol)
|
|||||||
int Load_log_event::write_data_header(IO_CACHE* file)
|
int Load_log_event::write_data_header(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
char buf[LOAD_HEADER_LEN];
|
char buf[LOAD_HEADER_LEN];
|
||||||
int4store(buf + L_THREAD_ID_OFFSET, thread_id);
|
int4store(buf + L_THREAD_ID_OFFSET, slave_proxy_id);
|
||||||
int4store(buf + L_EXEC_TIME_OFFSET, exec_time);
|
int4store(buf + L_EXEC_TIME_OFFSET, exec_time);
|
||||||
int4store(buf + L_SKIP_LINES_OFFSET, skip_lines);
|
int4store(buf + L_SKIP_LINES_OFFSET, skip_lines);
|
||||||
buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
|
buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
|
||||||
@ -1317,7 +1357,9 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
|
|||||||
enum enum_duplicates handle_dup,
|
enum enum_duplicates handle_dup,
|
||||||
bool using_trans)
|
bool using_trans)
|
||||||
:Log_event(thd_arg, 0, using_trans), thread_id(thd_arg->thread_id),
|
:Log_event(thd_arg, 0, using_trans), thread_id(thd_arg->thread_id),
|
||||||
num_fields(0), fields(0), field_lens(0),field_block_len(0),
|
slave_proxy_id(thd_arg->slave_proxy_id),
|
||||||
|
num_fields(0),fields(0),
|
||||||
|
field_lens(0),field_block_len(0),
|
||||||
table_name(table_name_arg ? table_name_arg : ""),
|
table_name(table_name_arg ? table_name_arg : ""),
|
||||||
db(db_arg), fname(ex->file_name)
|
db(db_arg), fname(ex->file_name)
|
||||||
{
|
{
|
||||||
@ -1422,7 +1464,7 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
|
|||||||
char* buf_end = (char*)buf + event_len;
|
char* buf_end = (char*)buf + event_len;
|
||||||
uint header_len= old_format ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
|
uint header_len= old_format ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
|
||||||
const char* data_head = buf + header_len;
|
const char* data_head = buf + header_len;
|
||||||
thread_id = uint4korr(data_head + L_THREAD_ID_OFFSET);
|
slave_proxy_id= thread_id= uint4korr(data_head + L_THREAD_ID_OFFSET);
|
||||||
exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET);
|
exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET);
|
||||||
skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET);
|
skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET);
|
||||||
table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];
|
table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];
|
||||||
|
@ -455,6 +455,13 @@ public:
|
|||||||
uint32 db_len;
|
uint32 db_len;
|
||||||
uint16 error_code;
|
uint16 error_code;
|
||||||
ulong thread_id;
|
ulong thread_id;
|
||||||
|
/*
|
||||||
|
For events created by Query_log_event::exec_event (and
|
||||||
|
Load_log_event::exec_event()) we need the *original* thread id, to be able
|
||||||
|
to log the event with the original (=master's) thread id (fix for
|
||||||
|
BUG#1686).
|
||||||
|
*/
|
||||||
|
ulong slave_proxy_id;
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
|
|
||||||
Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length,
|
Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length,
|
||||||
@ -543,6 +550,7 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ulong thread_id;
|
ulong thread_id;
|
||||||
|
ulong slave_proxy_id;
|
||||||
uint32 table_name_len;
|
uint32 table_name_len;
|
||||||
uint32 db_len;
|
uint32 db_len;
|
||||||
uint32 fname_len;
|
uint32 fname_len;
|
||||||
|
@ -1985,7 +1985,7 @@ extern "C" pthread_handler_decl(handle_shutdown,arg)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
const char *load_default_groups[]= { "mysqld","server",MYSQL_BASE_VERSION,0 };
|
const char *load_default_groups[]= { "mysqld","server",MYSQL_BASE_VERSION,0,0};
|
||||||
|
|
||||||
bool open_log(MYSQL_LOG *log, const char *hostname,
|
bool open_log(MYSQL_LOG *log, const char *hostname,
|
||||||
const char *opt_name, const char *extension,
|
const char *opt_name, const char *extension,
|
||||||
@ -2733,7 +2733,7 @@ default_service_handling(char **argv,
|
|||||||
const char *extra_opt)
|
const char *extra_opt)
|
||||||
{
|
{
|
||||||
char path_and_service[FN_REFLEN+FN_REFLEN+32], *pos, *end;
|
char path_and_service[FN_REFLEN+FN_REFLEN+32], *pos, *end;
|
||||||
end= path_and_service + sizeof(path_and_service)-1;
|
end= path_and_service + sizeof(path_and_service)-3;
|
||||||
|
|
||||||
/* We have to quote filename if it contains spaces */
|
/* We have to quote filename if it contains spaces */
|
||||||
pos= add_quoted_string(path_and_service, file_path, end);
|
pos= add_quoted_string(path_and_service, file_path, end);
|
||||||
@ -2743,7 +2743,9 @@ default_service_handling(char **argv,
|
|||||||
*pos++= ' ';
|
*pos++= ' ';
|
||||||
pos= add_quoted_string(pos, extra_opt, end);
|
pos= add_quoted_string(pos, extra_opt, end);
|
||||||
}
|
}
|
||||||
*pos= 0; // Ensure end null
|
/* We must have servicename last */
|
||||||
|
*pos++= ' ';
|
||||||
|
strmake(pos, servicename, (uint) (end+2 - pos));
|
||||||
|
|
||||||
if (Service.got_service_option(argv, "install"))
|
if (Service.got_service_option(argv, "install"))
|
||||||
{
|
{
|
||||||
@ -2786,10 +2788,16 @@ int main(int argc, char **argv)
|
|||||||
if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
|
if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
|
||||||
file_path, ""))
|
file_path, ""))
|
||||||
return 0;
|
return 0;
|
||||||
if (Service.IsService(argv[1]))
|
if (Service.IsService(argv[1])) /* Start an optional service */
|
||||||
{
|
{
|
||||||
/* start an optional service */
|
/*
|
||||||
load_default_groups[0]= argv[1];
|
Only add the service name to the groups read from the config file
|
||||||
|
if it's not "MySQL". (The default service name should be 'mysqld'
|
||||||
|
but we started a bad tradition by calling it MySQL from the start
|
||||||
|
and we are now stuck with it.
|
||||||
|
*/
|
||||||
|
if (my_strcasecmp(argv[1],"mysql"))
|
||||||
|
load_default_groups[3]= argv[1];
|
||||||
start_mode= 1;
|
start_mode= 1;
|
||||||
Service.Init(argv[1], mysql_service);
|
Service.Init(argv[1], mysql_service);
|
||||||
return 0;
|
return 0;
|
||||||
@ -2797,8 +2805,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
else if (argc == 3) /* install or remove any optional service */
|
else if (argc == 3) /* install or remove any optional service */
|
||||||
{
|
{
|
||||||
if (!default_service_handling(argv, argv[2], argv[2], file_path,
|
if (!default_service_handling(argv, argv[2], argv[2], file_path, ""))
|
||||||
argv[2]))
|
|
||||||
return 0;
|
return 0;
|
||||||
if (Service.IsService(argv[2]))
|
if (Service.IsService(argv[2]))
|
||||||
{
|
{
|
||||||
@ -2810,6 +2817,8 @@ int main(int argc, char **argv)
|
|||||||
opt_argc= 2; // Skip service-name
|
opt_argc= 2; // Skip service-name
|
||||||
opt_argv=argv;
|
opt_argv=argv;
|
||||||
start_mode= 1;
|
start_mode= 1;
|
||||||
|
if (my_strcasecmp(argv[2],"mysql"))
|
||||||
|
load_default_groups[3]= argv[2];
|
||||||
Service.Init(argv[2], mysql_service);
|
Service.Init(argv[2], mysql_service);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
27
sql/slave.cc
27
sql/slave.cc
@ -355,6 +355,22 @@ void init_slave_skip_errors(const char* arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void st_relay_log_info::close_temporary_tables()
|
||||||
|
{
|
||||||
|
TABLE *table,*next;
|
||||||
|
|
||||||
|
for (table=save_temporary_tables ; table ; table=next)
|
||||||
|
{
|
||||||
|
next=table->next;
|
||||||
|
/*
|
||||||
|
Don't ask for disk deletion. For now, anyway they will be deleted when
|
||||||
|
slave restarts, but it is a better intention to not delete them.
|
||||||
|
*/
|
||||||
|
close_temporary(table, 0);
|
||||||
|
}
|
||||||
|
save_temporary_tables= 0;
|
||||||
|
slave_open_temp_tables= 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
purge_relay_logs()
|
purge_relay_logs()
|
||||||
@ -847,6 +863,7 @@ static int end_slave_on_walk(MASTER_INFO* mi, gptr /*unused*/)
|
|||||||
|
|
||||||
void end_slave()
|
void end_slave()
|
||||||
{
|
{
|
||||||
|
/* This is called when the server terminates, in close_connections(). */
|
||||||
if (active_mi)
|
if (active_mi)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -1428,7 +1445,7 @@ file '%s', errno %d)", fname, my_errno);
|
|||||||
if (init_relay_log_pos(rli,NullS,BIN_LOG_HEADER_SIZE,0 /* no data lock */,
|
if (init_relay_log_pos(rli,NullS,BIN_LOG_HEADER_SIZE,0 /* no data lock */,
|
||||||
&msg))
|
&msg))
|
||||||
{
|
{
|
||||||
sql_print_error("Failed to open the relay log 'FIRST' (relay_log_pos 4");
|
sql_print_error("Failed to open the relay log 'FIRST' (relay_log_pos 4)");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
rli->group_master_log_name[0]= 0;
|
rli->group_master_log_name[0]= 0;
|
||||||
@ -3166,8 +3183,6 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
|
|||||||
RPL_LOG_NAME, llstr(rli->group_master_log_pos,llbuff));
|
RPL_LOG_NAME, llstr(rli->group_master_log_pos,llbuff));
|
||||||
|
|
||||||
err:
|
err:
|
||||||
/* Free temporary tables etc */
|
|
||||||
thd->cleanup();
|
|
||||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||||
thd->query = thd->db = 0; // extra safety
|
thd->query = thd->db = 0; // extra safety
|
||||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||||
@ -3585,6 +3600,12 @@ void end_relay_log_info(RELAY_LOG_INFO* rli)
|
|||||||
}
|
}
|
||||||
rli->inited = 0;
|
rli->inited = 0;
|
||||||
rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
|
rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
|
||||||
|
/*
|
||||||
|
Delete the slave's temporary tables from memory.
|
||||||
|
In the future there will be other actions than this, to ensure persistance
|
||||||
|
of slave's temp tables after shutdown.
|
||||||
|
*/
|
||||||
|
rli->close_temporary_tables();
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,10 +320,10 @@ typedef struct st_relay_log_info
|
|||||||
|
|
||||||
int wait_for_pos(THD* thd, String* log_name, longlong log_pos,
|
int wait_for_pos(THD* thd, String* log_name, longlong log_pos,
|
||||||
longlong timeout);
|
longlong timeout);
|
||||||
|
void close_temporary_tables();
|
||||||
|
|
||||||
/* Check if UNTIL condition is satisfied. See slave.cc for more. */
|
/* Check if UNTIL condition is satisfied. See slave.cc for more. */
|
||||||
bool is_until_satisfied();
|
bool is_until_satisfied();
|
||||||
|
|
||||||
} RELAY_LOG_INFO;
|
} RELAY_LOG_INFO;
|
||||||
|
|
||||||
|
|
||||||
|
@ -575,6 +575,8 @@ TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name)
|
|||||||
uint key_length= (uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
|
uint key_length= (uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
|
||||||
TABLE *table,**prev;
|
TABLE *table,**prev;
|
||||||
|
|
||||||
|
int4store(key+key_length,thd->server_id);
|
||||||
|
key_length += 4;
|
||||||
int4store(key+key_length,thd->variables.pseudo_thread_id);
|
int4store(key+key_length,thd->variables.pseudo_thread_id);
|
||||||
key_length += 4;
|
key_length += 4;
|
||||||
|
|
||||||
@ -603,18 +605,27 @@ bool close_temporary_table(THD *thd, const char *db, const char *table_name)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Used by ALTER TABLE when the table is a temporary one. It changes something
|
||||||
|
only if the ALTER contained a RENAME clause (otherwise, table_name is the old
|
||||||
|
name).
|
||||||
|
Prepares a table cache key, which is the concatenation of db, table_name and
|
||||||
|
thd->slave_proxy_id, separated by '\0'.
|
||||||
|
*/
|
||||||
bool rename_temporary_table(THD* thd, TABLE *table, const char *db,
|
bool rename_temporary_table(THD* thd, TABLE *table, const char *db,
|
||||||
const char *table_name)
|
const char *table_name)
|
||||||
{
|
{
|
||||||
char *key;
|
char *key;
|
||||||
if (!(key=(char*) alloc_root(&table->mem_root,
|
if (!(key=(char*) alloc_root(&table->mem_root,
|
||||||
(uint) strlen(db)+
|
(uint) strlen(db)+
|
||||||
(uint) strlen(table_name)+6)))
|
(uint) strlen(table_name)+6+4)))
|
||||||
return 1; /* purecov: inspected */
|
return 1; /* purecov: inspected */
|
||||||
table->key_length=(uint)
|
table->key_length=(uint)
|
||||||
(strmov((table->real_name=strmov(table->table_cache_key=key,
|
(strmov((table->real_name=strmov(table->table_cache_key=key,
|
||||||
db)+1),
|
db)+1),
|
||||||
table_name) - table->table_cache_key)+1;
|
table_name) - table->table_cache_key)+1;
|
||||||
|
int4store(key+table->key_length,thd->server_id);
|
||||||
|
table->key_length += 4;
|
||||||
int4store(key+table->key_length,thd->variables.pseudo_thread_id);
|
int4store(key+table->key_length,thd->variables.pseudo_thread_id);
|
||||||
table->key_length += 4;
|
table->key_length += 4;
|
||||||
return 0;
|
return 0;
|
||||||
@ -771,12 +782,13 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
|
|||||||
if (thd->killed)
|
if (thd->killed)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
key_length= (uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
|
key_length= (uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
|
||||||
int4store(key + key_length, thd->variables.pseudo_thread_id);
|
int4store(key + key_length, thd->server_id);
|
||||||
|
int4store(key + key_length + 4, thd->variables.pseudo_thread_id);
|
||||||
|
|
||||||
for (table=thd->temporary_tables; table ; table=table->next)
|
for (table=thd->temporary_tables; table ; table=table->next)
|
||||||
{
|
{
|
||||||
if (table->key_length == key_length+4 &&
|
if (table->key_length == key_length+8 &&
|
||||||
!memcmp(table->table_cache_key,key,key_length+4))
|
!memcmp(table->table_cache_key,key,key_length+8))
|
||||||
{
|
{
|
||||||
if (table->query_id == thd->query_id)
|
if (table->query_id == thd->query_id)
|
||||||
{
|
{
|
||||||
@ -1671,7 +1683,7 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
|
|||||||
total of 6 extra bytes in my_malloc in addition to table/db stuff
|
total of 6 extra bytes in my_malloc in addition to table/db stuff
|
||||||
*/
|
*/
|
||||||
if (!(tmp_table=(TABLE*) my_malloc(sizeof(*tmp_table)+(uint) strlen(db)+
|
if (!(tmp_table=(TABLE*) my_malloc(sizeof(*tmp_table)+(uint) strlen(db)+
|
||||||
(uint) strlen(table_name)+6,
|
(uint) strlen(table_name)+6+4,
|
||||||
MYF(MY_WME))))
|
MYF(MY_WME))))
|
||||||
DBUG_RETURN(0); /* purecov: inspected */
|
DBUG_RETURN(0); /* purecov: inspected */
|
||||||
|
|
||||||
@ -1693,6 +1705,9 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
|
|||||||
strmov(tmp_table->table_cache_key,db)
|
strmov(tmp_table->table_cache_key,db)
|
||||||
+1), table_name)
|
+1), table_name)
|
||||||
- tmp_table->table_cache_key)+1;
|
- tmp_table->table_cache_key)+1;
|
||||||
|
int4store(tmp_table->table_cache_key + tmp_table->key_length,
|
||||||
|
thd->server_id);
|
||||||
|
tmp_table->key_length += 4;
|
||||||
int4store(tmp_table->table_cache_key + tmp_table->key_length,
|
int4store(tmp_table->table_cache_key + tmp_table->key_length,
|
||||||
thd->variables.pseudo_thread_id);
|
thd->variables.pseudo_thread_id);
|
||||||
tmp_table->key_length += 4;
|
tmp_table->key_length += 4;
|
||||||
|
@ -2761,11 +2761,33 @@ my_bool Query_cache::move_by_type(byte **border,
|
|||||||
relink(block, new_block, next, prev, pnext, pprev);
|
relink(block, new_block, next, prev, pnext, pprev);
|
||||||
if (queries_blocks == block)
|
if (queries_blocks == block)
|
||||||
queries_blocks = new_block;
|
queries_blocks = new_block;
|
||||||
|
Query_cache_block_table *beg_of_table_table= block->table(0),
|
||||||
|
*end_of_table_table= block->table(n_tables);
|
||||||
|
byte *beg_of_new_table_table= (byte*) new_block->table(0);
|
||||||
|
|
||||||
for (TABLE_COUNTER_TYPE j=0; j < n_tables; j++)
|
for (TABLE_COUNTER_TYPE j=0; j < n_tables; j++)
|
||||||
{
|
{
|
||||||
Query_cache_block_table *block_table = new_block->table(j);
|
Query_cache_block_table *block_table = new_block->table(j);
|
||||||
block_table->next->prev = block_table;
|
|
||||||
block_table->prev->next = block_table;
|
// use aligment from begining of table if 'next' is in same block
|
||||||
|
if ((beg_of_table_table <= block_table->next) &&
|
||||||
|
(block_table->next < end_of_table_table))
|
||||||
|
((Query_cache_block_table *)(beg_of_new_table_table +
|
||||||
|
(((byte*)block_table->next) -
|
||||||
|
((byte*)beg_of_table_table))))->prev=
|
||||||
|
block_table;
|
||||||
|
else
|
||||||
|
block_table->next->prev= block_table;
|
||||||
|
|
||||||
|
// use aligment from begining of table if 'prev' is in same block
|
||||||
|
if ((beg_of_table_table <= block_table->prev) &&
|
||||||
|
(block_table->prev < end_of_table_table))
|
||||||
|
((Query_cache_block_table *)(beg_of_new_table_table +
|
||||||
|
(((byte*)block_table->prev) -
|
||||||
|
((byte*)beg_of_table_table))))->next=
|
||||||
|
block_table;
|
||||||
|
else
|
||||||
|
block_table->prev->next = block_table;
|
||||||
}
|
}
|
||||||
DBUG_PRINT("qcache", ("after circle tt"));
|
DBUG_PRINT("qcache", ("after circle tt"));
|
||||||
*border += len;
|
*border += len;
|
||||||
|
@ -396,6 +396,11 @@ bool THD::store_globals()
|
|||||||
return 1;
|
return 1;
|
||||||
mysys_var=my_thread_var;
|
mysys_var=my_thread_var;
|
||||||
dbug_thread_id=my_thread_id();
|
dbug_thread_id=my_thread_id();
|
||||||
|
/*
|
||||||
|
By default 'slave_proxy_id' is 'thread_id'. They may later become different
|
||||||
|
if this is the slave SQL thread.
|
||||||
|
*/
|
||||||
|
slave_proxy_id= thread_id;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,7 +481,11 @@ public:
|
|||||||
char priv_host[MAX_HOSTNAME];
|
char priv_host[MAX_HOSTNAME];
|
||||||
/* remote (peer) port */
|
/* remote (peer) port */
|
||||||
uint16 peer_port;
|
uint16 peer_port;
|
||||||
/* Points to info-string that will show in SHOW PROCESSLIST */
|
/*
|
||||||
|
Points to info-string that we show in SHOW PROCESSLIST
|
||||||
|
You are supposed to update thd->proc_info only if you have coded
|
||||||
|
a time-consuming piece that MySQL can get stuck in for a long time.
|
||||||
|
*/
|
||||||
const char *proc_info;
|
const char *proc_info;
|
||||||
/* points to host if host is available, otherwise points to ip */
|
/* points to host if host is available, otherwise points to ip */
|
||||||
const char *host_or_ip;
|
const char *host_or_ip;
|
||||||
@ -510,6 +514,11 @@ public:
|
|||||||
enum enum_server_command command;
|
enum enum_server_command command;
|
||||||
uint32 server_id;
|
uint32 server_id;
|
||||||
uint32 file_id; // for LOAD DATA INFILE
|
uint32 file_id; // for LOAD DATA INFILE
|
||||||
|
/*
|
||||||
|
Used in error messages to tell user in what part of MySQL we found an
|
||||||
|
error. E. g. when where= "having clause", if fix_fields() fails, user
|
||||||
|
will know that the error was in having clause.
|
||||||
|
*/
|
||||||
const char *where;
|
const char *where;
|
||||||
time_t start_time,time_after_lock,user_time;
|
time_t start_time,time_after_lock,user_time;
|
||||||
time_t connect_time,thr_create_time; // track down slow pthread_create
|
time_t connect_time,thr_create_time; // track down slow pthread_create
|
||||||
|
@ -172,6 +172,7 @@ static int get_or_create_user_conn(THD *thd, const char *user,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
thd->user_connect=uc;
|
thd->user_connect=uc;
|
||||||
|
uc->connections++;
|
||||||
end:
|
end:
|
||||||
(void) pthread_mutex_unlock(&LOCK_user_conn);
|
(void) pthread_mutex_unlock(&LOCK_user_conn);
|
||||||
return return_val;
|
return return_val;
|
||||||
@ -314,14 +315,15 @@ int check_user(THD *thd, enum enum_server_command command,
|
|||||||
thd->db_access=0;
|
thd->db_access=0;
|
||||||
|
|
||||||
/* Don't allow user to connect if he has done too many queries */
|
/* Don't allow user to connect if he has done too many queries */
|
||||||
if ((ur.questions || ur.updates ||
|
if ((ur.questions || ur.updates || ur.connections ||
|
||||||
ur.connections || max_user_connections) &&
|
max_user_connections) &&
|
||||||
get_or_create_user_conn(thd,thd->user,thd->host_or_ip,&ur))
|
get_or_create_user_conn(thd,thd->user,thd->host_or_ip,&ur))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
if (thd->user_connect && (thd->user_connect->user_resources.connections ||
|
if (thd->user_connect &&
|
||||||
max_user_connections) &&
|
(thd->user_connect->user_resources.connections ||
|
||||||
check_for_max_user_connections(thd, thd->user_connect))
|
max_user_connections) &&
|
||||||
DBUG_RETURN(-1);
|
check_for_max_user_connections(thd, thd->user_connect))
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
|
||||||
/* Change database if necessary: OK or FAIL is sent in mysql_change_db */
|
/* Change database if necessary: OK or FAIL is sent in mysql_change_db */
|
||||||
if (db && db[0])
|
if (db && db[0])
|
||||||
@ -386,42 +388,84 @@ void init_max_user_conn(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
check if user has already too many connections
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
check_for_max_user_connections()
|
||||||
|
thd Thread handle
|
||||||
|
uc User connect object
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
If check fails, we decrease user connection count, which means one
|
||||||
|
shouldn't call decrease_user_connections() after this function.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
1 error
|
||||||
|
*/
|
||||||
|
|
||||||
static int check_for_max_user_connections(THD *thd, USER_CONN *uc)
|
static int check_for_max_user_connections(THD *thd, USER_CONN *uc)
|
||||||
{
|
{
|
||||||
int error=0;
|
int error=0;
|
||||||
DBUG_ENTER("check_for_max_user_connections");
|
DBUG_ENTER("check_for_max_user_connections");
|
||||||
|
|
||||||
|
(void) pthread_mutex_lock(&LOCK_user_conn);
|
||||||
if (max_user_connections &&
|
if (max_user_connections &&
|
||||||
(max_user_connections < (uint) uc->connections))
|
max_user_connections < (uint) uc->connections)
|
||||||
{
|
{
|
||||||
net_printf(thd,ER_TOO_MANY_USER_CONNECTIONS, uc->user);
|
net_printf(thd,ER_TOO_MANY_USER_CONNECTIONS, uc->user);
|
||||||
error=1;
|
error=1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
uc->connections++;
|
|
||||||
if (uc->user_resources.connections &&
|
if (uc->user_resources.connections &&
|
||||||
uc->conn_per_hour++ >= uc->user_resources.connections)
|
uc->user_resources.connections <= uc->conn_per_hour)
|
||||||
{
|
{
|
||||||
net_printf(thd, ER_USER_LIMIT_REACHED, uc->user,
|
net_printf(thd, ER_USER_LIMIT_REACHED, uc->user,
|
||||||
"max_connections",
|
"max_connections",
|
||||||
(long) uc->user_resources.connections);
|
(long) uc->user_resources.connections);
|
||||||
error=1;
|
error=1;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
end:
|
uc->conn_per_hour++;
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (error)
|
||||||
|
uc->connections--; // no need for decrease_user_connections() here
|
||||||
|
(void) pthread_mutex_unlock(&LOCK_user_conn);
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Decrease user connection count
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
decrease_user_connections()
|
||||||
|
uc User connection object
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
If there is a n user connection object for a connection
|
||||||
|
(which only happens if 'max_user_connections' is defined or
|
||||||
|
if someone has created a resource grant for a user), then
|
||||||
|
the connection count is always incremented on connect.
|
||||||
|
|
||||||
|
The user connect object is not freed if some users has
|
||||||
|
'max connections per hour' defined as we need to be able to hold
|
||||||
|
count over the lifetime of the connection.
|
||||||
|
*/
|
||||||
|
|
||||||
static void decrease_user_connections(USER_CONN *uc)
|
static void decrease_user_connections(USER_CONN *uc)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("decrease_user_connections");
|
DBUG_ENTER("decrease_user_connections");
|
||||||
if ((uc->connections && !--uc->connections) && !mqh_used)
|
(void) pthread_mutex_lock(&LOCK_user_conn);
|
||||||
|
DBUG_ASSERT(uc->connections);
|
||||||
|
if (!--uc->connections && !mqh_used)
|
||||||
{
|
{
|
||||||
/* Last connection for user; Delete it */
|
/* Last connection for user; Delete it */
|
||||||
(void) pthread_mutex_lock(&LOCK_user_conn);
|
|
||||||
(void) hash_delete(&hash_user_connections,(byte*) uc);
|
(void) hash_delete(&hash_user_connections,(byte*) uc);
|
||||||
(void) pthread_mutex_unlock(&LOCK_user_conn);
|
|
||||||
}
|
}
|
||||||
|
(void) pthread_mutex_unlock(&LOCK_user_conn);
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1227,15 +1271,17 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
char *save_user= thd->user;
|
char *save_user= thd->user;
|
||||||
char *save_priv_user= thd->priv_user;
|
char *save_priv_user= thd->priv_user;
|
||||||
char *save_db= thd->db;
|
char *save_db= thd->db;
|
||||||
USER_CONN *save_uc= thd->user_connect;
|
USER_CONN *save_user_connect= thd->user_connect;
|
||||||
thd->user= my_strdup(user, MYF(0));
|
|
||||||
if (!thd->user)
|
if (!(thd->user= my_strdup(user, MYF(0))))
|
||||||
{
|
{
|
||||||
thd->user= save_user;
|
thd->user= save_user;
|
||||||
send_error(thd, ER_OUT_OF_RESOURCES);
|
send_error(thd, ER_OUT_OF_RESOURCES);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear variables that are allocated */
|
||||||
|
thd->user_connect= 0;
|
||||||
int res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, false);
|
int res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, false);
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
@ -1246,6 +1292,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
x_free(thd->user);
|
x_free(thd->user);
|
||||||
thd->user= save_user;
|
thd->user= save_user;
|
||||||
thd->priv_user= save_priv_user;
|
thd->priv_user= save_priv_user;
|
||||||
|
thd->user_connect= save_user_connect;
|
||||||
thd->master_access= save_master_access;
|
thd->master_access= save_master_access;
|
||||||
thd->db_access= save_db_access;
|
thd->db_access= save_db_access;
|
||||||
thd->db= save_db;
|
thd->db= save_db;
|
||||||
@ -1254,8 +1301,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* we've authenticated new user */
|
/* we've authenticated new user */
|
||||||
if (max_connections && save_uc)
|
if (save_user_connect)
|
||||||
decrease_user_connections(save_uc);
|
decrease_user_connections(save_user_connect);
|
||||||
x_free((gptr) save_db);
|
x_free((gptr) save_db);
|
||||||
x_free((gptr) save_user);
|
x_free((gptr) save_user);
|
||||||
}
|
}
|
||||||
|
@ -1453,10 +1453,21 @@ JOIN::exec()
|
|||||||
{
|
{
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
Here we sort rows for ORDER BY/GROUP BY clause, if the optimiser
|
||||||
|
chose FILESORT to be faster than INDEX SCAN or there is no
|
||||||
|
suitable index present.
|
||||||
|
Note, that create_sort_index calls test_if_skip_sort_order and may
|
||||||
|
finally replace sorting with index scan if there is a LIMIT clause in
|
||||||
|
the query. XXX: it's never shown in EXPLAIN!
|
||||||
|
OPTION_FOUND_ROWS supersedes LIMIT and is taken into account.
|
||||||
|
*/
|
||||||
if (create_sort_index(thd, curr_join,
|
if (create_sort_index(thd, curr_join,
|
||||||
curr_join->group_list ?
|
curr_join->group_list ?
|
||||||
curr_join->group_list : curr_join->order,
|
curr_join->group_list : curr_join->order,
|
||||||
curr_join->select_limit, unit->select_limit_cnt))
|
curr_join->select_limit,
|
||||||
|
(select_options & OPTION_FOUND_ROWS ?
|
||||||
|
HA_POS_ERROR : unit->select_limit_cnt)))
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2856,8 +2867,6 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
|
|||||||
!(s->table->force_index && best_key))
|
!(s->table->force_index && best_key))
|
||||||
{ // Check full join
|
{ // Check full join
|
||||||
ha_rows rnd_records= s->found_records;
|
ha_rows rnd_records= s->found_records;
|
||||||
/* Estimate cost of reading table. */
|
|
||||||
tmp= s->table->file->scan_time();
|
|
||||||
/*
|
/*
|
||||||
If there is a restriction on the table, assume that 25% of the
|
If there is a restriction on the table, assume that 25% of the
|
||||||
rows can be skipped on next part.
|
rows can be skipped on next part.
|
||||||
@ -2867,36 +2876,57 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
|
|||||||
if (found_constraint)
|
if (found_constraint)
|
||||||
rnd_records-= rnd_records/4;
|
rnd_records-= rnd_records/4;
|
||||||
|
|
||||||
if (s->on_expr) // Can't use join cache
|
/*
|
||||||
|
Range optimizer never proposes a RANGE if it isn't better
|
||||||
|
than FULL: so if RANGE is present, it's always preferred to FULL.
|
||||||
|
Here we estimate its cost.
|
||||||
|
*/
|
||||||
|
if (s->quick)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
For each record we:
|
||||||
|
- read record range through 'quick'
|
||||||
|
- skip rows which does not satisfy WHERE constraints
|
||||||
|
*/
|
||||||
tmp= record_count *
|
tmp= record_count *
|
||||||
/* We have to read the whole table for each record */
|
(s->quick->read_time +
|
||||||
(tmp +
|
(s->found_records - rnd_records)/(double) TIME_FOR_COMPARE);
|
||||||
/*
|
|
||||||
And we have to skip rows which does not satisfy join
|
|
||||||
condition for each record.
|
|
||||||
*/
|
|
||||||
(s->records - rnd_records)/(double) TIME_FOR_COMPARE);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We read the table as many times as join buffer becomes full. */
|
/* Estimate cost of reading table. */
|
||||||
tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
|
tmp= s->table->file->scan_time();
|
||||||
record_count /
|
if (s->on_expr) // Can't use join cache
|
||||||
(double) thd->variables.join_buff_size));
|
{
|
||||||
/*
|
/*
|
||||||
We don't make full cartesian product between rows in the scanned
|
For each record we have to:
|
||||||
table and existing records because we skip all rows from the
|
- read the whole table record
|
||||||
scanned table, which does not satisfy join condition when
|
- skip rows which does not satisfy join condition
|
||||||
we read the table (see flush_cached_records for details). Here we
|
*/
|
||||||
take into account cost to read and skip these records.
|
tmp= record_count *
|
||||||
*/
|
(tmp +
|
||||||
tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE;
|
(s->records - rnd_records)/(double) TIME_FOR_COMPARE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We read the table as many times as join buffer becomes full. */
|
||||||
|
tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
|
||||||
|
record_count /
|
||||||
|
(double) thd->variables.join_buff_size));
|
||||||
|
/*
|
||||||
|
We don't make full cartesian product between rows in the scanned
|
||||||
|
table and existing records because we skip all rows from the
|
||||||
|
scanned table, which does not satisfy join condition when
|
||||||
|
we read the table (see flush_cached_records for details). Here we
|
||||||
|
take into account cost to read and skip these records.
|
||||||
|
*/
|
||||||
|
tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We estimate the cost of evaluating WHERE clause for found records
|
We estimate the cost of evaluating WHERE clause for found records
|
||||||
as record_count * rnd_records + TIME_FOR_COMPARE. This cost plus
|
as record_count * rnd_records / TIME_FOR_COMPARE. This cost plus
|
||||||
tmp give us total cost of using TABLE SCAN
|
tmp give us total cost of using TABLE SCAN
|
||||||
*/
|
*/
|
||||||
if (best == DBL_MAX ||
|
if (best == DBL_MAX ||
|
||||||
@ -3320,6 +3350,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||||||
table_map used_tables;
|
table_map used_tables;
|
||||||
if (join->tables > 1)
|
if (join->tables > 1)
|
||||||
cond->update_used_tables(); // Tablenr may have changed
|
cond->update_used_tables(); // Tablenr may have changed
|
||||||
|
if (join->const_tables == join->tables)
|
||||||
|
join->const_table_map|=RAND_TABLE_BIT;
|
||||||
{ // Check const tables
|
{ // Check const tables
|
||||||
COND *const_cond=
|
COND *const_cond=
|
||||||
make_cond_for_table(cond,join->const_table_map,(table_map) 0);
|
make_cond_for_table(cond,join->const_table_map,(table_map) 0);
|
||||||
|
@ -22,7 +22,11 @@
|
|||||||
#include "sql_select.h"
|
#include "sql_select.h"
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include <thr_alarm.h>
|
#include <thr_alarm.h>
|
||||||
|
#if defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_H)
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
#elif defined(HAVE_MALLINFO) && defined(HAVE_SYS_MALLOC_H)
|
||||||
|
#include <sys/malloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Intern key cache variables */
|
/* Intern key cache variables */
|
||||||
extern "C" pthread_mutex_t THR_LOCK_keycache;
|
extern "C" pthread_mutex_t THR_LOCK_keycache;
|
||||||
|
@ -150,16 +150,19 @@ int rea_create_table(THD *thd, my_string file_name,
|
|||||||
|
|
||||||
my_free((gptr) screen_buff,MYF(0));
|
my_free((gptr) screen_buff,MYF(0));
|
||||||
my_free((gptr) keybuff, MYF(0));
|
my_free((gptr) keybuff, MYF(0));
|
||||||
VOID(my_close(file,MYF(MY_WME)));
|
if (my_sync(file, MYF(MY_WME)))
|
||||||
if (ha_create_table(file_name,create_info,0))
|
|
||||||
goto err2;
|
goto err2;
|
||||||
|
if (my_close(file,MYF(MY_WME)) ||
|
||||||
|
ha_create_table(file_name,create_info,0))
|
||||||
|
goto err3;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
my_free((gptr) screen_buff,MYF(0));
|
my_free((gptr) screen_buff,MYF(0));
|
||||||
my_free((gptr) keybuff, MYF(0));
|
my_free((gptr) keybuff, MYF(0));
|
||||||
|
err2:
|
||||||
VOID(my_close(file,MYF(MY_WME)));
|
VOID(my_close(file,MYF(MY_WME)));
|
||||||
err2:
|
err3:
|
||||||
my_delete(file_name,MYF(0));
|
my_delete(file_name,MYF(0));
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
} /* rea_create_table */
|
} /* rea_create_table */
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
#define ERRMAPP 1 /* Errormap f|r my_error */
|
#define ERRMAPP 1 /* Errormap f|r my_error */
|
||||||
#define LIBLEN FN_REFLEN-FN_LEN /* Max l{ngd p} dev */
|
#define LIBLEN FN_REFLEN-FN_LEN /* Max l{ngd p} dev */
|
||||||
#define MAX_DBKEY_LENGTH (FN_LEN*2+6) /* extra 4 bytes for slave tmp
|
#define MAX_DBKEY_LENGTH (FN_LEN*2+1+1+4+4) /* extra 4+4 bytes for slave tmp
|
||||||
* tables */
|
* tables */
|
||||||
#define MAX_ALIAS_NAME 256
|
#define MAX_ALIAS_NAME 256
|
||||||
#define MAX_FIELD_NAME 34 /* Max colum name length +2 */
|
#define MAX_FIELD_NAME 34 /* Max colum name length +2 */
|
||||||
|
@ -108,19 +108,6 @@ else
|
|||||||
test -z "$print_defaults" && print_defaults="my_print_defaults"
|
test -z "$print_defaults" && print_defaults="my_print_defaults"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#
|
|
||||||
# Set pid file if not given
|
|
||||||
#
|
|
||||||
if test -z "$pid_file"
|
|
||||||
then
|
|
||||||
pid_file=$datadir/`@HOSTNAME@`.pid
|
|
||||||
else
|
|
||||||
case "$pid_file" in
|
|
||||||
/* ) ;;
|
|
||||||
* ) pid_file="$datadir/$pid_file" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test if someone changed datadir; In this case we should also read the
|
# Test if someone changed datadir; In this case we should also read the
|
||||||
# default arguments from this directory
|
# default arguments from this directory
|
||||||
@ -134,6 +121,19 @@ fi
|
|||||||
|
|
||||||
parse_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server`
|
parse_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server`
|
||||||
|
|
||||||
|
#
|
||||||
|
# Set pid file if not given
|
||||||
|
#
|
||||||
|
if test -z "$pid_file"
|
||||||
|
then
|
||||||
|
pid_file=$datadir/`@HOSTNAME@`.pid
|
||||||
|
else
|
||||||
|
case "$pid_file" in
|
||||||
|
/* ) ;;
|
||||||
|
* ) pid_file="$datadir/$pid_file" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
# Safeguard (relative paths, core dumps..)
|
# Safeguard (relative paths, core dumps..)
|
||||||
cd $basedir
|
cd $basedir
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user