Merge from mysql-5.5-bugfixing to mysql-5.5-runtime.
This commit is contained in:
commit
dd4cd40a87
@ -6228,8 +6228,10 @@ get_one_option(int optid, const struct my_option *opt, char *argument)
|
|||||||
print_version();
|
print_version();
|
||||||
exit(0);
|
exit(0);
|
||||||
case OPT_MYSQL_PROTOCOL:
|
case OPT_MYSQL_PROTOCOL:
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
|
opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
|
||||||
opt->name);
|
opt->name);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
usage();
|
usage();
|
||||||
|
@ -27,7 +27,7 @@ dnl
|
|||||||
dnl When changing the major version number please also check the switch
|
dnl When changing the major version number please also check the switch
|
||||||
dnl statement in mysqlbinlog::check_master_version(). You may also need
|
dnl statement in mysqlbinlog::check_master_version(). You may also need
|
||||||
dnl to update version.c in ndb.
|
dnl to update version.c in ndb.
|
||||||
AC_INIT([MySQL Server], [5.5.6-m3], [], [mysql])
|
AC_INIT([MySQL Server], [5.5.7-m3], [], [mysql])
|
||||||
|
|
||||||
AC_CONFIG_SRCDIR([sql/mysqld.cc])
|
AC_CONFIG_SRCDIR([sql/mysqld.cc])
|
||||||
AC_CANONICAL_SYSTEM
|
AC_CANONICAL_SYSTEM
|
||||||
|
@ -26,6 +26,8 @@ HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \
|
|||||||
pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
|
pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
|
||||||
my_xml.h mysql_embed.h mysql/services.h \
|
my_xml.h mysql_embed.h mysql/services.h \
|
||||||
mysql/service_my_snprintf.h mysql/service_thd_alloc.h \
|
mysql/service_my_snprintf.h mysql/service_thd_alloc.h \
|
||||||
|
mysql/service_thread_scheduler.h \
|
||||||
|
mysql/service_thd_wait.h \
|
||||||
my_pthread.h my_no_pthread.h \
|
my_pthread.h my_no_pthread.h \
|
||||||
decimal.h errmsg.h my_global.h my_net.h \
|
decimal.h errmsg.h my_global.h my_net.h \
|
||||||
my_getopt.h sslopt-longopts.h my_dir.h \
|
my_getopt.h sslopt-longopts.h my_dir.h \
|
||||||
|
@ -71,7 +71,7 @@ typedef struct st_mysql_xid MYSQL_XID;
|
|||||||
Plugin API. Common for all plugin types.
|
Plugin API. Common for all plugin types.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0101
|
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0102
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The allowable types of plugins
|
The allowable types of plugins
|
||||||
|
@ -31,6 +31,27 @@ void *thd_memdup(void* thd, const void* str, unsigned int size);
|
|||||||
MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
|
MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
|
||||||
const char *str, unsigned int size,
|
const char *str, unsigned int size,
|
||||||
int allocate_lex_string);
|
int allocate_lex_string);
|
||||||
|
#include <mysql/service_thd_wait.h>
|
||||||
|
typedef enum _thd_wait_type_e {
|
||||||
|
THD_WAIT_MUTEX= 1,
|
||||||
|
THD_WAIT_DISKIO= 2,
|
||||||
|
THD_WAIT_ROW_TABLE_LOCK= 3,
|
||||||
|
THD_WAIT_GLOBAL_LOCK= 4
|
||||||
|
} thd_wait_type;
|
||||||
|
extern struct thd_wait_service_st {
|
||||||
|
void (*thd_wait_begin_func)(void*, thd_wait_type);
|
||||||
|
void (*thd_wait_end_func)(void*);
|
||||||
|
} *thd_wait_service;
|
||||||
|
void thd_wait_begin(void* thd, thd_wait_type wait_type);
|
||||||
|
void thd_wait_end(void* thd);
|
||||||
|
#include <mysql/service_thread_scheduler.h>
|
||||||
|
struct scheduler_functions;
|
||||||
|
extern struct my_thread_scheduler_service {
|
||||||
|
int (*set)(struct scheduler_functions *scheduler);
|
||||||
|
int (*reset)();
|
||||||
|
} *my_thread_scheduler_service;
|
||||||
|
int my_thread_scheduler_set(struct scheduler_functions *scheduler);
|
||||||
|
int my_thread_scheduler_reset();
|
||||||
struct st_mysql_xid {
|
struct st_mysql_xid {
|
||||||
long formatID;
|
long formatID;
|
||||||
long gtrid_length;
|
long gtrid_length;
|
||||||
|
@ -31,6 +31,27 @@ void *thd_memdup(void* thd, const void* str, unsigned int size);
|
|||||||
MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
|
MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
|
||||||
const char *str, unsigned int size,
|
const char *str, unsigned int size,
|
||||||
int allocate_lex_string);
|
int allocate_lex_string);
|
||||||
|
#include <mysql/service_thd_wait.h>
|
||||||
|
typedef enum _thd_wait_type_e {
|
||||||
|
THD_WAIT_MUTEX= 1,
|
||||||
|
THD_WAIT_DISKIO= 2,
|
||||||
|
THD_WAIT_ROW_TABLE_LOCK= 3,
|
||||||
|
THD_WAIT_GLOBAL_LOCK= 4
|
||||||
|
} thd_wait_type;
|
||||||
|
extern struct thd_wait_service_st {
|
||||||
|
void (*thd_wait_begin_func)(void*, thd_wait_type);
|
||||||
|
void (*thd_wait_end_func)(void*);
|
||||||
|
} *thd_wait_service;
|
||||||
|
void thd_wait_begin(void* thd, thd_wait_type wait_type);
|
||||||
|
void thd_wait_end(void* thd);
|
||||||
|
#include <mysql/service_thread_scheduler.h>
|
||||||
|
struct scheduler_functions;
|
||||||
|
extern struct my_thread_scheduler_service {
|
||||||
|
int (*set)(struct scheduler_functions *scheduler);
|
||||||
|
int (*reset)();
|
||||||
|
} *my_thread_scheduler_service;
|
||||||
|
int my_thread_scheduler_set(struct scheduler_functions *scheduler);
|
||||||
|
int my_thread_scheduler_reset();
|
||||||
struct st_mysql_xid {
|
struct st_mysql_xid {
|
||||||
long formatID;
|
long formatID;
|
||||||
long gtrid_length;
|
long gtrid_length;
|
||||||
|
83
include/mysql/service_thd_wait.h
Normal file
83
include/mysql/service_thd_wait.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/* Copyright (C) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
|
||||||
|
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; version 2 of the License.
|
||||||
|
|
||||||
|
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 */
|
||||||
|
|
||||||
|
#ifndef MYSQL_SERVICE_THD_WAIT_INCLUDED
|
||||||
|
#define MYSQL_SERVICE_THD_WAIT_INCLUDED
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file include/mysql/service_thd_wait.h
|
||||||
|
This service provides functions for plugins and storage engines to report
|
||||||
|
when they are going to sleep/stall.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
thd_wait_begin() - call just before a wait begins
|
||||||
|
thd Thread object
|
||||||
|
Use NULL if the thd is NOT known.
|
||||||
|
wait_type Type of wait
|
||||||
|
1 -- short wait (e.g. for mutex)
|
||||||
|
2 -- medium wait (e.g. for disk io)
|
||||||
|
3 -- large wait (e.g. for locked row/table)
|
||||||
|
NOTES
|
||||||
|
This is used by the threadpool to have better knowledge of which
|
||||||
|
threads that currently are actively running on CPUs. When a thread
|
||||||
|
reports that it's going to sleep/stall, the threadpool scheduler is
|
||||||
|
free to start another thread in the pool most likely. The expected wait
|
||||||
|
time is simply an indication of how long the wait is expected to
|
||||||
|
become, the real wait time could be very different.
|
||||||
|
|
||||||
|
thd_wait_end() called immediately after the wait is complete
|
||||||
|
|
||||||
|
thd_wait_end() MUST be called if thd_wait_begin() was called.
|
||||||
|
|
||||||
|
Using thd_wait_...() service is optional but recommended. Using it will
|
||||||
|
improve performance as the thread pool will be more active at managing the
|
||||||
|
thread workload.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum _thd_wait_type_e {
|
||||||
|
THD_WAIT_MUTEX= 1,
|
||||||
|
THD_WAIT_DISKIO= 2,
|
||||||
|
THD_WAIT_ROW_TABLE_LOCK= 3,
|
||||||
|
THD_WAIT_GLOBAL_LOCK= 4
|
||||||
|
} thd_wait_type;
|
||||||
|
|
||||||
|
extern struct thd_wait_service_st {
|
||||||
|
void (*thd_wait_begin_func)(MYSQL_THD, thd_wait_type);
|
||||||
|
void (*thd_wait_end_func)(MYSQL_THD);
|
||||||
|
} *thd_wait_service;
|
||||||
|
|
||||||
|
#ifdef MYSQL_DYNAMIC_PLUGIN
|
||||||
|
|
||||||
|
#define thd_wait_begin(_THD, _WAIT_TYPE) \
|
||||||
|
thd_wait_service->thd_wait_begin_func(_THD, _WAIT_TYPE)
|
||||||
|
#define thd_wait_end(_THD) thd_wait_service->thd_wait_end_func(_THD)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void thd_wait_begin(MYSQL_THD thd, thd_wait_type wait_type);
|
||||||
|
void thd_wait_end(MYSQL_THD thd);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
65
include/mysql/service_thread_scheduler.h
Normal file
65
include/mysql/service_thread_scheduler.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
|
||||||
|
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; version 2 of the License.
|
||||||
|
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SERVICE_THREAD_SCHEDULER_INCLUDED
|
||||||
|
#define SERVICE_THREAD_SCHEDULER_INCLUDED
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct scheduler_functions;
|
||||||
|
|
||||||
|
extern struct my_thread_scheduler_service {
|
||||||
|
int (*set)(struct scheduler_functions *scheduler);
|
||||||
|
int (*reset)();
|
||||||
|
} *my_thread_scheduler_service;
|
||||||
|
|
||||||
|
#ifdef MYSQL_DYNAMIC_PLUGIN
|
||||||
|
|
||||||
|
#define my_thread_scheduler_set(F) my_thread_scheduler_service->set((F))
|
||||||
|
#define my_thread_scheduler_reset() my_thread_scheduler_service->reset()
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set the thread scheduler to use for the server.
|
||||||
|
|
||||||
|
@param scheduler Pointer to scheduler callbacks to use.
|
||||||
|
@retval 0 Scheduler installed correctly.
|
||||||
|
@retval 1 Invalid value (NULL) used for scheduler.
|
||||||
|
*/
|
||||||
|
int my_thread_scheduler_set(struct scheduler_functions *scheduler);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Restore the previous thread scheduler.
|
||||||
|
|
||||||
|
@note If no thread scheduler was installed previously with
|
||||||
|
thd_set_thread_scheduler, this function will report an error.
|
||||||
|
|
||||||
|
@retval 0 Scheduler installed correctly.
|
||||||
|
@retval 1 No scheduler installed.
|
||||||
|
*/
|
||||||
|
int my_thread_scheduler_reset();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SERVICE_THREAD_SCHEDULER_INCLUDED */
|
@ -20,6 +20,8 @@ extern "C" {
|
|||||||
|
|
||||||
#include <mysql/service_my_snprintf.h>
|
#include <mysql/service_my_snprintf.h>
|
||||||
#include <mysql/service_thd_alloc.h>
|
#include <mysql/service_thd_alloc.h>
|
||||||
|
#include <mysql/service_thd_wait.h>
|
||||||
|
#include <mysql/service_thread_scheduler.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -21,4 +21,5 @@
|
|||||||
|
|
||||||
#define VERSION_my_snprintf 0x0100
|
#define VERSION_my_snprintf 0x0100
|
||||||
#define VERSION_thd_alloc 0x0100
|
#define VERSION_thd_alloc 0x0100
|
||||||
|
#define VERSION_thd_wait 0x0100
|
||||||
|
#define VERSION_my_thread_scheduler 0x0100
|
||||||
|
@ -155,6 +155,8 @@ void thr_downgrade_write_lock(THR_LOCK_DATA *data,
|
|||||||
enum thr_lock_type new_lock_type);
|
enum thr_lock_type new_lock_type);
|
||||||
my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data,
|
my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data,
|
||||||
ulong lock_wait_timeout);
|
ulong lock_wait_timeout);
|
||||||
|
void thr_set_lock_wait_callback(void (*before_wait)(void),
|
||||||
|
void (*after_wait)(void));
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -217,6 +217,7 @@ struct st_vio
|
|||||||
void (*timeout)(Vio*, unsigned int which, unsigned int timeout);
|
void (*timeout)(Vio*, unsigned int which, unsigned int timeout);
|
||||||
my_bool (*poll_read)(Vio *vio, uint timeout);
|
my_bool (*poll_read)(Vio *vio, uint timeout);
|
||||||
my_bool (*is_connected)(Vio*);
|
my_bool (*is_connected)(Vio*);
|
||||||
|
my_bool (*has_data) (Vio*);
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
void *ssl_arg;
|
void *ssl_arg;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,21 +1,17 @@
|
|||||||
# Copyright (C) 2001-2006 MySQL AB
|
# Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
#
|
#
|
||||||
# This library is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# modify it under the terms of the GNU Library General Public
|
# it under the terms of the GNU General Public License as published by
|
||||||
# License as published by the Free Software Foundation; version 2
|
# the Free Software Foundation; version 2 of the License.
|
||||||
# of the License.
|
|
||||||
#
|
#
|
||||||
# This library is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# Library General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Library General Public
|
# You should have received a copy of the GNU General Public License
|
||||||
# License along with this library; if not, write to the Free
|
# along with this program; if not, write to the Free Software
|
||||||
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
# MA 02111-1307, USA
|
|
||||||
#
|
|
||||||
# This file is public domain and comes with NO WARRANTY of any kind
|
|
||||||
|
|
||||||
MYSQLDATAdir = $(localstatedir)
|
MYSQLDATAdir = $(localstatedir)
|
||||||
MYSQLSHAREdir = $(pkgdatadir)
|
MYSQLSHAREdir = $(pkgdatadir)
|
||||||
|
@ -15,7 +15,11 @@
|
|||||||
|
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
|
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
|
||||||
|
|
||||||
SET(MYSQLSERVICES_SOURCES my_snprintf_service.c thd_alloc_service.c)
|
SET(MYSQLSERVICES_SOURCES
|
||||||
|
my_snprintf_service.c
|
||||||
|
thd_alloc_service.c
|
||||||
|
thd_wait_service.c
|
||||||
|
my_thread_scheduler_service.c)
|
||||||
|
|
||||||
ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
|
ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
|
||||||
INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR})
|
INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR})
|
||||||
|
@ -15,5 +15,7 @@
|
|||||||
|
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
pkglib_LIBRARIES = libmysqlservices.a
|
pkglib_LIBRARIES = libmysqlservices.a
|
||||||
libmysqlservices_a_SOURCES = my_snprintf_service.c thd_alloc_service.c
|
libmysqlservices_a_SOURCES = my_snprintf_service.c thd_alloc_service.c \
|
||||||
|
thd_wait_service.c \
|
||||||
|
my_thread_scheduler_service.c
|
||||||
EXTRA_DIST = CMakeLists.txt
|
EXTRA_DIST = CMakeLists.txt
|
||||||
|
21
libservices/my_thread_scheduler_service.c
Normal file
21
libservices/my_thread_scheduler_service.c
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
|
||||||
|
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; version 2 of the License.
|
||||||
|
|
||||||
|
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 <service_versions.h>
|
||||||
|
SERVICE_VERSION my_thread_scheduler_service=
|
||||||
|
(void*)VERSION_my_thread_scheduler;
|
19
libservices/thd_wait_service.c
Normal file
19
libservices/thd_wait_service.c
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
|
||||||
|
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; version 2 of the License.
|
||||||
|
|
||||||
|
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 <service_versions.h>
|
||||||
|
SERVICE_VERSION *thd_wait_service= (void*)VERSION_thd_wait;
|
@ -13,6 +13,7 @@
|
|||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
IF(INSTALL_MYSQLTESTDIR)
|
||||||
INSTALL(
|
INSTALL(
|
||||||
DIRECTORY .
|
DIRECTORY .
|
||||||
DESTINATION ${INSTALL_MYSQLTESTDIR}
|
DESTINATION ${INSTALL_MYSQLTESTDIR}
|
||||||
@ -28,6 +29,7 @@ INSTALL(
|
|||||||
PATTERN "*.am" EXCLUDE
|
PATTERN "*.am" EXCLUDE
|
||||||
PATTERN "*.in" EXCLUDE
|
PATTERN "*.in" EXCLUDE
|
||||||
)
|
)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -48,9 +50,11 @@ IF(UNIX)
|
|||||||
./mysql-test-run.pl mysql-test-run
|
./mysql-test-run.pl mysql-test-run
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
)
|
)
|
||||||
|
IF(INSTALL_MYSQLTESTDIR)
|
||||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mtr
|
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mtr
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/mysql-test-run
|
${CMAKE_CURRENT_BINARY_DIR}/mysql-test-run
|
||||||
DESTINATION ${INSTALL_MYSQLTESTDIR})
|
DESTINATION ${INSTALL_MYSQLTESTDIR})
|
||||||
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(CMAKE_GENERATOR MATCHES "Visual Studio")
|
IF(CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||||
|
5
mysql-test/include/not_blackhole.inc
Normal file
5
mysql-test/include/not_blackhole.inc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
if (`SELECT count(*) FROM information_schema.engines WHERE
|
||||||
|
(support = 'YES' OR support = 'DEFAULT') AND
|
||||||
|
engine = 'blackhole'`){
|
||||||
|
skip Blackhole engine enabled;
|
||||||
|
}
|
@ -499,4 +499,13 @@ INDEX(a), INDEX(b), INDEX(c));
|
|||||||
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);
|
||||||
DELETE FROM t1 WHERE a = 10 OR b = 20 ORDER BY c LIMIT 1;
|
DELETE FROM t1 WHERE a = 10 OR b = 20 ORDER BY c LIMIT 1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Bug #53034: Multiple-table DELETE statements not accepting
|
||||||
|
# "Access compatibility" syntax
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (id INT);
|
||||||
|
CREATE TABLE t2 LIKE t1;
|
||||||
|
CREATE TABLE t3 LIKE t1;
|
||||||
|
DELETE FROM t1.*, test.t2.*, a.* USING t1, t2, t3 AS a;
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
@ -1003,6 +1003,7 @@ SELECT 1 FROM
|
|||||||
1
|
1
|
||||||
1
|
1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
End of 5.0 tests
|
||||||
#
|
#
|
||||||
# Bug #52397: another crash with explain extended and group_concat
|
# Bug #52397: another crash with explain extended and group_concat
|
||||||
#
|
#
|
||||||
@ -1019,6 +1020,25 @@ Warnings:
|
|||||||
Note 1003 select 1 AS `1` from dual
|
Note 1003 select 1 AS `1` from dual
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
#
|
||||||
|
# Bug #54476: crash when group_concat and 'with rollup' in prepared statements
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1), (2);
|
||||||
|
PREPARE stmt FROM "SELECT GROUP_CONCAT(t1.a ORDER BY t1.a) FROM t1 JOIN t1 t2 GROUP BY t1.a WITH ROLLUP";
|
||||||
|
EXECUTE stmt;
|
||||||
|
GROUP_CONCAT(t1.a ORDER BY t1.a)
|
||||||
|
1,1
|
||||||
|
2,2
|
||||||
|
1,1,2,2
|
||||||
|
EXECUTE stmt;
|
||||||
|
GROUP_CONCAT(t1.a ORDER BY t1.a)
|
||||||
|
1,1
|
||||||
|
2,2
|
||||||
|
1,1,2,2
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
DROP TABLE t1;
|
||||||
|
End of 5.1 tests
|
||||||
DROP TABLE IF EXISTS t1, t2;
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
CREATE TABLE t1 (a VARCHAR(6), b INT);
|
CREATE TABLE t1 (a VARCHAR(6), b INT);
|
||||||
CREATE TABLE t2 (a VARCHAR(6), b INT);
|
CREATE TABLE t2 (a VARCHAR(6), b INT);
|
||||||
|
@ -1713,6 +1713,17 @@ f1 f2 f3 f4 f1 = f2
|
|||||||
NULL NULL NULL NULL NULL
|
NULL NULL NULL NULL NULL
|
||||||
drop table t1;
|
drop table t1;
|
||||||
#
|
#
|
||||||
|
# Bug #54465: assert: field_types == 0 || field_types[field_pos] ==
|
||||||
|
# MYSQL_TYPE_LONGLONG
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1), (2);
|
||||||
|
SELECT MAX((SELECT 1 FROM t1 ORDER BY @var LIMIT 1)) m FROM t1 t2, t1
|
||||||
|
ORDER BY t1.a;
|
||||||
|
m
|
||||||
|
1
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
#
|
#
|
||||||
# Bug#55648: Server crash on MIN/MAX on maximum time value
|
# Bug#55648: Server crash on MIN/MAX on maximum time value
|
||||||
|
@ -337,6 +337,21 @@ select connection_id() > 0;
|
|||||||
connection_id() > 0
|
connection_id() > 0
|
||||||
1
|
1
|
||||||
#
|
#
|
||||||
|
# Bug #54461: crash with longblob and union or update with subquery
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT, b LONGBLOB);
|
||||||
|
INSERT INTO t1 VALUES (1, '2'), (2, '3'), (3, '2');
|
||||||
|
SELECT DISTINCT LEAST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1;
|
||||||
|
LEAST(a, (SELECT b FROM t1 LIMIT 1))
|
||||||
|
1
|
||||||
|
2
|
||||||
|
SELECT DISTINCT GREATEST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1;
|
||||||
|
GREATEST(a, (SELECT b FROM t1 LIMIT 1))
|
||||||
|
2
|
||||||
|
3
|
||||||
|
1
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# Bug #52165: Assertion failed: file .\dtoa.c, line 465
|
# Bug #52165: Assertion failed: file .\dtoa.c, line 465
|
||||||
#
|
#
|
||||||
CREATE TABLE t1 (a SET('a'), b INT);
|
CREATE TABLE t1 (a SET('a'), b INT);
|
||||||
|
@ -1305,4 +1305,12 @@ date_sub("0069-01-01 00:00:01",INTERVAL 2 SECOND)
|
|||||||
select date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND);
|
select date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND)
|
date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND)
|
||||||
0168-12-31 23:59:59
|
0168-12-31 23:59:59
|
||||||
|
CREATE TABLE t1(a DOUBLE NOT NULL);
|
||||||
|
INSERT INTO t1 VALUES (0),(9.216e-096);
|
||||||
|
# should not crash
|
||||||
|
SELECT 1 FROM t1 ORDER BY @x:=makedate(a,a);
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
@ -688,7 +688,7 @@ The following options may be given as the first argument:
|
|||||||
How many threads we should keep in a cache for reuse
|
How many threads we should keep in a cache for reuse
|
||||||
--thread-handling=name
|
--thread-handling=name
|
||||||
Define threads usage for handling queries, one of
|
Define threads usage for handling queries, one of
|
||||||
one-thread-per-connection, no-threads
|
one-thread-per-connection, no-threads, loaded-dynamically
|
||||||
--thread-stack=# The stack size for each thread
|
--thread-stack=# The stack size for each thread
|
||||||
--time-format=name The TIME format (ignored)
|
--time-format=name The TIME format (ignored)
|
||||||
--timed-mutexes Specify whether to time mutexes (only InnoDB mutexes are
|
--timed-mutexes Specify whether to time mutexes (only InnoDB mutexes are
|
||||||
|
@ -692,7 +692,7 @@ The following options may be given as the first argument:
|
|||||||
How many threads we should keep in a cache for reuse
|
How many threads we should keep in a cache for reuse
|
||||||
--thread-handling=name
|
--thread-handling=name
|
||||||
Define threads usage for handling queries, one of
|
Define threads usage for handling queries, one of
|
||||||
one-thread-per-connection, no-threads
|
one-thread-per-connection, no-threads, loaded-dynamically
|
||||||
--thread-stack=# The stack size for each thread
|
--thread-stack=# The stack size for each thread
|
||||||
--time-format=name The TIME format (ignored)
|
--time-format=name The TIME format (ignored)
|
||||||
--timed-mutexes Specify whether to time mutexes (only InnoDB mutexes are
|
--timed-mutexes Specify whether to time mutexes (only InnoDB mutexes are
|
||||||
|
16
mysql-test/r/partition_not_blackhole.result
Normal file
16
mysql-test/r/partition_not_blackhole.result
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
#
|
||||||
|
# Bug#46086: crash when dropping a partitioned table and
|
||||||
|
# the original engine is disabled
|
||||||
|
# Copy a .frm and .par file which was created with:
|
||||||
|
# create table `t1` (`id` int primary key) engine=blackhole
|
||||||
|
# partition by key () partitions 1;
|
||||||
|
SHOW TABLES;
|
||||||
|
Tables_in_test
|
||||||
|
t1
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
ERROR HY000: Incorrect information in file: './test/t1.frm'
|
||||||
|
DROP TABLE t1;
|
||||||
|
ERROR 42S02: Unknown table 't1'
|
||||||
|
t1.frm
|
||||||
|
t1.par
|
@ -1653,4 +1653,17 @@ a b
|
|||||||
0 0
|
0 0
|
||||||
1 1
|
1 1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Bug #54802: 'NOT BETWEEN' evaluation is incorrect
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (c_key INT, c_notkey INT, KEY(c_key));
|
||||||
|
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 ALL c_key NULL NULL NULL 3 Using where
|
||||||
|
SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
|
||||||
|
c_key c_notkey
|
||||||
|
1 1
|
||||||
|
3 3
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
BIN
mysql-test/std_data/parts/t1_blackhole.frm
Normal file
BIN
mysql-test/std_data/parts/t1_blackhole.frm
Normal file
Binary file not shown.
BIN
mysql-test/std_data/parts/t1_blackhole.par
Normal file
BIN
mysql-test/std_data/parts/t1_blackhole.par
Normal file
Binary file not shown.
@ -2549,6 +2549,64 @@ LOCK TABLES t1 READ;
|
|||||||
ALTER TABLE t1 COMMENT 'test';
|
ALTER TABLE t1 COMMENT 'test';
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Bug#55656: mysqldump can be slower after bug #39653 fix
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT , b INT, c INT, d INT,
|
||||||
|
KEY (b), PRIMARY KEY (a,b)) ENGINE=INNODB;
|
||||||
|
INSERT INTO t1 VALUES (1,1,1,1), (2,2,2,2), (3,3,3,3);
|
||||||
|
EXPLAIN SELECT COUNT(*) FROM t1;
|
||||||
|
id 1
|
||||||
|
select_type SIMPLE
|
||||||
|
table t1
|
||||||
|
type index
|
||||||
|
possible_keys NULL
|
||||||
|
key b
|
||||||
|
key_len 4
|
||||||
|
ref NULL
|
||||||
|
rows 3
|
||||||
|
Extra Using index
|
||||||
|
DROP INDEX b ON t1;
|
||||||
|
CREATE INDEX b ON t1(a,b);
|
||||||
|
EXPLAIN SELECT COUNT(*) FROM t1;
|
||||||
|
id 1
|
||||||
|
select_type SIMPLE
|
||||||
|
table t1
|
||||||
|
type index
|
||||||
|
possible_keys NULL
|
||||||
|
key b
|
||||||
|
key_len 8
|
||||||
|
ref NULL
|
||||||
|
rows 3
|
||||||
|
Extra Using index
|
||||||
|
DROP INDEX b ON t1;
|
||||||
|
CREATE INDEX b ON t1(a,b,c);
|
||||||
|
EXPLAIN SELECT COUNT(*) FROM t1;
|
||||||
|
id 1
|
||||||
|
select_type SIMPLE
|
||||||
|
table t1
|
||||||
|
type index
|
||||||
|
possible_keys NULL
|
||||||
|
key b
|
||||||
|
key_len 13
|
||||||
|
ref NULL
|
||||||
|
rows 3
|
||||||
|
Extra Using index
|
||||||
|
DROP INDEX b ON t1;
|
||||||
|
CREATE INDEX b ON t1(a,b,c,d);
|
||||||
|
EXPLAIN SELECT COUNT(*) FROM t1;
|
||||||
|
id 1
|
||||||
|
select_type SIMPLE
|
||||||
|
table t1
|
||||||
|
type index
|
||||||
|
possible_keys NULL
|
||||||
|
key PRIMARY
|
||||||
|
key_len 8
|
||||||
|
ref NULL
|
||||||
|
rows 3
|
||||||
|
Extra Using index
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
#
|
#
|
||||||
# Test for bug #39932 "create table fails if column for FK is in different
|
# Test for bug #39932 "create table fails if column for FK is in different
|
||||||
|
@ -746,6 +746,31 @@ UNLOCK TABLES;
|
|||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#55656: mysqldump can be slower after bug #39653 fix
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT , b INT, c INT, d INT,
|
||||||
|
KEY (b), PRIMARY KEY (a,b)) ENGINE=INNODB;
|
||||||
|
INSERT INTO t1 VALUES (1,1,1,1), (2,2,2,2), (3,3,3,3);
|
||||||
|
--query_vertical EXPLAIN SELECT COUNT(*) FROM t1
|
||||||
|
|
||||||
|
DROP INDEX b ON t1;
|
||||||
|
CREATE INDEX b ON t1(a,b);
|
||||||
|
--query_vertical EXPLAIN SELECT COUNT(*) FROM t1
|
||||||
|
|
||||||
|
DROP INDEX b ON t1;
|
||||||
|
CREATE INDEX b ON t1(a,b,c);
|
||||||
|
--query_vertical EXPLAIN SELECT COUNT(*) FROM t1
|
||||||
|
|
||||||
|
DROP INDEX b ON t1;
|
||||||
|
CREATE INDEX b ON t1(a,b,c,d);
|
||||||
|
--query_vertical EXPLAIN SELECT COUNT(*) FROM t1
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
|
||||||
|
@ -4,12 +4,8 @@ reset master;
|
|||||||
reset slave;
|
reset slave;
|
||||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
start slave;
|
start slave;
|
||||||
# Make sure the 'master_log.err-old' file does not
|
|
||||||
# exist before execute 'flush error logs' statement.
|
|
||||||
# Test if support 'flush error logs' statement.
|
# Test if support 'flush error logs' statement.
|
||||||
flush error logs;
|
flush error logs;
|
||||||
# Check the 'master_log.err-old' file is created
|
|
||||||
# after executed 'flush error logs' statement.
|
|
||||||
# Make sure binary logs was not be flushed
|
# Make sure binary logs was not be flushed
|
||||||
# after execute 'flush error logs' statement.
|
# after execute 'flush error logs' statement.
|
||||||
# Make sure relay logs was not be flushed
|
# Make sure relay logs was not be flushed
|
||||||
@ -42,12 +38,8 @@ flush binary logs;
|
|||||||
# after executed 'flush binary logs' statement.
|
# after executed 'flush binary logs' statement.
|
||||||
# Make sure the 'slave-relay-bin.000007' file does not exist
|
# Make sure the 'slave-relay-bin.000007' file does not exist
|
||||||
# exist before execute 'flush error logs, relay logs' statement.
|
# exist before execute 'flush error logs, relay logs' statement.
|
||||||
# Make sure the 'master_log.err-old' file does not exist
|
|
||||||
# before execute 'flush error logs, relay logs' statement.
|
|
||||||
# Test if support to combine all kinds of logs into one statement.
|
# Test if support to combine all kinds of logs into one statement.
|
||||||
flush error logs, relay logs;
|
flush error logs, relay logs;
|
||||||
# Check the 'master_log.err-old' file is created
|
|
||||||
# after executed 'flush error logs, relay logs' statement.
|
|
||||||
# Make sure binary logs was not be flushed
|
# Make sure binary logs was not be flushed
|
||||||
# after execute 'flush error logs, relay logs' statement.
|
# after execute 'flush error logs, relay logs' statement.
|
||||||
# Check the 'slave-relay-bin.000007' file is created after
|
# Check the 'slave-relay-bin.000007' file is created after
|
||||||
@ -55,12 +47,8 @@ flush error logs, relay logs;
|
|||||||
# Make sure the 'slave-relay-bin.000008' and 'slave-relay-bin.000009'
|
# Make sure the 'slave-relay-bin.000008' and 'slave-relay-bin.000009'
|
||||||
# files do not exist before execute 'flush error logs, relay logs'
|
# files do not exist before execute 'flush error logs, relay logs'
|
||||||
# statement.
|
# statement.
|
||||||
# Make sure the 'master_log.err-old' file does not exist
|
|
||||||
# before execute 'flush logs' statement.
|
|
||||||
# Test if 'flush logs' statement works fine and flush all the logs.
|
# Test if 'flush logs' statement works fine and flush all the logs.
|
||||||
flush logs;
|
flush logs;
|
||||||
# Check the 'master_log.err-old' file is created
|
|
||||||
# after executed 'flush logs' statement.
|
|
||||||
# Check 'master-bin.000003' is created
|
# Check 'master-bin.000003' is created
|
||||||
# after execute 'flush logs' statement.
|
# after execute 'flush logs' statement.
|
||||||
# Check the 'slave-relay-bin.000008' and 'slave-relay-bin.000009'
|
# Check the 'slave-relay-bin.000008' and 'slave-relay-bin.000009'
|
||||||
|
@ -10,3 +10,4 @@ drop table t1, t2;
|
|||||||
sync_slave_with_master;
|
sync_slave_with_master;
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
|
||||||
|
@ -9,17 +9,10 @@
|
|||||||
connection master;
|
connection master;
|
||||||
|
|
||||||
# Test 'flush error logs' statement.
|
# Test 'flush error logs' statement.
|
||||||
--echo # Make sure the 'master_log.err-old' file does not
|
|
||||||
--echo # exist before execute 'flush error logs' statement.
|
|
||||||
--error 1
|
|
||||||
file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
|
|
||||||
|
|
||||||
--echo # Test if support 'flush error logs' statement.
|
--echo # Test if support 'flush error logs' statement.
|
||||||
flush error logs;
|
flush error logs;
|
||||||
|
|
||||||
--echo # Check the 'master_log.err-old' file is created
|
|
||||||
--echo # after executed 'flush error logs' statement.
|
|
||||||
file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
|
|
||||||
file_exists $MYSQLTEST_VARDIR/tmp/master_log.err;
|
file_exists $MYSQLTEST_VARDIR/tmp/master_log.err;
|
||||||
|
|
||||||
--echo # Make sure binary logs was not be flushed
|
--echo # Make sure binary logs was not be flushed
|
||||||
@ -109,19 +102,10 @@ sync_slave_with_master;
|
|||||||
file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000007;
|
file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000007;
|
||||||
|
|
||||||
connection master;
|
connection master;
|
||||||
remove_file $MYSQLTEST_VARDIR/tmp/master_log.err-old;
|
|
||||||
|
|
||||||
--echo # Make sure the 'master_log.err-old' file does not exist
|
|
||||||
--echo # before execute 'flush error logs, relay logs' statement.
|
|
||||||
--error 1
|
|
||||||
file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
|
|
||||||
|
|
||||||
--echo # Test if support to combine all kinds of logs into one statement.
|
--echo # Test if support to combine all kinds of logs into one statement.
|
||||||
flush error logs, relay logs;
|
flush error logs, relay logs;
|
||||||
|
|
||||||
--echo # Check the 'master_log.err-old' file is created
|
|
||||||
--echo # after executed 'flush error logs, relay logs' statement.
|
|
||||||
file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
|
|
||||||
file_exists $MYSQLTEST_VARDIR/tmp/master_log.err;
|
file_exists $MYSQLTEST_VARDIR/tmp/master_log.err;
|
||||||
|
|
||||||
--echo # Make sure binary logs was not be flushed
|
--echo # Make sure binary logs was not be flushed
|
||||||
@ -145,19 +129,10 @@ file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000008;
|
|||||||
file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000009;
|
file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000009;
|
||||||
|
|
||||||
connection master;
|
connection master;
|
||||||
remove_file $MYSQLTEST_VARDIR/tmp/master_log.err-old;
|
|
||||||
|
|
||||||
--echo # Make sure the 'master_log.err-old' file does not exist
|
|
||||||
--echo # before execute 'flush logs' statement.
|
|
||||||
--error 1
|
|
||||||
file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
|
|
||||||
|
|
||||||
--echo # Test if 'flush logs' statement works fine and flush all the logs.
|
--echo # Test if 'flush logs' statement works fine and flush all the logs.
|
||||||
flush logs;
|
flush logs;
|
||||||
|
|
||||||
--echo # Check the 'master_log.err-old' file is created
|
|
||||||
--echo # after executed 'flush logs' statement.
|
|
||||||
file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
|
|
||||||
file_exists $MYSQLTEST_VARDIR/tmp/master_log.err;
|
file_exists $MYSQLTEST_VARDIR/tmp/master_log.err;
|
||||||
|
|
||||||
--echo # Check 'master-bin.000003' is created
|
--echo # Check 'master-bin.000003' is created
|
||||||
|
@ -540,4 +540,17 @@ DELETE FROM t1 WHERE a = 10 OR b = 20 ORDER BY c LIMIT 1;
|
|||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #53034: Multiple-table DELETE statements not accepting
|
||||||
|
--echo # "Access compatibility" syntax
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (id INT);
|
||||||
|
CREATE TABLE t2 LIKE t1;
|
||||||
|
CREATE TABLE t3 LIKE t1;
|
||||||
|
|
||||||
|
DELETE FROM t1.*, test.t2.*, a.* USING t1, t2, t3 AS a;
|
||||||
|
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
@ -708,6 +708,7 @@ SELECT 1 FROM
|
|||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Bug #52397: another crash with explain extended and group_concat
|
--echo # Bug #52397: another crash with explain extended and group_concat
|
||||||
@ -722,6 +723,26 @@ DROP TABLE t1;
|
|||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #54476: crash when group_concat and 'with rollup' in prepared statements
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1), (2);
|
||||||
|
|
||||||
|
PREPARE stmt FROM "SELECT GROUP_CONCAT(t1.a ORDER BY t1.a) FROM t1 JOIN t1 t2 GROUP BY t1.a WITH ROLLUP";
|
||||||
|
EXECUTE stmt;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo End of 5.1 tests
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug#36785: Wrong error message when group_concat() exceeds max length
|
# Bug#36785: Wrong error message when group_concat() exceeds max length
|
||||||
#
|
#
|
||||||
|
@ -1082,6 +1082,20 @@ select a.f1 as a, b.f4 as b, a.f1 > b.f4 as gt,
|
|||||||
from t1 a, t1 b;
|
from t1 a, t1 b;
|
||||||
select *, f1 = f2 from t1;
|
select *, f1 = f2 from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #54465: assert: field_types == 0 || field_types[field_pos] ==
|
||||||
|
--echo # MYSQL_TYPE_LONGLONG
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1), (2);
|
||||||
|
|
||||||
|
SELECT MAX((SELECT 1 FROM t1 ORDER BY @var LIMIT 1)) m FROM t1 t2, t1
|
||||||
|
ORDER BY t1.a;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
|
||||||
|
@ -467,6 +467,19 @@ select NAME_CONST('_id',1234) as id;
|
|||||||
|
|
||||||
select connection_id() > 0;
|
select connection_id() > 0;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #54461: crash with longblob and union or update with subquery
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT, b LONGBLOB);
|
||||||
|
INSERT INTO t1 VALUES (1, '2'), (2, '3'), (3, '2');
|
||||||
|
|
||||||
|
SELECT DISTINCT LEAST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1;
|
||||||
|
SELECT DISTINCT GREATEST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Bug #52165: Assertion failed: file .\dtoa.c, line 465
|
--echo # Bug #52165: Assertion failed: file .\dtoa.c, line 465
|
||||||
--echo #
|
--echo #
|
||||||
@ -478,4 +491,5 @@ SELECT COALESCE(a) = COALESCE(b) FROM t1;
|
|||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo End of tests
|
--echo End of tests
|
||||||
|
@ -821,4 +821,15 @@ select date_sub("0069-01-01 00:00:01",INTERVAL 2 SECOND);
|
|||||||
select date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND);
|
select date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #55565: debug assertion when ordering by expressions with user
|
||||||
|
# variable assignments
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1(a DOUBLE NOT NULL);
|
||||||
|
INSERT INTO t1 VALUES (0),(9.216e-096);
|
||||||
|
--echo # should not crash
|
||||||
|
SELECT 1 FROM t1 ORDER BY @x:=makedate(a,a);
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
1
mysql-test/t/partition_not_blackhole-master.opt
Normal file
1
mysql-test/t/partition_not_blackhole-master.opt
Normal file
@ -0,0 +1 @@
|
|||||||
|
--loose-skip-blackhole
|
26
mysql-test/t/partition_not_blackhole.test
Normal file
26
mysql-test/t/partition_not_blackhole.test
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
--source include/have_partition.inc
|
||||||
|
--source include/not_blackhole.inc
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
let $MYSQLD_DATADIR= `SELECT @@datadir`;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#46086: crash when dropping a partitioned table and
|
||||||
|
--echo # the original engine is disabled
|
||||||
|
--echo # Copy a .frm and .par file which was created with:
|
||||||
|
--echo # create table `t1` (`id` int primary key) engine=blackhole
|
||||||
|
--echo # partition by key () partitions 1;
|
||||||
|
--copy_file std_data/parts/t1_blackhole.frm $MYSQLD_DATADIR/test/t1.frm
|
||||||
|
--copy_file std_data/parts/t1_blackhole.par $MYSQLD_DATADIR/test/t1.par
|
||||||
|
SHOW TABLES;
|
||||||
|
--replace_result $MYSQLD_DATADIR ./
|
||||||
|
--error ER_NOT_FORM_FILE
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
--error ER_BAD_TABLE_ERROR
|
||||||
|
DROP TABLE t1;
|
||||||
|
--list_files $MYSQLD_DATADIR/test t1*
|
||||||
|
--remove_file $MYSQLD_DATADIR/test/t1.frm
|
||||||
|
--remove_file $MYSQLD_DATADIR/test/t1.par
|
@ -1313,4 +1313,16 @@ SELECT * FROM t1 FORCE INDEX (PRIMARY)
|
|||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #54802: 'NOT BETWEEN' evaluation is incorrect
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (c_key INT, c_notkey INT, KEY(c_key));
|
||||||
|
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
|
||||||
|
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
|
||||||
|
SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
@ -163,7 +163,6 @@ int handle_options(int *argc, char ***argv,
|
|||||||
int error, i;
|
int error, i;
|
||||||
my_bool is_cmdline_arg= 1;
|
my_bool is_cmdline_arg= 1;
|
||||||
|
|
||||||
LINT_INIT(opt_found);
|
|
||||||
/* handle_options() assumes arg0 (program name) always exists */
|
/* handle_options() assumes arg0 (program name) always exists */
|
||||||
DBUG_ASSERT(argc && *argc >= 1);
|
DBUG_ASSERT(argc && *argc >= 1);
|
||||||
DBUG_ASSERT(argv && *argv);
|
DBUG_ASSERT(argv && *argv);
|
||||||
@ -188,6 +187,7 @@ int handle_options(int *argc, char ***argv,
|
|||||||
{
|
{
|
||||||
char **first= pos;
|
char **first= pos;
|
||||||
char *cur_arg= *pos;
|
char *cur_arg= *pos;
|
||||||
|
opt_found= 0;
|
||||||
if (!is_cmdline_arg && (cur_arg == args_separator))
|
if (!is_cmdline_arg && (cur_arg == args_separator))
|
||||||
{
|
{
|
||||||
is_cmdline_arg= 1;
|
is_cmdline_arg= 1;
|
||||||
|
@ -477,7 +477,7 @@ static my_bool win32_init_tcp_ip()
|
|||||||
{
|
{
|
||||||
if (win32_have_tcpip())
|
if (win32_have_tcpip())
|
||||||
{
|
{
|
||||||
WORD wVersionRequested = MAKEWORD( 2, 0 );
|
WORD wVersionRequested = MAKEWORD( 2, 2 );
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
/* Be a good citizen: maybe another lib has already initialised
|
/* Be a good citizen: maybe another lib has already initialised
|
||||||
sockets, so dont clobber them unless necessary */
|
sockets, so dont clobber them unless necessary */
|
||||||
|
@ -91,6 +91,16 @@ enum thr_lock_type thr_upgraded_concurrent_insert_lock = TL_WRITE;
|
|||||||
LIST *thr_lock_thread_list; /* List of threads in use */
|
LIST *thr_lock_thread_list; /* List of threads in use */
|
||||||
ulong max_write_lock_count= ~(ulong) 0L;
|
ulong max_write_lock_count= ~(ulong) 0L;
|
||||||
|
|
||||||
|
static void (*before_lock_wait)(void)= 0;
|
||||||
|
static void (*after_lock_wait)(void)= 0;
|
||||||
|
|
||||||
|
void thr_set_lock_wait_callback(void (*before_wait)(void),
|
||||||
|
void (*after_wait)(void))
|
||||||
|
{
|
||||||
|
before_lock_wait= before_wait;
|
||||||
|
after_lock_wait= after_wait;
|
||||||
|
}
|
||||||
|
|
||||||
static inline mysql_cond_t *get_cond(void)
|
static inline mysql_cond_t *get_cond(void)
|
||||||
{
|
{
|
||||||
return &my_thread_var->suspend;
|
return &my_thread_var->suspend;
|
||||||
@ -431,6 +441,19 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
|
|||||||
old_proc_info= proc_info_hook(NULL, "Waiting for table level lock",
|
old_proc_info= proc_info_hook(NULL, "Waiting for table level lock",
|
||||||
__func__, __FILE__, __LINE__);
|
__func__, __FILE__, __LINE__);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Since before_lock_wait potentially can create more threads to
|
||||||
|
scheduler work for, we don't want to call the before_lock_wait
|
||||||
|
callback unless it will really start to wait.
|
||||||
|
|
||||||
|
For similar reasons, we do not want to call before_lock_wait and
|
||||||
|
after_lock_wait for each lap around the loop, so we restrict
|
||||||
|
ourselves to call it before_lock_wait once before starting to wait
|
||||||
|
and once after the thread has exited the wait loop.
|
||||||
|
*/
|
||||||
|
if ((!thread_var->abort || in_wait_list) && before_lock_wait)
|
||||||
|
(*before_lock_wait)();
|
||||||
|
|
||||||
set_timespec(wait_timeout, lock_wait_timeout);
|
set_timespec(wait_timeout, lock_wait_timeout);
|
||||||
while (!thread_var->abort || in_wait_list)
|
while (!thread_var->abort || in_wait_list)
|
||||||
{
|
{
|
||||||
@ -462,6 +485,14 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
|
|||||||
/* purecov: end */
|
/* purecov: end */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
We call the after_lock_wait callback once the wait loop has
|
||||||
|
finished.
|
||||||
|
*/
|
||||||
|
if (after_lock_wait)
|
||||||
|
(*after_lock_wait)();
|
||||||
|
|
||||||
DBUG_PRINT("thr_lock", ("aborted: %d in_wait_list: %d",
|
DBUG_PRINT("thr_lock", ("aborted: %d in_wait_list: %d",
|
||||||
thread_var->abort, in_wait_list));
|
thread_var->abort, in_wait_list));
|
||||||
|
|
||||||
|
@ -271,8 +271,7 @@ IF(WIN32 AND MYSQLD_EXECUTABLE)
|
|||||||
COMMAND ${CMAKE_COMMAND}
|
COMMAND ${CMAKE_COMMAND}
|
||||||
${CONFIG_PARAM} -P ${CMAKE_CURRENT_BINARY_DIR}/create_initial_db.cmake
|
${CONFIG_PARAM} -P ${CMAKE_CURRENT_BINARY_DIR}/create_initial_db.cmake
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data
|
||||||
COMMAND ${CMAKE_COMMAND} -E touch initdb.dep
|
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/initdb.dep
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
DEPENDS mysqld
|
DEPENDS mysqld
|
||||||
)
|
)
|
||||||
ADD_CUSTOM_TARGET(initial_database
|
ADD_CUSTOM_TARGET(initial_database
|
||||||
|
@ -93,6 +93,7 @@ struct show_table_authors_st show_table_authors[]= {
|
|||||||
{ "Arjen Lentz", "Brisbane, Australia",
|
{ "Arjen Lentz", "Brisbane, Australia",
|
||||||
"Documentation (2001-2004), Dutch error messages, LOG2()" },
|
"Documentation (2001-2004), Dutch error messages, LOG2()" },
|
||||||
{ "Marc Liyanage", "", "Created Mac OS X packages" },
|
{ "Marc Liyanage", "", "Created Mac OS X packages" },
|
||||||
|
{ "Kelly Long", "Denver, CO, USA", "Pool Of Threads" },
|
||||||
{ "Zarko Mocnik", "", "Sorting for Slovenian language" },
|
{ "Zarko Mocnik", "", "Sorting for Slovenian language" },
|
||||||
{ "Per-Erik Martin", "Uppsala, Sweden", "Stored Procedures (5.0)" },
|
{ "Per-Erik Martin", "Uppsala, Sweden", "Stored Procedures (5.0)" },
|
||||||
{ "Alexis Mikhailov", "", "User-defined functions" },
|
{ "Alexis Mikhailov", "", "User-defined functions" },
|
||||||
|
@ -2446,9 +2446,14 @@ bool ha_partition::get_from_handler_file(const char *name, MEM_ROOT *mem_root)
|
|||||||
tot_partition_words= (m_tot_parts + 3) / 4;
|
tot_partition_words= (m_tot_parts + 3) / 4;
|
||||||
engine_array= (handlerton **) my_alloca(m_tot_parts * sizeof(handlerton*));
|
engine_array= (handlerton **) my_alloca(m_tot_parts * sizeof(handlerton*));
|
||||||
for (i= 0; i < m_tot_parts; i++)
|
for (i= 0; i < m_tot_parts; i++)
|
||||||
|
{
|
||||||
engine_array[i]= ha_resolve_by_legacy_type(ha_thd(),
|
engine_array[i]= ha_resolve_by_legacy_type(ha_thd(),
|
||||||
(enum legacy_db_type)
|
(enum legacy_db_type)
|
||||||
*(uchar *) ((file_buffer) + 12 + i));
|
*(uchar *) ((file_buffer) +
|
||||||
|
12 + i));
|
||||||
|
if (!engine_array[i])
|
||||||
|
goto err3;
|
||||||
|
}
|
||||||
address_tot_name_len= file_buffer + 12 + 4 * tot_partition_words;
|
address_tot_name_len= file_buffer + 12 + 4 * tot_partition_words;
|
||||||
tot_name_words= (uint4korr(address_tot_name_len) + 3) / 4;
|
tot_name_words= (uint4korr(address_tot_name_len) + 3) / 4;
|
||||||
if (len_words != (tot_partition_words + tot_name_words + 4))
|
if (len_words != (tot_partition_words + tot_name_words + 4))
|
||||||
|
@ -2533,6 +2533,8 @@ void Item_func_min_max::fix_length_and_dec()
|
|||||||
decimals,
|
decimals,
|
||||||
unsigned_flag));
|
unsigned_flag));
|
||||||
}
|
}
|
||||||
|
else if (cmp_type == REAL_RESULT)
|
||||||
|
fix_char_length(float_length(decimals));
|
||||||
cached_field_type= agg_field_type(args, arg_count);
|
cached_field_type= agg_field_type(args, arg_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,26 +434,6 @@ void Item_sum::mark_as_sum_func()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item_sum::make_field(Send_field *tmp_field)
|
|
||||||
{
|
|
||||||
if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
|
|
||||||
{
|
|
||||||
((Item_field*) args[0])->field->make_field(tmp_field);
|
|
||||||
/* For expressions only col_name should be non-empty string. */
|
|
||||||
char *empty_string= (char*)"";
|
|
||||||
tmp_field->db_name= empty_string;
|
|
||||||
tmp_field->org_table_name= empty_string;
|
|
||||||
tmp_field->table_name= empty_string;
|
|
||||||
tmp_field->org_col_name= empty_string;
|
|
||||||
tmp_field->col_name= name;
|
|
||||||
if (maybe_null)
|
|
||||||
tmp_field->flags&= ~NOT_NULL_FLAG;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
init_make_field(tmp_field, field_type());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Item_sum::print(String *str, enum_query_type query_type)
|
void Item_sum::print(String *str, enum_query_type query_type)
|
||||||
{
|
{
|
||||||
/* orig_args is not filled with valid values until fix_fields() */
|
/* orig_args is not filled with valid values until fix_fields() */
|
||||||
@ -984,7 +964,8 @@ bool Aggregator_distinct::add()
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
copy_fields(tmp_table_param);
|
copy_fields(tmp_table_param);
|
||||||
copy_funcs(tmp_table_param->items_to_copy);
|
if (copy_funcs(tmp_table_param->items_to_copy, table->in_use))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
for (Field **field=table->field ; *field ; field++)
|
for (Field **field=table->field ; *field ; field++)
|
||||||
if ((*field)->is_real_null(0))
|
if ((*field)->is_real_null(0))
|
||||||
@ -3058,7 +3039,6 @@ Item_func_group_concat::Item_func_group_concat(THD *thd,
|
|||||||
tree(item->tree),
|
tree(item->tree),
|
||||||
unique_filter(item->unique_filter),
|
unique_filter(item->unique_filter),
|
||||||
table(item->table),
|
table(item->table),
|
||||||
order(item->order),
|
|
||||||
context(item->context),
|
context(item->context),
|
||||||
arg_count_order(item->arg_count_order),
|
arg_count_order(item->arg_count_order),
|
||||||
arg_count_field(item->arg_count_field),
|
arg_count_field(item->arg_count_field),
|
||||||
@ -3071,6 +3051,24 @@ Item_func_group_concat::Item_func_group_concat(THD *thd,
|
|||||||
{
|
{
|
||||||
quick_group= item->quick_group;
|
quick_group= item->quick_group;
|
||||||
result.set_charset(collation.collation);
|
result.set_charset(collation.collation);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Since the ORDER structures pointed to by the elements of the 'order' array
|
||||||
|
may be modified in find_order_in_list() called from
|
||||||
|
Item_func_group_concat::setup(), create a copy of those structures so that
|
||||||
|
such modifications done in this object would not have any effect on the
|
||||||
|
object being copied.
|
||||||
|
*/
|
||||||
|
ORDER *tmp;
|
||||||
|
if (!(order= (ORDER **) thd->alloc(sizeof(ORDER *) * arg_count_order +
|
||||||
|
sizeof(ORDER) * arg_count_order)))
|
||||||
|
return;
|
||||||
|
tmp= (ORDER *)(order + arg_count_order);
|
||||||
|
for (uint i= 0; i < arg_count_order; i++, tmp++)
|
||||||
|
{
|
||||||
|
memcpy(tmp, item->order[i], sizeof(ORDER));
|
||||||
|
order[i]= tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3136,7 +3134,8 @@ bool Item_func_group_concat::add()
|
|||||||
if (always_null)
|
if (always_null)
|
||||||
return 0;
|
return 0;
|
||||||
copy_fields(tmp_table_param);
|
copy_fields(tmp_table_param);
|
||||||
copy_funcs(tmp_table_param->items_to_copy);
|
if (copy_funcs(tmp_table_param->items_to_copy, table->in_use))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
for (uint i= 0; i < arg_count_field; i++)
|
for (uint i= 0; i < arg_count_field; i++)
|
||||||
{
|
{
|
||||||
|
@ -427,7 +427,6 @@ public:
|
|||||||
forced_const= TRUE;
|
forced_const= TRUE;
|
||||||
}
|
}
|
||||||
virtual bool const_item() const { return forced_const; }
|
virtual bool const_item() const { return forced_const; }
|
||||||
void make_field(Send_field *field);
|
|
||||||
virtual void print(String *str, enum_query_type query_type);
|
virtual void print(String *str, enum_query_type query_type);
|
||||||
void fix_num_length_and_dec();
|
void fix_num_length_and_dec();
|
||||||
|
|
||||||
|
109
sql/log.cc
109
sql/log.cc
@ -5447,67 +5447,90 @@ void sql_perror(const char *message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __WIN__
|
||||||
|
extern "C" my_bool reopen_fstreams(const char *filename,
|
||||||
|
FILE *outstream, FILE *errstream)
|
||||||
|
{
|
||||||
|
int handle_fd;
|
||||||
|
int stream_fd;
|
||||||
|
HANDLE osfh;
|
||||||
|
|
||||||
|
DBUG_ASSERT(filename && (outstream || errstream));
|
||||||
|
|
||||||
|
if ((osfh= CreateFile(filename, GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE |
|
||||||
|
FILE_SHARE_DELETE, NULL,
|
||||||
|
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL)) == INVALID_HANDLE_VALUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if ((handle_fd= _open_osfhandle((intptr_t)osfh,
|
||||||
|
_O_APPEND | _O_TEXT)) == -1)
|
||||||
|
{
|
||||||
|
CloseHandle(osfh);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outstream)
|
||||||
|
{
|
||||||
|
stream_fd= _fileno(outstream);
|
||||||
|
if (_dup2(handle_fd, stream_fd) < 0)
|
||||||
|
{
|
||||||
|
CloseHandle(osfh);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errstream)
|
||||||
|
{
|
||||||
|
stream_fd= _fileno(errstream);
|
||||||
|
if (_dup2(handle_fd, stream_fd) < 0)
|
||||||
|
{
|
||||||
|
CloseHandle(osfh);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_close(handle_fd);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
extern "C" my_bool reopen_fstreams(const char *filename,
|
||||||
|
FILE *outstream, FILE *errstream)
|
||||||
|
{
|
||||||
|
if (outstream && !freopen(filename, "a+", outstream))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (errstream && !freopen(filename, "a+", errstream))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Unfortunately, there seems to be no good way
|
Unfortunately, there seems to be no good way
|
||||||
to restore the original streams upon failure.
|
to restore the original streams upon failure.
|
||||||
*/
|
*/
|
||||||
static bool redirect_std_streams(const char *file)
|
static bool redirect_std_streams(const char *file)
|
||||||
{
|
{
|
||||||
if (freopen(file, "a+", stdout) && freopen(file, "a+", stderr))
|
if (reopen_fstreams(file, stdout, stderr))
|
||||||
{
|
return TRUE;
|
||||||
|
|
||||||
setbuf(stderr, NULL);
|
setbuf(stderr, NULL);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool flush_error_log()
|
bool flush_error_log()
|
||||||
{
|
{
|
||||||
bool result=0;
|
bool result= 0;
|
||||||
if (opt_error_log)
|
if (opt_error_log)
|
||||||
{
|
{
|
||||||
char err_renamed[FN_REFLEN], *end;
|
|
||||||
end= strmake(err_renamed,log_error_file,FN_REFLEN-5);
|
|
||||||
strmov(end, "-old");
|
|
||||||
mysql_mutex_lock(&LOCK_error_log);
|
mysql_mutex_lock(&LOCK_error_log);
|
||||||
#ifdef __WIN__
|
|
||||||
char err_temp[FN_REFLEN+5];
|
|
||||||
/*
|
|
||||||
On Windows is necessary a temporary file for to rename
|
|
||||||
the current error file.
|
|
||||||
*/
|
|
||||||
strxmov(err_temp, err_renamed,"-tmp",NullS);
|
|
||||||
my_delete(err_temp, MYF(0));
|
|
||||||
if (freopen(err_temp,"a+",stdout))
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
size_t bytes;
|
|
||||||
uchar buf[IO_SIZE];
|
|
||||||
|
|
||||||
freopen(err_temp,"a+",stderr);
|
|
||||||
setbuf(stderr, NULL);
|
|
||||||
my_delete(err_renamed, MYF(0));
|
|
||||||
my_rename(log_error_file, err_renamed, MYF(0));
|
|
||||||
redirect_std_streams(log_error_file);
|
|
||||||
|
|
||||||
if ((fd= my_open(err_temp, O_RDONLY, MYF(0))) >= 0)
|
|
||||||
{
|
|
||||||
while ((bytes= mysql_file_read(fd, buf, IO_SIZE, MYF(0))) &&
|
|
||||||
bytes != MY_FILE_ERROR)
|
|
||||||
my_fwrite(stderr, buf, bytes, MYF(0));
|
|
||||||
mysql_file_close(fd, MYF(0));
|
|
||||||
}
|
|
||||||
my_delete(err_temp, MYF(0));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result= 1;
|
|
||||||
#else
|
|
||||||
my_rename(log_error_file, err_renamed, MYF(0));
|
|
||||||
if (redirect_std_streams(log_error_file))
|
if (redirect_std_streams(log_error_file))
|
||||||
result= 1;
|
result= 1;
|
||||||
#endif
|
|
||||||
mysql_mutex_unlock(&LOCK_error_log);
|
mysql_mutex_unlock(&LOCK_error_log);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -394,10 +394,10 @@ public:
|
|||||||
/* Use this to start writing a new log file */
|
/* Use this to start writing a new log file */
|
||||||
void new_file();
|
void new_file();
|
||||||
|
|
||||||
bool write(Log_event* event_info);
|
bool write(Log_event* event_info); // binary log write
|
||||||
bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event, bool incident);
|
bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event, bool incident);
|
||||||
bool write_incident(THD *thd, bool lock);
|
|
||||||
|
|
||||||
|
bool write_incident(THD *thd, bool lock);
|
||||||
int write_cache(IO_CACHE *cache, bool lock_log, bool flush_and_sync);
|
int write_cache(IO_CACHE *cache, bool lock_log, bool flush_and_sync);
|
||||||
void set_write_error(THD *thd);
|
void set_write_error(THD *thd);
|
||||||
bool check_write_error(THD *thd);
|
bool check_write_error(THD *thd);
|
||||||
|
@ -64,7 +64,9 @@
|
|||||||
#include "events.h"
|
#include "events.h"
|
||||||
#include "sql_audit.h"
|
#include "sql_audit.h"
|
||||||
#include "probes_mysql.h"
|
#include "probes_mysql.h"
|
||||||
|
#include "scheduler.h"
|
||||||
#include "debug_sync.h"
|
#include "debug_sync.h"
|
||||||
|
#include "sql_callback.h"
|
||||||
|
|
||||||
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
|
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
|
||||||
#include "../storage/perfschema/pfs_server.h"
|
#include "../storage/perfschema/pfs_server.h"
|
||||||
@ -193,6 +195,9 @@ typedef fp_except fp_except_t;
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern "C" my_bool reopen_fstreams(const char *filename,
|
||||||
|
FILE *outstream, FILE *errstream);
|
||||||
|
|
||||||
inline void setup_fpu()
|
inline void setup_fpu()
|
||||||
{
|
{
|
||||||
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
|
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
|
||||||
@ -456,7 +461,7 @@ ulong slave_trans_retries;
|
|||||||
uint slave_net_timeout;
|
uint slave_net_timeout;
|
||||||
ulong slave_exec_mode_options;
|
ulong slave_exec_mode_options;
|
||||||
ulonglong slave_type_conversions_options;
|
ulonglong slave_type_conversions_options;
|
||||||
ulong thread_cache_size=0, thread_pool_size= 0;
|
ulong thread_cache_size=0;
|
||||||
ulong binlog_cache_size=0;
|
ulong binlog_cache_size=0;
|
||||||
ulonglong max_binlog_cache_size=0;
|
ulonglong max_binlog_cache_size=0;
|
||||||
ulong query_cache_size=0;
|
ulong query_cache_size=0;
|
||||||
@ -898,8 +903,6 @@ my_bool opt_enable_shared_memory;
|
|||||||
HANDLE smem_event_connect_request= 0;
|
HANDLE smem_event_connect_request= 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
scheduler_functions thread_scheduler;
|
|
||||||
|
|
||||||
my_bool opt_use_ssl = 0;
|
my_bool opt_use_ssl = 0;
|
||||||
char *opt_ssl_ca= NULL, *opt_ssl_capath= NULL, *opt_ssl_cert= NULL,
|
char *opt_ssl_ca= NULL, *opt_ssl_capath= NULL, *opt_ssl_cert= NULL,
|
||||||
*opt_ssl_cipher= NULL, *opt_ssl_key= NULL;
|
*opt_ssl_cipher= NULL, *opt_ssl_key= NULL;
|
||||||
@ -1087,7 +1090,8 @@ static void close_connections(void)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
tmp->killed= THD::KILL_CONNECTION;
|
tmp->killed= THD::KILL_CONNECTION;
|
||||||
thread_scheduler.post_kill_notification(tmp);
|
MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp));
|
||||||
|
mysql_mutex_lock(&tmp->LOCK_thd_data);
|
||||||
if (tmp->mysys_var)
|
if (tmp->mysys_var)
|
||||||
{
|
{
|
||||||
tmp->mysys_var->abort=1;
|
tmp->mysys_var->abort=1;
|
||||||
@ -1100,6 +1104,7 @@ static void close_connections(void)
|
|||||||
}
|
}
|
||||||
mysql_mutex_unlock(&tmp->mysys_var->mutex);
|
mysql_mutex_unlock(&tmp->mysys_var->mutex);
|
||||||
}
|
}
|
||||||
|
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||||
}
|
}
|
||||||
mysql_mutex_unlock(&LOCK_thread_count); // For unlink from list
|
mysql_mutex_unlock(&LOCK_thread_count); // For unlink from list
|
||||||
|
|
||||||
@ -1479,7 +1484,7 @@ void clean_up(bool print_message)
|
|||||||
if (print_message && my_default_lc_messages && server_start_time)
|
if (print_message && my_default_lc_messages && server_start_time)
|
||||||
sql_print_information(ER_DEFAULT(ER_SHUTDOWN_COMPLETE),my_progname);
|
sql_print_information(ER_DEFAULT(ER_SHUTDOWN_COMPLETE),my_progname);
|
||||||
cleanup_errmsgs();
|
cleanup_errmsgs();
|
||||||
thread_scheduler.end();
|
MYSQL_CALLBACK(thread_scheduler, end, ());
|
||||||
finish_client_errs();
|
finish_client_errs();
|
||||||
DBUG_PRINT("quit", ("Error messages freed"));
|
DBUG_PRINT("quit", ("Error messages freed"));
|
||||||
/* Tell main we are ready */
|
/* Tell main we are ready */
|
||||||
@ -1752,7 +1757,7 @@ static void network_init(void)
|
|||||||
DBUG_ENTER("network_init");
|
DBUG_ENTER("network_init");
|
||||||
LINT_INIT(ret);
|
LINT_INIT(ret);
|
||||||
|
|
||||||
if (thread_scheduler.init())
|
if (MYSQL_CALLBACK_ELSE(thread_scheduler, init, (), 0))
|
||||||
unireg_abort(1); /* purecov: inspected */
|
unireg_abort(1); /* purecov: inspected */
|
||||||
|
|
||||||
set_ports();
|
set_ports();
|
||||||
@ -2000,7 +2005,7 @@ extern "C" sig_handler end_thread_signal(int sig __attribute__((unused)))
|
|||||||
if (thd && ! thd->bootstrap)
|
if (thd && ! thd->bootstrap)
|
||||||
{
|
{
|
||||||
statistic_increment(killed_threads, &LOCK_status);
|
statistic_increment(killed_threads, &LOCK_status);
|
||||||
thread_scheduler.end_thread(thd,0); /* purecov: inspected */
|
MYSQL_CALLBACK(thread_scheduler, end_thread, (thd,0)); /* purecov: inspected */
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN; /* purecov: deadcode */
|
DBUG_VOID_RETURN; /* purecov: deadcode */
|
||||||
}
|
}
|
||||||
@ -2396,7 +2401,7 @@ and this may fail.\n\n");
|
|||||||
(ulong) dflt_key_cache->key_cache_mem_size);
|
(ulong) dflt_key_cache->key_cache_mem_size);
|
||||||
fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
|
fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
|
||||||
fprintf(stderr, "max_used_connections=%lu\n", max_used_connections);
|
fprintf(stderr, "max_used_connections=%lu\n", max_used_connections);
|
||||||
fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads);
|
fprintf(stderr, "max_threads=%u\n", thread_scheduler->max_threads);
|
||||||
fprintf(stderr, "thread_count=%u\n", thread_count);
|
fprintf(stderr, "thread_count=%u\n", thread_count);
|
||||||
fprintf(stderr, "connection_count=%u\n", connection_count);
|
fprintf(stderr, "connection_count=%u\n", connection_count);
|
||||||
fprintf(stderr, "It is possible that mysqld could use up to \n\
|
fprintf(stderr, "It is possible that mysqld could use up to \n\
|
||||||
@ -2404,7 +2409,7 @@ key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = %lu K\n\
|
|||||||
bytes of memory\n", ((ulong) dflt_key_cache->key_cache_mem_size +
|
bytes of memory\n", ((ulong) dflt_key_cache->key_cache_mem_size +
|
||||||
(global_system_variables.read_buff_size +
|
(global_system_variables.read_buff_size +
|
||||||
global_system_variables.sortbuff_size) *
|
global_system_variables.sortbuff_size) *
|
||||||
thread_scheduler.max_threads +
|
thread_scheduler->max_threads +
|
||||||
max_connections * sizeof(THD)) / 1024);
|
max_connections * sizeof(THD)) / 1024);
|
||||||
fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
|
fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
|
||||||
|
|
||||||
@ -2651,7 +2656,7 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
|
|||||||
This should actually be '+ max_number_of_slaves' instead of +10,
|
This should actually be '+ max_number_of_slaves' instead of +10,
|
||||||
but the +10 should be quite safe.
|
but the +10 should be quite safe.
|
||||||
*/
|
*/
|
||||||
init_thr_alarm(thread_scheduler.max_threads +
|
init_thr_alarm(thread_scheduler->max_threads +
|
||||||
global_system_variables.max_insert_delayed_threads + 10);
|
global_system_variables.max_insert_delayed_threads + 10);
|
||||||
if (thd_lib_detected != THD_LIB_LT && (test_flags & TEST_SIGINT))
|
if (thd_lib_detected != THD_LIB_LT && (test_flags & TEST_SIGINT))
|
||||||
{
|
{
|
||||||
@ -3738,15 +3743,17 @@ static int init_server_components()
|
|||||||
opt_error_log= 0; // Too long file name
|
opt_error_log= 0; // Too long file name
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
my_bool res;
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
if (freopen(log_error_file, "a+", stdout))
|
res= reopen_fstreams(log_error_file, stdout, stderr);
|
||||||
|
#else
|
||||||
|
res= reopen_fstreams(log_error_file, NULL, stderr);
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
if (freopen(log_error_file, "a+", stderr))
|
if (!res)
|
||||||
setbuf(stderr, NULL);
|
setbuf(stderr, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
proc_info_hook= set_thd_proc_info;
|
proc_info_hook= set_thd_proc_info;
|
||||||
|
|
||||||
@ -4353,23 +4360,6 @@ int mysqld_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __WIN__
|
|
||||||
/*
|
|
||||||
Before performing any socket operation (like retrieving hostname
|
|
||||||
in init_common_variables we have to call WSAStartup
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
WSADATA WsaData;
|
|
||||||
if (SOCKET_ERROR == WSAStartup (0x0101, &WsaData))
|
|
||||||
{
|
|
||||||
/* errors are not read yet, so we use english text here */
|
|
||||||
my_message(ER_WSAS_FAILED, "WSAStartup Failed", MYF(0));
|
|
||||||
/* Not enough initializations for unireg_abort() */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* __WIN__ */
|
|
||||||
|
|
||||||
if (init_common_variables())
|
if (init_common_variables())
|
||||||
unireg_abort(1); // Will do exit
|
unireg_abort(1); // Will do exit
|
||||||
|
|
||||||
@ -4457,8 +4447,8 @@ int mysqld_main(int argc, char **argv)
|
|||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
if (!opt_console)
|
if (!opt_console)
|
||||||
{
|
{
|
||||||
freopen(log_error_file,"a+",stdout);
|
if (reopen_fstreams(log_error_file, stdout, stderr))
|
||||||
freopen(log_error_file,"a+",stderr);
|
unireg_abort(1);
|
||||||
setbuf(stderr, NULL);
|
setbuf(stderr, NULL);
|
||||||
FreeConsole(); // Remove window
|
FreeConsole(); // Remove window
|
||||||
}
|
}
|
||||||
@ -5028,7 +5018,7 @@ static void create_new_thread(THD *thd)
|
|||||||
|
|
||||||
thread_count++;
|
thread_count++;
|
||||||
|
|
||||||
thread_scheduler.add_connection(thd);
|
MYSQL_CALLBACK(thread_scheduler, add_connection, (thd));
|
||||||
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
@ -7344,14 +7334,12 @@ static int get_options(int *argc_ptr, char ***argv_ptr)
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
#ifdef EMBEDDED_LIBRARY
|
#ifdef EMBEDDED_LIBRARY
|
||||||
one_thread_scheduler(&thread_scheduler);
|
one_thread_scheduler();
|
||||||
#else
|
#else
|
||||||
if (thread_handling <= SCHEDULER_ONE_THREAD_PER_CONNECTION)
|
if (thread_handling <= SCHEDULER_ONE_THREAD_PER_CONNECTION)
|
||||||
one_thread_per_connection_scheduler(&thread_scheduler);
|
one_thread_per_connection_scheduler();
|
||||||
else if (thread_handling == SCHEDULER_NO_THREADS)
|
else /* thread_handling == SCHEDULER_NO_THREADS) */
|
||||||
one_thread_scheduler(&thread_scheduler);
|
one_thread_scheduler();
|
||||||
else
|
|
||||||
pool_of_threads_scheduler(&thread_scheduler); /* purecov: tested */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
global_system_variables.engine_condition_pushdown=
|
global_system_variables.engine_condition_pushdown=
|
||||||
|
@ -28,7 +28,7 @@ class THD;
|
|||||||
struct handlerton;
|
struct handlerton;
|
||||||
class Time_zone;
|
class Time_zone;
|
||||||
|
|
||||||
class scheduler_functions;
|
struct scheduler_functions;
|
||||||
|
|
||||||
typedef struct st_mysql_const_lex_string LEX_CSTRING;
|
typedef struct st_mysql_const_lex_string LEX_CSTRING;
|
||||||
typedef struct st_mysql_show_var SHOW_VAR;
|
typedef struct st_mysql_show_var SHOW_VAR;
|
||||||
@ -175,7 +175,7 @@ extern ulong binlog_cache_size, open_files_limit;
|
|||||||
extern ulonglong max_binlog_cache_size;
|
extern ulonglong max_binlog_cache_size;
|
||||||
extern ulong max_binlog_size, max_relay_log_size;
|
extern ulong max_binlog_size, max_relay_log_size;
|
||||||
extern ulong opt_binlog_rows_event_max_size;
|
extern ulong opt_binlog_rows_event_max_size;
|
||||||
extern ulong rpl_recovery_rank, thread_cache_size, thread_pool_size;
|
extern ulong rpl_recovery_rank, thread_cache_size;
|
||||||
extern ulong back_log;
|
extern ulong back_log;
|
||||||
extern char language[FN_REFLEN];
|
extern char language[FN_REFLEN];
|
||||||
extern ulong server_id, concurrency;
|
extern ulong server_id, concurrency;
|
||||||
@ -207,7 +207,7 @@ extern my_bool old_mode;
|
|||||||
extern LEX_STRING opt_init_connect, opt_init_slave;
|
extern LEX_STRING opt_init_connect, opt_init_slave;
|
||||||
extern int bootstrap_error;
|
extern int bootstrap_error;
|
||||||
extern I_List<THD> threads;
|
extern I_List<THD> threads;
|
||||||
extern scheduler_functions thread_scheduler;
|
extern char err_shared_dir[];
|
||||||
extern TYPELIB thread_handling_typelib;
|
extern TYPELIB thread_handling_typelib;
|
||||||
extern my_decimal decimal_zero;
|
extern my_decimal decimal_zero;
|
||||||
|
|
||||||
|
@ -5620,7 +5620,11 @@ static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond)
|
|||||||
SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func,
|
SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func,
|
||||||
field_item, (Item*)(intptr)i, inv);
|
field_item, (Item*)(intptr)i, inv);
|
||||||
if (inv)
|
if (inv)
|
||||||
|
{
|
||||||
tree= !tree ? tmp : tree_or(param, tree, tmp);
|
tree= !tree ? tmp : tree_or(param, tree, tmp);
|
||||||
|
if (tree == NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
tree= tree_and(param, tree, tmp);
|
tree= tree_and(param, tree, tmp);
|
||||||
}
|
}
|
||||||
|
169
sql/scheduler.cc
169
sql/scheduler.cc
@ -25,30 +25,8 @@
|
|||||||
#include "unireg.h" // REQUIRED: for other includes
|
#include "unireg.h" // REQUIRED: for other includes
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
#include "sql_connect.h" // init_new_connection_handler_thread
|
#include "sql_connect.h" // init_new_connection_handler_thread
|
||||||
|
#include "scheduler.h"
|
||||||
/*
|
#include "sql_callback.h"
|
||||||
'Dummy' functions to be used when we don't need any handling for a scheduler
|
|
||||||
event
|
|
||||||
*/
|
|
||||||
|
|
||||||
static bool init_dummy(void) {return 0;}
|
|
||||||
static void post_kill_dummy(THD* thd) {}
|
|
||||||
static void end_dummy(void) {}
|
|
||||||
static bool end_thread_dummy(THD *thd, bool cache_thread) { return 0; }
|
|
||||||
|
|
||||||
/*
|
|
||||||
Initialize default scheduler with dummy functions so that setup functions
|
|
||||||
only need to declare those that are relvant for their usage
|
|
||||||
*/
|
|
||||||
|
|
||||||
scheduler_functions::scheduler_functions()
|
|
||||||
:init(init_dummy),
|
|
||||||
init_new_connection_thread(init_new_connection_handler_thread),
|
|
||||||
add_connection(0), // Must be defined
|
|
||||||
post_kill_notification(post_kill_dummy),
|
|
||||||
end_thread(end_thread_dummy), end(end_dummy)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
End connection, in case when we are using 'no-threads'
|
End connection, in case when we are using 'no-threads'
|
||||||
@ -61,19 +39,89 @@ static bool no_threads_end(THD *thd, bool put_in_cache)
|
|||||||
return 1; // Abort handle_one_connection
|
return 1; // Abort handle_one_connection
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static scheduler_functions one_thread_scheduler_functions=
|
||||||
|
{
|
||||||
|
1, // max_threads
|
||||||
|
NULL, // init
|
||||||
|
init_new_connection_handler_thread, // init_new_connection_thread
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
handle_connection_in_main_thread, // add_connection
|
||||||
|
#else
|
||||||
|
NULL, // add_connection
|
||||||
|
#endif // EMBEDDED_LIBRARY
|
||||||
|
NULL, // thd_wait_begin
|
||||||
|
NULL, // thd_wait_end
|
||||||
|
NULL, // post_kill_notification
|
||||||
|
no_threads_end, // end_thread
|
||||||
|
NULL, // end
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
static scheduler_functions one_thread_per_connection_scheduler_functions=
|
||||||
|
{
|
||||||
|
0, // max_threads
|
||||||
|
NULL, // init
|
||||||
|
init_new_connection_handler_thread, // init_new_connection_thread
|
||||||
|
create_thread_to_handle_connection, // add_connection
|
||||||
|
NULL, // thd_wait_begin
|
||||||
|
NULL, // thd_wait_end
|
||||||
|
NULL, // post_kill_notification
|
||||||
|
one_thread_per_connection_end, // end_thread
|
||||||
|
NULL, // end
|
||||||
|
};
|
||||||
|
#endif // EMBEDDED_LIBRARY
|
||||||
|
|
||||||
|
|
||||||
|
scheduler_functions *thread_scheduler= NULL;
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
Helper functions to allow mysys to call the thread scheduler when
|
||||||
|
waiting for locks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**@{*/
|
||||||
|
static void scheduler_wait_begin(void) {
|
||||||
|
MYSQL_CALLBACK(thread_scheduler,
|
||||||
|
thd_wait_begin, (current_thd, THD_WAIT_ROW_TABLE_LOCK));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scheduler_wait_end(void) {
|
||||||
|
MYSQL_CALLBACK(thread_scheduler, thd_wait_end, (current_thd));
|
||||||
|
}
|
||||||
|
/**@}*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
Common scheduler init function.
|
||||||
|
|
||||||
|
The scheduler is either initialized by calling
|
||||||
|
one_thread_scheduler() or one_thread_per_connection_scheduler() in
|
||||||
|
mysqld.cc, so this init function will always be called.
|
||||||
|
*/
|
||||||
|
static void scheduler_init() {
|
||||||
|
thr_set_lock_wait_callback(scheduler_wait_begin, scheduler_wait_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Initialize scheduler for --thread-handling=one-thread-per-connection
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
void one_thread_per_connection_scheduler()
|
||||||
|
{
|
||||||
|
scheduler_init();
|
||||||
|
one_thread_per_connection_scheduler_functions.max_threads= max_connections;
|
||||||
|
thread_scheduler= &one_thread_per_connection_scheduler_functions;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Initailize scheduler for --thread-handling=no-threads
|
Initailize scheduler for --thread-handling=no-threads
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void one_thread_scheduler(scheduler_functions* func)
|
void one_thread_scheduler()
|
||||||
{
|
{
|
||||||
func->max_threads= 1;
|
scheduler_init();
|
||||||
#ifndef EMBEDDED_LIBRARY
|
thread_scheduler= &one_thread_scheduler_functions;
|
||||||
func->add_connection= handle_connection_in_main_thread;
|
|
||||||
#endif
|
|
||||||
func->init_new_connection_thread= init_dummy;
|
|
||||||
func->end_thread= no_threads_end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -81,11 +129,58 @@ void one_thread_scheduler(scheduler_functions* func)
|
|||||||
Initialize scheduler for --thread-handling=one-thread-per-connection
|
Initialize scheduler for --thread-handling=one-thread-per-connection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
/*
|
||||||
void one_thread_per_connection_scheduler(scheduler_functions* func)
|
thd_scheduler keeps the link between THD and events.
|
||||||
|
It's embedded in the THD class.
|
||||||
|
*/
|
||||||
|
|
||||||
|
thd_scheduler::thd_scheduler()
|
||||||
|
: m_psi(NULL), data(NULL)
|
||||||
{
|
{
|
||||||
func->max_threads= max_connections;
|
#ifndef DBUG_OFF
|
||||||
func->add_connection= create_thread_to_handle_connection;
|
dbug_explain[0]= '\0';
|
||||||
func->end_thread= one_thread_per_connection_end;
|
set_explain= FALSE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* EMBEDDED_LIBRARY */
|
|
||||||
|
|
||||||
|
thd_scheduler::~thd_scheduler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static scheduler_functions *saved_thread_scheduler;
|
||||||
|
static uint saved_thread_handling;
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int my_thread_scheduler_set(scheduler_functions *scheduler)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(scheduler != 0);
|
||||||
|
|
||||||
|
if (scheduler == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
saved_thread_scheduler= thread_scheduler;
|
||||||
|
saved_thread_handling= thread_handling;
|
||||||
|
thread_scheduler= scheduler;
|
||||||
|
// Scheduler loaded dynamically
|
||||||
|
thread_handling= SCHEDULER_TYPES_COUNT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int my_thread_scheduler_reset()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(saved_thread_scheduler != NULL);
|
||||||
|
|
||||||
|
if (saved_thread_scheduler == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
thread_scheduler= saved_thread_scheduler;
|
||||||
|
thread_handling= saved_thread_handling;
|
||||||
|
saved_thread_scheduler= 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,38 +28,77 @@ class THD;
|
|||||||
|
|
||||||
/* Functions used when manipulating threads */
|
/* Functions used when manipulating threads */
|
||||||
|
|
||||||
class scheduler_functions
|
struct scheduler_functions
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
uint max_threads;
|
uint max_threads;
|
||||||
bool (*init)(void);
|
bool (*init)(void);
|
||||||
bool (*init_new_connection_thread)(void);
|
bool (*init_new_connection_thread)(void);
|
||||||
void (*add_connection)(THD *thd);
|
void (*add_connection)(THD *thd);
|
||||||
|
void (*thd_wait_begin)(THD *thd, int wait_type);
|
||||||
|
void (*thd_wait_end)(THD *thd);
|
||||||
void (*post_kill_notification)(THD *thd);
|
void (*post_kill_notification)(THD *thd);
|
||||||
bool (*end_thread)(THD *thd, bool cache_thread);
|
bool (*end_thread)(THD *thd, bool cache_thread);
|
||||||
void (*end)(void);
|
void (*end)(void);
|
||||||
scheduler_functions();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Scheduler types enumeration.
|
||||||
|
|
||||||
|
The default of --thread-handling is the first one in the
|
||||||
|
thread_handling_names array, this array has to be consistent with
|
||||||
|
the order in this array, so to change default one has to change the
|
||||||
|
first entry in this enum and the first entry in the
|
||||||
|
thread_handling_names array.
|
||||||
|
|
||||||
|
@note The last entry of the enumeration is also used to mark the
|
||||||
|
thread handling as dynamic. In this case the name of the thread
|
||||||
|
handling is fetched from the name of the plugin that implements it.
|
||||||
|
*/
|
||||||
enum scheduler_types
|
enum scheduler_types
|
||||||
{
|
{
|
||||||
SCHEDULER_ONE_THREAD_PER_CONNECTION=0,
|
SCHEDULER_ONE_THREAD_PER_CONNECTION=0,
|
||||||
SCHEDULER_NO_THREADS,
|
SCHEDULER_NO_THREADS,
|
||||||
SCHEDULER_POOL_OF_THREADS
|
SCHEDULER_TYPES_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
void one_thread_per_connection_scheduler(scheduler_functions* func);
|
void one_thread_per_connection_scheduler();
|
||||||
void one_thread_scheduler(scheduler_functions* func);
|
void one_thread_scheduler();
|
||||||
|
|
||||||
enum pool_command_op
|
enum pool_command_op
|
||||||
{
|
{
|
||||||
NOT_IN_USE_OP= 0, NORMAL_OP= 1, CONNECT_OP, KILL_OP, DIE_OP
|
NOT_IN_USE_OP= 0, NORMAL_OP= 1, CONNECT_OP, KILL_OP, DIE_OP
|
||||||
};
|
};
|
||||||
|
|
||||||
#define HAVE_POOL_OF_THREADS 0 /* For easyer tests */
|
/*
|
||||||
#define pool_of_threads_scheduler(A) one_thread_per_connection_scheduler(A)
|
To be used for pool-of-threads (implemeneted differently on various OSs)
|
||||||
|
*/
|
||||||
class thd_scheduler
|
class thd_scheduler
|
||||||
{};
|
{
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
Thread instrumentation for the user job.
|
||||||
|
This member holds the instrumentation while the user job is not run
|
||||||
|
by a thread.
|
||||||
|
|
||||||
#endif /* SCHEDULER_INCLUDED */
|
Note that this member is not conditionally declared
|
||||||
|
(ifdef HAVE_PSI_INTERFACE), because doing so will change the binary
|
||||||
|
layout of THD, which is exposed to plugin code that may be compiled
|
||||||
|
differently.
|
||||||
|
*/
|
||||||
|
PSI_thread *m_psi;
|
||||||
|
|
||||||
|
void *data; /* scheduler-specific data structure */
|
||||||
|
|
||||||
|
# ifndef DBUG_OFF
|
||||||
|
char dbug_explain[512];
|
||||||
|
bool set_explain;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
thd_scheduler();
|
||||||
|
~thd_scheduler();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern scheduler_functions *thread_scheduler;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
43
sql/sql_callback.h
Normal file
43
sql/sql_callback.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
|
||||||
|
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; version 2 of the License.
|
||||||
|
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SQL_CALLBACK_INCLUDED
|
||||||
|
#define SQL_CALLBACK_INCLUDED
|
||||||
|
|
||||||
|
/**
|
||||||
|
Macro used for an internal callback.
|
||||||
|
|
||||||
|
The macro will check that the object exists and that the function
|
||||||
|
is defined. If that is the case, it will call the function with the
|
||||||
|
given parameters.
|
||||||
|
|
||||||
|
If the object or the function is not defined, the callback will be
|
||||||
|
considered successful (nothing needed to be done) and will
|
||||||
|
therefore return no error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MYSQL_CALLBACK(OBJ, FUNC, PARAMS) \
|
||||||
|
do { \
|
||||||
|
if ((OBJ) && ((OBJ)->FUNC)) \
|
||||||
|
(OBJ)->FUNC PARAMS; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define MYSQL_CALLBACK_ELSE(OBJ, FUNC, PARAMS, ELSE) \
|
||||||
|
(((OBJ) && ((OBJ)->FUNC)) ? (OBJ)->FUNC PARAMS : (ELSE))
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* SQL_CALLBACK_INCLUDED */
|
@ -57,6 +57,7 @@
|
|||||||
#include "transaction.h"
|
#include "transaction.h"
|
||||||
#include "debug_sync.h"
|
#include "debug_sync.h"
|
||||||
#include "sql_parse.h" // is_update_query
|
#include "sql_parse.h" // is_update_query
|
||||||
|
#include "sql_callback.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The following is used to initialise Table_ident with a internal
|
The following is used to initialise Table_ident with a internal
|
||||||
@ -1075,6 +1076,7 @@ THD::~THD()
|
|||||||
DBUG_ENTER("~THD()");
|
DBUG_ENTER("~THD()");
|
||||||
/* Ensure that no one is using THD */
|
/* Ensure that no one is using THD */
|
||||||
mysql_mutex_lock(&LOCK_thd_data);
|
mysql_mutex_lock(&LOCK_thd_data);
|
||||||
|
mysys_var=0; // Safety (shouldn't be needed)
|
||||||
mysql_mutex_unlock(&LOCK_thd_data);
|
mysql_mutex_unlock(&LOCK_thd_data);
|
||||||
add_to_status(&global_status_var, &status_var);
|
add_to_status(&global_status_var, &status_var);
|
||||||
|
|
||||||
@ -1100,7 +1102,6 @@ THD::~THD()
|
|||||||
my_free(db);
|
my_free(db);
|
||||||
db= NULL;
|
db= NULL;
|
||||||
free_root(&transaction.mem_root,MYF(0));
|
free_root(&transaction.mem_root,MYF(0));
|
||||||
mysys_var=0; // Safety (shouldn't be needed)
|
|
||||||
mysql_mutex_destroy(&LOCK_thd_data);
|
mysql_mutex_destroy(&LOCK_thd_data);
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
dbug_sentry= THD_SENTRY_GONE;
|
dbug_sentry= THD_SENTRY_GONE;
|
||||||
@ -1189,7 +1190,7 @@ void THD::awake(THD::killed_state state_to_set)
|
|||||||
{
|
{
|
||||||
thr_alarm_kill(thread_id);
|
thr_alarm_kill(thread_id);
|
||||||
if (!slave_thread)
|
if (!slave_thread)
|
||||||
thread_scheduler.post_kill_notification(this);
|
MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (this));
|
||||||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||||
if (this != current_thd)
|
if (this != current_thd)
|
||||||
{
|
{
|
||||||
@ -1258,6 +1259,15 @@ bool THD::store_globals()
|
|||||||
if (my_pthread_setspecific_ptr(THR_THD, this) ||
|
if (my_pthread_setspecific_ptr(THR_THD, this) ||
|
||||||
my_pthread_setspecific_ptr(THR_MALLOC, &mem_root))
|
my_pthread_setspecific_ptr(THR_MALLOC, &mem_root))
|
||||||
return 1;
|
return 1;
|
||||||
|
/*
|
||||||
|
mysys_var is concurrently readable by a killer thread.
|
||||||
|
It is protected by LOCK_thd_data, it is not needed to lock while the
|
||||||
|
pointer is changing from NULL not non-NULL. If the kill thread reads
|
||||||
|
NULL it doesn't refer to anything, but if it is non-NULL we need to
|
||||||
|
ensure that the thread doesn't proceed to assign another thread to
|
||||||
|
have the mysys_var reference (which in fact refers to the worker
|
||||||
|
threads local storage with key THR_KEY_mysys.
|
||||||
|
*/
|
||||||
mysys_var=my_thread_var;
|
mysys_var=my_thread_var;
|
||||||
/*
|
/*
|
||||||
Let mysqld define the thread id (not mysys)
|
Let mysqld define the thread id (not mysys)
|
||||||
@ -3187,6 +3197,60 @@ extern "C" bool thd_sqlcom_can_generate_row_events(const MYSQL_THD thd)
|
|||||||
{
|
{
|
||||||
return sqlcom_can_generate_row_events(thd);
|
return sqlcom_can_generate_row_events(thd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
extern "C" void thd_pool_wait_begin(MYSQL_THD thd, int wait_type);
|
||||||
|
extern "C" void thd_pool_wait_end(MYSQL_THD thd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Interface for MySQL Server, plugins and storage engines to report
|
||||||
|
when they are going to sleep/stall.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
thd_wait_begin()
|
||||||
|
thd Thread object
|
||||||
|
wait_type Type of wait
|
||||||
|
1 -- short wait (e.g. for mutex)
|
||||||
|
2 -- medium wait (e.g. for disk io)
|
||||||
|
3 -- large wait (e.g. for locked row/table)
|
||||||
|
NOTES
|
||||||
|
This is used by the threadpool to have better knowledge of which
|
||||||
|
threads that currently are actively running on CPUs. When a thread
|
||||||
|
reports that it's going to sleep/stall, the threadpool scheduler is
|
||||||
|
free to start another thread in the pool most likely. The expected wait
|
||||||
|
time is simply an indication of how long the wait is expected to
|
||||||
|
become, the real wait time could be very different.
|
||||||
|
|
||||||
|
thd_wait_end MUST be called immediately after waking up again.
|
||||||
|
*/
|
||||||
|
extern "C" void thd_wait_begin(MYSQL_THD thd, thd_wait_type wait_type)
|
||||||
|
{
|
||||||
|
MYSQL_CALLBACK(thread_scheduler, thd_wait_begin, (thd, wait_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Interface for MySQL Server, plugins and storage engines to report
|
||||||
|
when they waking up from a sleep/stall.
|
||||||
|
|
||||||
|
@param thd Thread handle
|
||||||
|
*/
|
||||||
|
extern "C" void thd_wait_end(MYSQL_THD thd)
|
||||||
|
{
|
||||||
|
MYSQL_CALLBACK(thread_scheduler, thd_wait_end, (thd));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
extern "C" void thd_wait_begin(MYSQL_THD thd, thd_wait_type wait_type)
|
||||||
|
{
|
||||||
|
/* do NOTHING for the embedded library */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void thd_wait_end(MYSQL_THD thd)
|
||||||
|
{
|
||||||
|
/* do NOTHING for the embedded library */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif // INNODB_COMPATIBILITY_HOOKS */
|
#endif // INNODB_COMPATIBILITY_HOOKS */
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -3370,6 +3434,13 @@ void THD::set_query_id(query_id_t new_query_id)
|
|||||||
mysql_mutex_unlock(&LOCK_thd_data);
|
mysql_mutex_unlock(&LOCK_thd_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Assign a new value to thd->mysys_var. */
|
||||||
|
void THD::set_mysys_var(struct st_my_thread_var *new_mysys_var)
|
||||||
|
{
|
||||||
|
mysql_mutex_lock(&LOCK_thd_data);
|
||||||
|
mysys_var= new_mysys_var;
|
||||||
|
mysql_mutex_unlock(&LOCK_thd_data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Leave explicit LOCK TABLES or prelocked mode and restore value of
|
Leave explicit LOCK TABLES or prelocked mode and restore value of
|
||||||
|
@ -1634,6 +1634,10 @@ public:
|
|||||||
xid_state.xid.null();
|
xid_state.xid.null();
|
||||||
free_root(&mem_root,MYF(MY_KEEP_PREALLOC));
|
free_root(&mem_root,MYF(MY_KEEP_PREALLOC));
|
||||||
}
|
}
|
||||||
|
my_bool is_active()
|
||||||
|
{
|
||||||
|
return (all.ha_list != NULL);
|
||||||
|
}
|
||||||
st_transactions()
|
st_transactions()
|
||||||
{
|
{
|
||||||
bzero((char*)this, sizeof(*this));
|
bzero((char*)this, sizeof(*this));
|
||||||
@ -2664,7 +2668,7 @@ public:
|
|||||||
virtual void set_statement(Statement *stmt);
|
virtual void set_statement(Statement *stmt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Assign a new value to thd->query and thd->query_id.
|
Assign a new value to thd->query and thd->query_id and mysys_var.
|
||||||
Protected with LOCK_thd_data mutex.
|
Protected with LOCK_thd_data mutex.
|
||||||
*/
|
*/
|
||||||
void set_query(char *query_arg, uint32 query_length_arg);
|
void set_query(char *query_arg, uint32 query_length_arg);
|
||||||
@ -2677,6 +2681,7 @@ public:
|
|||||||
open_tables= open_tables_arg;
|
open_tables= open_tables_arg;
|
||||||
mysql_mutex_unlock(&LOCK_thd_data);
|
mysql_mutex_unlock(&LOCK_thd_data);
|
||||||
}
|
}
|
||||||
|
void set_mysys_var(struct st_my_thread_var *new_mysys_var);
|
||||||
void enter_locked_tables_mode(enum_locked_tables_mode mode_arg)
|
void enter_locked_tables_mode(enum_locked_tables_mode mode_arg)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(locked_tables_mode == LTM_NONE);
|
DBUG_ASSERT(locked_tables_mode == LTM_NONE);
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "hostname.h" // inc_host_errors, ip_to_hostname,
|
#include "hostname.h" // inc_host_errors, ip_to_hostname,
|
||||||
// reset_host_errors
|
// reset_host_errors
|
||||||
#include "sql_acl.h" // acl_getroot, NO_ACCESS, SUPER_ACL
|
#include "sql_acl.h" // acl_getroot, NO_ACCESS, SUPER_ACL
|
||||||
|
#include "sql_callback.h"
|
||||||
|
|
||||||
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
|
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
|
||||||
/*
|
/*
|
||||||
@ -966,7 +967,7 @@ bool setup_connection_thread_globals(THD *thd)
|
|||||||
{
|
{
|
||||||
close_connection(thd, ER_OUT_OF_RESOURCES, 1);
|
close_connection(thd, ER_OUT_OF_RESOURCES, 1);
|
||||||
statistic_increment(aborted_connects,&LOCK_status);
|
statistic_increment(aborted_connects,&LOCK_status);
|
||||||
thread_scheduler.end_thread(thd, 0);
|
MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0));
|
||||||
return 1; // Error
|
return 1; // Error
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -989,7 +990,7 @@ bool setup_connection_thread_globals(THD *thd)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static bool login_connection(THD *thd)
|
bool login_connection(THD *thd)
|
||||||
{
|
{
|
||||||
NET *net= &thd->net;
|
NET *net= &thd->net;
|
||||||
int error;
|
int error;
|
||||||
@ -1027,7 +1028,7 @@ static bool login_connection(THD *thd)
|
|||||||
This mainly updates status variables
|
This mainly updates status variables
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void end_connection(THD *thd)
|
void end_connection(THD *thd)
|
||||||
{
|
{
|
||||||
NET *net= &thd->net;
|
NET *net= &thd->net;
|
||||||
plugin_thdvar_cleanup(thd);
|
plugin_thdvar_cleanup(thd);
|
||||||
@ -1068,7 +1069,7 @@ static void end_connection(THD *thd)
|
|||||||
Initialize THD to handle queries
|
Initialize THD to handle queries
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void prepare_new_connection_state(THD* thd)
|
void prepare_new_connection_state(THD* thd)
|
||||||
{
|
{
|
||||||
Security_context *sctx= thd->security_ctx;
|
Security_context *sctx= thd->security_ctx;
|
||||||
|
|
||||||
@ -1137,11 +1138,11 @@ void do_handle_one_connection(THD *thd_arg)
|
|||||||
|
|
||||||
thd->thr_create_utime= my_micro_time();
|
thd->thr_create_utime= my_micro_time();
|
||||||
|
|
||||||
if (thread_scheduler.init_new_connection_thread())
|
if (MYSQL_CALLBACK_ELSE(thread_scheduler, init_new_connection_thread, (), 0))
|
||||||
{
|
{
|
||||||
close_connection(thd, ER_OUT_OF_RESOURCES, 1);
|
close_connection(thd, ER_OUT_OF_RESOURCES, 1);
|
||||||
statistic_increment(aborted_connects,&LOCK_status);
|
statistic_increment(aborted_connects,&LOCK_status);
|
||||||
thread_scheduler.end_thread(thd,0);
|
MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1195,7 +1196,7 @@ void do_handle_one_connection(THD *thd_arg)
|
|||||||
|
|
||||||
end_thread:
|
end_thread:
|
||||||
close_connection(thd, 0, 1);
|
close_connection(thd, 0, 1);
|
||||||
if (thread_scheduler.end_thread(thd,1))
|
if (MYSQL_CALLBACK_ELSE(thread_scheduler, end_thread, (thd, 1), 0))
|
||||||
return; // Probably no-threads
|
return; // Probably no-threads
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -40,4 +40,8 @@ int check_user(THD *thd, enum enum_server_command command,
|
|||||||
const char *passwd, uint passwd_len, const char *db,
|
const char *passwd, uint passwd_len, const char *db,
|
||||||
bool check_count);
|
bool check_count);
|
||||||
|
|
||||||
|
bool login_connection(THD *thd);
|
||||||
|
void prepare_new_connection_state(THD* thd);
|
||||||
|
void end_connection(THD *thd);
|
||||||
|
|
||||||
#endif /* SQL_CONNECT_INCLUDED */
|
#endif /* SQL_CONNECT_INCLUDED */
|
||||||
|
@ -36,9 +36,23 @@ static struct thd_alloc_service_st thd_alloc_handler= {
|
|||||||
thd_make_lex_string
|
thd_make_lex_string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct thd_wait_service_st thd_wait_handler= {
|
||||||
|
thd_wait_begin,
|
||||||
|
thd_wait_end
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct my_thread_scheduler_service my_thread_scheduler_handler= {
|
||||||
|
my_thread_scheduler_set,
|
||||||
|
my_thread_scheduler_reset,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static struct st_service_ref list_of_services[]=
|
static struct st_service_ref list_of_services[]=
|
||||||
{
|
{
|
||||||
{ "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler },
|
{ "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler },
|
||||||
{ "thd_alloc_service", VERSION_thd_alloc, &thd_alloc_handler }
|
{ "thd_alloc_service", VERSION_thd_alloc, &thd_alloc_handler },
|
||||||
|
{ "thd_wait_service", VERSION_thd_wait, &thd_wait_handler },
|
||||||
|
{ "my_thread_scheduler_service",
|
||||||
|
VERSION_my_thread_scheduler, &my_thread_scheduler_handler },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12723,7 +12723,9 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
|||||||
if (!end_of_records)
|
if (!end_of_records)
|
||||||
{
|
{
|
||||||
copy_fields(&join->tmp_table_param);
|
copy_fields(&join->tmp_table_param);
|
||||||
copy_funcs(join->tmp_table_param.items_to_copy);
|
if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
|
||||||
|
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
|
||||||
|
|
||||||
if (!join->having || join->having->val_int())
|
if (!join->having || join->having->val_int())
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
@ -12813,7 +12815,8 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
|||||||
memcpy(table->record[0]+key_part->offset, group->buff, 1);
|
memcpy(table->record[0]+key_part->offset, group->buff, 1);
|
||||||
}
|
}
|
||||||
init_tmptable_sum_functions(join->sum_funcs);
|
init_tmptable_sum_functions(join->sum_funcs);
|
||||||
copy_funcs(join->tmp_table_param.items_to_copy);
|
if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
|
||||||
|
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
|
||||||
if ((error=table->file->ha_write_row(table->record[0])))
|
if ((error=table->file->ha_write_row(table->record[0])))
|
||||||
{
|
{
|
||||||
if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
|
if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
|
||||||
@ -12848,7 +12851,8 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
|||||||
|
|
||||||
init_tmptable_sum_functions(join->sum_funcs);
|
init_tmptable_sum_functions(join->sum_funcs);
|
||||||
copy_fields(&join->tmp_table_param); // Groups are copied twice.
|
copy_fields(&join->tmp_table_param); // Groups are copied twice.
|
||||||
copy_funcs(join->tmp_table_param.items_to_copy);
|
if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
|
||||||
|
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
|
||||||
|
|
||||||
if (!(error=table->file->ha_write_row(table->record[0])))
|
if (!(error=table->file->ha_write_row(table->record[0])))
|
||||||
join->send_records++; // New group
|
join->send_records++; // New group
|
||||||
@ -12935,7 +12939,8 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
|||||||
if (idx < (int) join->send_group_parts)
|
if (idx < (int) join->send_group_parts)
|
||||||
{
|
{
|
||||||
copy_fields(&join->tmp_table_param);
|
copy_fields(&join->tmp_table_param);
|
||||||
copy_funcs(join->tmp_table_param.items_to_copy);
|
if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
|
||||||
|
DBUG_RETURN(NESTED_LOOP_ERROR);
|
||||||
if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
|
if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
|
||||||
DBUG_RETURN(NESTED_LOOP_ERROR);
|
DBUG_RETURN(NESTED_LOOP_ERROR);
|
||||||
if (join->procedure)
|
if (join->procedure)
|
||||||
@ -13238,6 +13243,34 @@ ok:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Find shortest key suitable for full table scan.
|
||||||
|
|
||||||
|
@param table Table to scan
|
||||||
|
@param usable_keys Allowed keys
|
||||||
|
|
||||||
|
@note
|
||||||
|
As far as
|
||||||
|
1) clustered primary key entry data set is a set of all record
|
||||||
|
fields (key fields and not key fields) and
|
||||||
|
2) secondary index entry data is a union of its key fields and
|
||||||
|
primary key fields (at least InnoDB and its derivatives don't
|
||||||
|
duplicate primary key fields there, even if the primary and
|
||||||
|
the secondary keys have a common subset of key fields),
|
||||||
|
then secondary index entry data is always a subset of primary key entry.
|
||||||
|
Unfortunately, key_info[nr].key_length doesn't show the length
|
||||||
|
of key/pointer pair but a sum of key field lengths only, thus
|
||||||
|
we can't estimate index IO volume comparing only this key_length
|
||||||
|
value of secondary keys and clustered PK.
|
||||||
|
So, try secondary keys first, and choose PK only if there are no
|
||||||
|
usable secondary covering keys or found best secondary key include
|
||||||
|
all table fields (i.e. same as PK):
|
||||||
|
|
||||||
|
@return
|
||||||
|
MAX_KEY no suitable key found
|
||||||
|
key index otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
uint find_shortest_key(TABLE *table, const key_map *usable_keys)
|
uint find_shortest_key(TABLE *table, const key_map *usable_keys)
|
||||||
{
|
{
|
||||||
uint best= MAX_KEY;
|
uint best= MAX_KEY;
|
||||||
@ -13250,23 +13283,6 @@ uint find_shortest_key(TABLE *table, const key_map *usable_keys)
|
|||||||
uint min_length= (uint) ~0;
|
uint min_length= (uint) ~0;
|
||||||
for (uint nr=0; nr < table->s->keys ; nr++)
|
for (uint nr=0; nr < table->s->keys ; nr++)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
As far as
|
|
||||||
1) clustered primary key entry data set is a set of all record
|
|
||||||
fields (key fields and not key fields) and
|
|
||||||
2) secondary index entry data is a union of its key fields and
|
|
||||||
primary key fields (at least InnoDB and its derivatives don't
|
|
||||||
duplicate primary key fields there, even if the primary and
|
|
||||||
the secondary keys have a common subset of key fields),
|
|
||||||
then secondary index entry data is always a subset of primary key
|
|
||||||
entry, and the PK is always longer.
|
|
||||||
Unfortunately, key_info[nr].key_length doesn't show the length
|
|
||||||
of key/pointer pair but a sum of key field lengths only, thus
|
|
||||||
we can't estimate index IO volume comparing only this key_length
|
|
||||||
value of seconday keys and clustered PK.
|
|
||||||
So, try secondary keys first, and choose PK only if there are no
|
|
||||||
usable secondary covering keys:
|
|
||||||
*/
|
|
||||||
if (nr == usable_clustered_pk)
|
if (nr == usable_clustered_pk)
|
||||||
continue;
|
continue;
|
||||||
if (usable_keys->is_set(nr))
|
if (usable_keys->is_set(nr))
|
||||||
@ -13279,7 +13295,20 @@ uint find_shortest_key(TABLE *table, const key_map *usable_keys)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return best != MAX_KEY ? best : usable_clustered_pk;
|
if (usable_clustered_pk != MAX_KEY)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
If the primary key is clustered and found shorter key covers all table
|
||||||
|
fields then primary key scan normally would be faster because amount of
|
||||||
|
data to scan is the same but PK is clustered.
|
||||||
|
It's safe to compare key parts with table fields since duplicate key
|
||||||
|
parts aren't allowed.
|
||||||
|
*/
|
||||||
|
if (best == MAX_KEY ||
|
||||||
|
table->key_info[best].key_parts >= table->s->fields)
|
||||||
|
best= usable_clustered_pk;
|
||||||
|
}
|
||||||
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15807,14 +15836,39 @@ update_sum_func(Item_sum **func_ptr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Copy result of functions to record in tmp_table. */
|
/**
|
||||||
|
Copy result of functions to record in tmp_table.
|
||||||
|
|
||||||
void
|
Uses the thread pointer to check for errors in
|
||||||
copy_funcs(Item **func_ptr)
|
some of the val_xxx() methods called by the
|
||||||
|
save_in_result_field() function.
|
||||||
|
TODO: make the Item::val_xxx() return error code
|
||||||
|
|
||||||
|
@param func_ptr array of the function Items to copy to the tmp table
|
||||||
|
@param thd pointer to the current thread for error checking
|
||||||
|
@retval
|
||||||
|
FALSE if OK
|
||||||
|
@retval
|
||||||
|
TRUE on error
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
|
copy_funcs(Item **func_ptr, const THD *thd)
|
||||||
{
|
{
|
||||||
Item *func;
|
Item *func;
|
||||||
for (; (func = *func_ptr) ; func_ptr++)
|
for (; (func = *func_ptr) ; func_ptr++)
|
||||||
|
{
|
||||||
func->save_in_result_field(1);
|
func->save_in_result_field(1);
|
||||||
|
/*
|
||||||
|
Need to check the THD error state because Item::val_xxx() don't
|
||||||
|
return error code, but can generate errors
|
||||||
|
TODO: change it for a real status check when Item::val_xxx()
|
||||||
|
are extended to return status code.
|
||||||
|
*/
|
||||||
|
if (thd->is_error())
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -606,7 +606,7 @@ bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
|||||||
List<Item> &new_list1, List<Item> &new_list2,
|
List<Item> &new_list1, List<Item> &new_list2,
|
||||||
uint elements, List<Item> &fields);
|
uint elements, List<Item> &fields);
|
||||||
void copy_fields(TMP_TABLE_PARAM *param);
|
void copy_fields(TMP_TABLE_PARAM *param);
|
||||||
void copy_funcs(Item **func_ptr);
|
bool copy_funcs(Item **func_ptr, const THD *thd);
|
||||||
bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
|
bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
|
||||||
int error, bool ignore_last_dupp_error);
|
int error, bool ignore_last_dupp_error);
|
||||||
uint find_shortest_key(TABLE *table, const key_map *usable_keys);
|
uint find_shortest_key(TABLE *table, const key_map *usable_keys);
|
||||||
|
@ -1815,6 +1815,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
|
|||||||
if ((thd_info->db=tmp->db)) // Safe test
|
if ((thd_info->db=tmp->db)) // Safe test
|
||||||
thd_info->db=thd->strdup(thd_info->db);
|
thd_info->db=thd->strdup(thd_info->db);
|
||||||
thd_info->command=(int) tmp->command;
|
thd_info->command=(int) tmp->command;
|
||||||
|
mysql_mutex_lock(&tmp->LOCK_thd_data);
|
||||||
if ((mysys_var= tmp->mysys_var))
|
if ((mysys_var= tmp->mysys_var))
|
||||||
mysql_mutex_lock(&mysys_var->mutex);
|
mysql_mutex_lock(&mysys_var->mutex);
|
||||||
thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
|
thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
|
||||||
@ -1822,16 +1823,15 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
|
|||||||
if (mysys_var)
|
if (mysys_var)
|
||||||
mysql_mutex_unlock(&mysys_var->mutex);
|
mysql_mutex_unlock(&mysys_var->mutex);
|
||||||
|
|
||||||
thd_info->start_time= tmp->start_time;
|
|
||||||
thd_info->query=0;
|
thd_info->query=0;
|
||||||
/* Lock THD mutex that protects its data when looking at it. */
|
/* Lock THD mutex that protects its data when looking at it. */
|
||||||
mysql_mutex_lock(&tmp->LOCK_thd_data);
|
|
||||||
if (tmp->query())
|
if (tmp->query())
|
||||||
{
|
{
|
||||||
uint length= min(max_query_length, tmp->query_length());
|
uint length= min(max_query_length, tmp->query_length());
|
||||||
thd_info->query= (char*) thd->strmake(tmp->query(),length);
|
thd_info->query= (char*) thd->strmake(tmp->query(),length);
|
||||||
}
|
}
|
||||||
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||||
|
thd_info->start_time= tmp->start_time;
|
||||||
thread_infos.append(thd_info);
|
thread_infos.append(thd_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1918,6 +1918,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
|
|||||||
table->field[3]->set_notnull();
|
table->field[3]->set_notnull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mysql_mutex_lock(&tmp->LOCK_thd_data);
|
||||||
if ((mysys_var= tmp->mysys_var))
|
if ((mysys_var= tmp->mysys_var))
|
||||||
mysql_mutex_lock(&mysys_var->mutex);
|
mysql_mutex_lock(&mysys_var->mutex);
|
||||||
/* COMMAND */
|
/* COMMAND */
|
||||||
@ -1938,6 +1939,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
|
|||||||
|
|
||||||
if (mysys_var)
|
if (mysys_var)
|
||||||
mysql_mutex_unlock(&mysys_var->mutex);
|
mysql_mutex_unlock(&mysys_var->mutex);
|
||||||
|
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||||
|
|
||||||
/* INFO */
|
/* INFO */
|
||||||
/* Lock THD mutex that protects its data when looking at it. */
|
/* Lock THD mutex that protects its data when looking at it. */
|
||||||
@ -7490,7 +7492,9 @@ int finalize_schema_table(st_plugin_int *plugin)
|
|||||||
ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
|
ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
|
||||||
DBUG_ENTER("finalize_schema_table");
|
DBUG_ENTER("finalize_schema_table");
|
||||||
|
|
||||||
if (schema_table && plugin->plugin->deinit)
|
if (schema_table)
|
||||||
|
{
|
||||||
|
if (plugin->plugin->deinit)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("Deinitializing plugin: '%s'", plugin->name.str));
|
DBUG_PRINT("info", ("Deinitializing plugin: '%s'", plugin->name.str));
|
||||||
if (plugin->plugin->deinit(NULL))
|
if (plugin->plugin->deinit(NULL))
|
||||||
@ -7498,6 +7502,7 @@ int finalize_schema_table(st_plugin_int *plugin)
|
|||||||
DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.",
|
DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.",
|
||||||
plugin->name.str));
|
plugin->name.str));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
my_free(schema_table);
|
my_free(schema_table);
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
@ -1425,6 +1425,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
|
|
||||||
%type <table>
|
%type <table>
|
||||||
table_ident table_ident_nodb references xid
|
table_ident table_ident_nodb references xid
|
||||||
|
table_ident_opt_wild
|
||||||
|
|
||||||
%type <simple_string>
|
%type <simple_string>
|
||||||
remember_name remember_end opt_db text_or_password
|
remember_name remember_end opt_db text_or_password
|
||||||
@ -10371,7 +10372,7 @@ table_alias_ref_list:
|
|||||||
;
|
;
|
||||||
|
|
||||||
table_alias_ref:
|
table_alias_ref:
|
||||||
table_ident
|
table_ident_opt_wild
|
||||||
{
|
{
|
||||||
if (!Select->add_table_to_list(YYTHD, $1, NULL,
|
if (!Select->add_table_to_list(YYTHD, $1, NULL,
|
||||||
TL_OPTION_UPDATING | TL_OPTION_ALIAS,
|
TL_OPTION_UPDATING | TL_OPTION_ALIAS,
|
||||||
@ -12161,6 +12162,21 @@ table_ident:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
table_ident_opt_wild:
|
||||||
|
ident opt_wild
|
||||||
|
{
|
||||||
|
$$= new Table_ident($1);
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| ident '.' ident opt_wild
|
||||||
|
{
|
||||||
|
$$= new Table_ident(YYTHD, $1,$3,0);
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
table_ident_nodb:
|
table_ident_nodb:
|
||||||
ident
|
ident
|
||||||
{
|
{
|
||||||
|
@ -1673,19 +1673,13 @@ static Sys_var_ulong Sys_trans_prealloc_size(
|
|||||||
|
|
||||||
static const char *thread_handling_names[]=
|
static const char *thread_handling_names[]=
|
||||||
{
|
{
|
||||||
"one-thread-per-connection", "no-threads",
|
"one-thread-per-connection", "no-threads", "loaded-dynamically",
|
||||||
#if HAVE_POOL_OF_THREADS == 1
|
|
||||||
"pool-of-threads",
|
|
||||||
#endif
|
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
static Sys_var_enum Sys_thread_handling(
|
static Sys_var_enum Sys_thread_handling(
|
||||||
"thread_handling",
|
"thread_handling",
|
||||||
"Define threads usage for handling queries, one of "
|
"Define threads usage for handling queries, one of "
|
||||||
"one-thread-per-connection, no-threads"
|
"one-thread-per-connection, no-threads, loaded-dynamically"
|
||||||
#if HAVE_POOL_OF_THREADS == 1
|
|
||||||
", pool-of-threads"
|
|
||||||
#endif
|
|
||||||
, READ_ONLY GLOBAL_VAR(thread_handling), CMD_LINE(REQUIRED_ARG),
|
, READ_ONLY GLOBAL_VAR(thread_handling), CMD_LINE(REQUIRED_ARG),
|
||||||
thread_handling_names, DEFAULT(0));
|
thread_handling_names, DEFAULT(0));
|
||||||
|
|
||||||
|
@ -192,7 +192,6 @@ typedef struct st_order {
|
|||||||
struct st_order *next;
|
struct st_order *next;
|
||||||
Item **item; /* Point at item in select fields */
|
Item **item; /* Point at item in select fields */
|
||||||
Item *item_ptr; /* Storage for initial item */
|
Item *item_ptr; /* Storage for initial item */
|
||||||
Item **item_copy; /* For SPs; the original item ptr */
|
|
||||||
int counter; /* position in SELECT list, correct
|
int counter; /* position in SELECT list, correct
|
||||||
only if counter_used is true*/
|
only if counter_used is true*/
|
||||||
bool asc; /* true if ascending */
|
bool asc; /* true if ascending */
|
||||||
|
@ -43,6 +43,8 @@ Created 11/11/1995 Heikki Tuuri
|
|||||||
#include "log0log.h"
|
#include "log0log.h"
|
||||||
#include "os0file.h"
|
#include "os0file.h"
|
||||||
#include "trx0sys.h"
|
#include "trx0sys.h"
|
||||||
|
#include "mysql/plugin.h"
|
||||||
|
#include "mysql/service_thd_wait.h"
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
These statistics are generated for heuristics used in estimating the
|
These statistics are generated for heuristics used in estimating the
|
||||||
@ -1744,10 +1746,14 @@ buf_flush_wait_batch_end(
|
|||||||
|
|
||||||
buf_pool = buf_pool_from_array(i);
|
buf_pool = buf_pool_from_array(i);
|
||||||
|
|
||||||
|
thd_wait_begin(NULL, THD_WAIT_DISKIO);
|
||||||
os_event_wait(buf_pool->no_flush[type]);
|
os_event_wait(buf_pool->no_flush[type]);
|
||||||
|
thd_wait_end(NULL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
thd_wait_begin(NULL, THD_WAIT_DISKIO);
|
||||||
os_event_wait(buf_pool->no_flush[type]);
|
os_event_wait(buf_pool->no_flush[type]);
|
||||||
|
thd_wait_end(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,8 @@ Created 11/5/1995 Heikki Tuuri
|
|||||||
#include "os0file.h"
|
#include "os0file.h"
|
||||||
#include "srv0start.h"
|
#include "srv0start.h"
|
||||||
#include "srv0srv.h"
|
#include "srv0srv.h"
|
||||||
|
#include "mysql/plugin.h"
|
||||||
|
#include "mysql/service_thd_wait.h"
|
||||||
|
|
||||||
/** The linear read-ahead area size */
|
/** The linear read-ahead area size */
|
||||||
#define BUF_READ_AHEAD_LINEAR_AREA BUF_READ_AHEAD_AREA
|
#define BUF_READ_AHEAD_LINEAR_AREA BUF_READ_AHEAD_AREA
|
||||||
@ -135,6 +137,7 @@ buf_read_page_low(
|
|||||||
|
|
||||||
ut_ad(buf_page_in_file(bpage));
|
ut_ad(buf_page_in_file(bpage));
|
||||||
|
|
||||||
|
thd_wait_begin(NULL, THD_WAIT_DISKIO);
|
||||||
if (zip_size) {
|
if (zip_size) {
|
||||||
*err = fil_io(OS_FILE_READ | wake_later,
|
*err = fil_io(OS_FILE_READ | wake_later,
|
||||||
sync, space, zip_size, offset, 0, zip_size,
|
sync, space, zip_size, offset, 0, zip_size,
|
||||||
@ -146,6 +149,7 @@ buf_read_page_low(
|
|||||||
sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
|
sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
|
||||||
((buf_block_t*) bpage)->frame, bpage);
|
((buf_block_t*) bpage)->frame, bpage);
|
||||||
}
|
}
|
||||||
|
thd_wait_end(NULL);
|
||||||
ut_a(*err == DB_SUCCESS);
|
ut_a(*err == DB_SUCCESS);
|
||||||
|
|
||||||
if (sync) {
|
if (sync) {
|
||||||
|
@ -84,6 +84,8 @@ Created 10/8/1995 Heikki Tuuri
|
|||||||
#include "ha_prototypes.h"
|
#include "ha_prototypes.h"
|
||||||
#include "trx0i_s.h"
|
#include "trx0i_s.h"
|
||||||
#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
|
#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
|
||||||
|
#include "mysql/plugin.h"
|
||||||
|
#include "mysql/service_thd_wait.h"
|
||||||
|
|
||||||
/* This is set to TRUE if the MySQL user has set it in MySQL; currently
|
/* This is set to TRUE if the MySQL user has set it in MySQL; currently
|
||||||
affects only FOREIGN KEY definition parsing */
|
affects only FOREIGN KEY definition parsing */
|
||||||
@ -1232,7 +1234,9 @@ retry:
|
|||||||
|
|
||||||
trx->op_info = "waiting in InnoDB queue";
|
trx->op_info = "waiting in InnoDB queue";
|
||||||
|
|
||||||
|
thd_wait_begin(trx->mysql_thd, THD_WAIT_ROW_TABLE_LOCK);
|
||||||
os_event_wait(slot->event);
|
os_event_wait(slot->event);
|
||||||
|
thd_wait_end(trx->mysql_thd);
|
||||||
|
|
||||||
trx->op_info = "";
|
trx->op_info = "";
|
||||||
|
|
||||||
@ -1597,7 +1601,9 @@ srv_suspend_mysql_thread(
|
|||||||
|
|
||||||
/* Suspend this thread and wait for the event. */
|
/* Suspend this thread and wait for the event. */
|
||||||
|
|
||||||
|
thd_wait_begin(trx->mysql_thd, THD_WAIT_ROW_TABLE_LOCK);
|
||||||
os_event_wait(event);
|
os_event_wait(event);
|
||||||
|
thd_wait_end(trx->mysql_thd);
|
||||||
|
|
||||||
/* After resuming, reacquire the data dictionary latch if
|
/* After resuming, reacquire the data dictionary latch if
|
||||||
necessary. */
|
necessary. */
|
||||||
|
10
vio/vio.c
10
vio/vio.c
@ -44,6 +44,11 @@ static my_bool no_poll_read(Vio *vio __attribute__((unused)),
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static my_bool has_no_data(Vio *vio __attribute__((unused)))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper to fill most of the Vio* with defaults.
|
* Helper to fill most of the Vio* with defaults.
|
||||||
*/
|
*/
|
||||||
@ -83,6 +88,7 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
|
|||||||
|
|
||||||
vio->poll_read =no_poll_read;
|
vio->poll_read =no_poll_read;
|
||||||
vio->is_connected =vio_is_connected_pipe;
|
vio->is_connected =vio_is_connected_pipe;
|
||||||
|
vio->has_data =has_no_data;
|
||||||
|
|
||||||
vio->timeout=vio_win32_timeout;
|
vio->timeout=vio_win32_timeout;
|
||||||
/* Set default timeout */
|
/* Set default timeout */
|
||||||
@ -110,6 +116,7 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
|
|||||||
|
|
||||||
vio->poll_read =no_poll_read;
|
vio->poll_read =no_poll_read;
|
||||||
vio->is_connected =vio_is_connected_shared_memory;
|
vio->is_connected =vio_is_connected_shared_memory;
|
||||||
|
vio->has_data =has_no_data;
|
||||||
|
|
||||||
/* Currently, shared memory is on Windows only, hence the below is ok*/
|
/* Currently, shared memory is on Windows only, hence the below is ok*/
|
||||||
vio->timeout= vio_win32_timeout;
|
vio->timeout= vio_win32_timeout;
|
||||||
@ -137,6 +144,7 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
|
|||||||
vio->timeout =vio_timeout;
|
vio->timeout =vio_timeout;
|
||||||
vio->poll_read =vio_poll_read;
|
vio->poll_read =vio_poll_read;
|
||||||
vio->is_connected =vio_is_connected;
|
vio->is_connected =vio_is_connected;
|
||||||
|
vio->has_data =vio_ssl_has_data;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_OPENSSL */
|
#endif /* HAVE_OPENSSL */
|
||||||
@ -155,6 +163,8 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
|
|||||||
vio->timeout =vio_timeout;
|
vio->timeout =vio_timeout;
|
||||||
vio->poll_read =vio_poll_read;
|
vio->poll_read =vio_poll_read;
|
||||||
vio->is_connected =vio_is_connected;
|
vio->is_connected =vio_is_connected;
|
||||||
|
vio->has_data= (flags & VIO_BUFFERED_READ) ?
|
||||||
|
vio_buff_has_data : has_no_data;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ int vio_close_shared_memory(Vio * vio);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void vio_timeout(Vio *vio,uint which, uint timeout);
|
void vio_timeout(Vio *vio,uint which, uint timeout);
|
||||||
|
my_bool vio_buff_has_data(Vio *vio);
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
#include "my_net.h" /* needed because of struct in_addr */
|
#include "my_net.h" /* needed because of struct in_addr */
|
||||||
@ -62,5 +63,7 @@ void vio_ssl_delete(Vio *vio);
|
|||||||
|
|
||||||
int vio_ssl_blocking(Vio *vio, my_bool set_blocking_mode, my_bool *old_mode);
|
int vio_ssl_blocking(Vio *vio, my_bool set_blocking_mode, my_bool *old_mode);
|
||||||
|
|
||||||
|
my_bool vio_ssl_has_data(Vio *vio);
|
||||||
|
|
||||||
#endif /* HAVE_OPENSSL */
|
#endif /* HAVE_OPENSSL */
|
||||||
#endif /* VIO_PRIV_INCLUDED */
|
#endif /* VIO_PRIV_INCLUDED */
|
||||||
|
@ -98,6 +98,10 @@ size_t vio_read_buff(Vio *vio, uchar* buf, size_t size)
|
|||||||
#undef VIO_UNBUFFERED_READ_MIN_SIZE
|
#undef VIO_UNBUFFERED_READ_MIN_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my_bool vio_buff_has_data(Vio *vio)
|
||||||
|
{
|
||||||
|
return (vio->read_pos != vio->read_end);
|
||||||
|
}
|
||||||
|
|
||||||
size_t vio_write(Vio * vio, const uchar* buf, size_t size)
|
size_t vio_write(Vio * vio, const uchar* buf, size_t size)
|
||||||
{
|
{
|
||||||
|
@ -244,6 +244,9 @@ int vio_ssl_blocking(Vio *vio __attribute__((unused)),
|
|||||||
return (set_blocking_mode ? 0 : 1);
|
return (set_blocking_mode ? 0 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my_bool vio_ssl_has_data(Vio *vio)
|
||||||
|
{
|
||||||
|
return SSL_pending(vio->ssl_arg) > 0 ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* HAVE_OPENSSL */
|
#endif /* HAVE_OPENSSL */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user