Commit bae0e813 authored by Konstantin Osipov's avatar Konstantin Osipov

Backport of:

-------------------------------------------------------------
revno: 2877
committer: Davi Arnaut <Davi.Arnaut@Sun.COM>
branch nick: 35164-6.0
timestamp: Wed 2008-10-15 19:53:18 -0300
message:
Bug#35164: Large number of invalid pthread_attr_setschedparam calls
Bug#37536: Thread scheduling causes performance degradation at low thread count
Bug#12702: Long queries take 100% of CPU and freeze other applications under Windows

The problem is that although having threads with different priorities
yields marginal improvements [1] in some platforms [2], relying on some
statically defined priorities (QUERY_PRIOR and WAIT_PRIOR) to play well
(or to work at all) with different scheduling practices and disciplines
is, at best, a shot in the dark as the meaning of priority values may
change depending on the scheduling policy set for the process.

Another problem is that increasing priorities can hurt other concurrent
(running on the same hardware) applications (such as AMP) by causing
starvation problems as MySQL threads will successively preempt lower
priority processes. This can be evidenced by Bug#12702.

The solution is to not change the threads priorities and rely on the
system scheduler to perform its job. This also enables a system admin
to increase or decrease the scheduling priority of the MySQL process,
if intended.

Furthermore, the internal wrappers and code for changing the priority
of threads is being removed as they are now unused and ancient.

1. Due to unintentional side effects. On Solaris this could artificially
help benchmarks as calling the priority changing syscall millions of
times is more beneficial than the actual setting of the priority.

2. Where it actually works. It has never worked on Linux as the default
scheduling policy SCHED_OTHER only accepts the static priority 0.


configure.in:
  Remove checks for functions that are not used anymore.
include/config-netware.h:
  Remove unused define.
include/my_pthread.h:
  Remove thread priority changing wrappers.
mysys/my_pthread.c:
  Remove thread priority changing wrappers. They do not work properly
  and their implementations were incorrectly protected by a check for
  HAVE_PTHREAD_SETSCHEDPARAM.
mysys/thr_alarm.c:
  Remove meaningless (100) increase of a thread priority.
sql/mysql_priv.h:
  Remove meaningless thread priority values.
sql/mysqld.cc:
  Don't change thread priorities.
sql/slave.cc:
  Don't change thread priorities.
sql/slave.h:
  Update function prototype.
sql/sql_parse.cc:
  Don't change thread priorities.
sql/sql_prepare.cc:
  Don't change thread priorities.
sql/unireg.h:
  Mark flag as obsolete.
storage/innobase/handler/ha_innodb.cc:
  Remove use of obsolete flag and associated behavior.
storage/innobase/include/srv0srv.h:
  Remove use of obsolete flag and associated variables.
storage/innobase/os/os0thread.c:
  Remove use of obsolete flag and associated behavior.
storage/innobase/srv/srv0srv.c:
  Remove use of obsolete flag and associated variables.
parent 9f495825
......@@ -2098,11 +2098,9 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bsearch bzero \
localtime_r gethrtime gmtime_r \
locking longjmp lrand48 madvise mallinfo memcpy memmove \
mkstemp mlockall perror poll pread pthread_attr_create mmap mmap64 getpagesize \
pthread_attr_getstacksize pthread_attr_setprio pthread_attr_setschedparam \
pthread_attr_setstacksize pthread_condattr_create pthread_getsequence_np \
pthread_key_delete pthread_rwlock_rdlock pthread_setprio \
pthread_setprio_np pthread_setschedparam pthread_sigmask readlink \
realpath rename rint rwlock_init setupterm \
pthread_attr_getstacksize pthread_attr_setstacksize pthread_condattr_create \
pthread_getsequence_np pthread_key_delete pthread_rwlock_rdlock pthread_sigmask \
readlink realpath rename rint rwlock_init setupterm \
shmget shmat shmdt shmctl sigaction sigemptyset sigaddset \
sighold sigset sigthreadmask port_create sleep \
snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr \
......
......@@ -73,7 +73,6 @@ extern "C" {
#undef HAVE_FINITE
#undef HAVE_GETPWNAM
#undef HAVE_GETPWUID
#undef HAVE_PTHREAD_SETSCHEDPARAM
#undef HAVE_READLINK
#undef HAVE_STPCPY
/* changes end */
......
......@@ -35,7 +35,6 @@ typedef DWORD pthread_t;
typedef struct thread_attr {
DWORD dwStackSize ;
DWORD dwCreatingFlag ;
int priority ;
} pthread_attr_t ;
typedef struct { int dummy; } pthread_condattr_t;
......@@ -110,7 +109,6 @@ int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_attr_init(pthread_attr_t *connect_att);
int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack);
int pthread_attr_setprio(pthread_attr_t *connect_att,int priority);
int pthread_attr_destroy(pthread_attr_t *connect_att);
struct tm *localtime_r(const time_t *timep,struct tm *tmp);
struct tm *gmtime_r(const time_t *timep,struct tm *tmp);
......@@ -141,19 +139,18 @@ int pthread_join(pthread_t thread, void **value_ptr);
#define pthread_mutex_trylock(A) win_pthread_mutex_trylock((A))
#define pthread_mutex_unlock(A) LeaveCriticalSection(A)
#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
#define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B))
#define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH)
/* Dummy defines for easier code */
#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
#define my_pthread_attr_setprio(A,B) pthread_attr_setprio(A,B)
#define pthread_attr_setscope(A,B)
#define pthread_detach_this_thread()
#define pthread_condattr_init(A)
#define pthread_condattr_destroy(A)
#define my_pthread_getprio(thread_id) pthread_dummy(0)
/* per the platform's documentation */
#define pthread_yield() Sleep(0)
#else /* Normal threads */
......@@ -181,8 +178,6 @@ void my_pthread_exit(void *status);
#define pthread_exit(A) my_pthread_exit(A)
#endif
extern int my_pthread_getprio(pthread_t thread_id);
#define pthread_key(T,V) pthread_key_t V
#define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,(V))
#define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,(void*) (V))
......@@ -254,32 +249,6 @@ int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */
#define my_sigset(A,B) signal((A),(B))
#endif
#ifndef my_pthread_setprio
#if defined(HAVE_PTHREAD_SETPRIO_NP) /* FSU threads */
#define my_pthread_setprio(A,B) pthread_setprio_np((A),(B))
#elif defined(HAVE_PTHREAD_SETPRIO)
#define my_pthread_setprio(A,B) pthread_setprio((A),(B))
#elif defined(HAVE_PTHREAD_SETSCHEDPRIO) && !defined (__GNUC__)
/*
Workaround for bug on Solaris where pthread.h have bug in GNU
version of pthread.h => configure says yes, header files says
no. So not used with gcc and issue is Solaris only, so will
be used on Solaris using SunStudio.
*/
#define my_pthread_setprio(A,B) pthread_setschedprio((A),(B))
#else
extern void my_pthread_setprio(pthread_t thread_id,int prior);
#endif
#endif
#ifndef my_pthread_attr_setprio
#ifdef HAVE_PTHREAD_ATTR_SETPRIO
#define my_pthread_attr_setprio(A,B) pthread_attr_setprio((A),(B))
#else
extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority);
#endif
#endif
#if !defined(HAVE_PTHREAD_ATTR_SETSCOPE) || defined(HAVE_DEC_3_2_THREADS)
#define pthread_attr_setscope(A,B)
#undef HAVE_GETHOSTBYADDR_R /* No definition */
......
......@@ -30,47 +30,6 @@
#endif
uint thd_lib_detected= 0;
#ifndef my_pthread_setprio
void my_pthread_setprio(pthread_t thread_id,int prior)
{
#ifdef HAVE_PTHREAD_SETSCHEDPARAM
struct sched_param tmp_sched_param;
bzero((char*) &tmp_sched_param,sizeof(tmp_sched_param));
tmp_sched_param.sched_priority=prior;
VOID(pthread_setschedparam(thread_id,SCHED_POLICY,&tmp_sched_param));
#endif
}
#endif
#ifndef my_pthread_getprio
int my_pthread_getprio(pthread_t thread_id)
{
#ifdef HAVE_PTHREAD_SETSCHEDPARAM
struct sched_param tmp_sched_param;
int policy;
if (!pthread_getschedparam(thread_id,&policy,&tmp_sched_param))
{
return tmp_sched_param.sched_priority;
}
#endif
return -1;
}
#endif
#ifndef my_pthread_attr_setprio
void my_pthread_attr_setprio(pthread_attr_t *attr, int priority)
{
#ifdef HAVE_PTHREAD_SETSCHEDPARAM
struct sched_param tmp_sched_param;
bzero((char*) &tmp_sched_param,sizeof(tmp_sched_param));
tmp_sched_param.sched_priority=priority;
VOID(pthread_attr_setschedparam(attr,&tmp_sched_param));
#endif
}
#endif
/* To allow use of pthread_getspecific with two arguments */
#ifdef HAVE_NONPOSIX_PTHREAD_GETSPECIFIC
......@@ -364,9 +323,8 @@ int sigwait(sigset_t *setp, int *sigp)
pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
pthread_attr_setstacksize(&thr_attr,8196);
my_pthread_attr_setprio(&thr_attr,100); /* Very high priority */
VOID(pthread_create(&sigwait_thread_id,&thr_attr,sigwait_thread,setp));
VOID(pthread_attr_destroy(&thr_attr));
pthread_create(&sigwait_thread_id,&thr_attr,sigwait_thread,setp);
pthread_attr_destroy(&thr_attr);
}
pthread_mutex_lock(&LOCK_sigwait);
......
......@@ -97,10 +97,8 @@ void init_thr_alarm(uint max_alarms)
pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
pthread_attr_setstacksize(&thr_attr,8196);
my_pthread_attr_setprio(&thr_attr,100); /* Very high priority */
VOID(pthread_create(&alarm_thread,&thr_attr,alarm_handler,NULL));
VOID(pthread_attr_destroy(&thr_attr));
pthread_create(&alarm_thread,&thr_attr,alarm_handler,NULL);
pthread_attr_destroy(&thr_attr);
}
#elif defined(USE_ONE_SIGNAL_HAND)
pthread_sigmask(SIG_BLOCK, &s, NULL); /* used with sigwait() */
......
......@@ -428,17 +428,7 @@ class Default_object_creation_ctx : public Object_creation_ctx
#if defined(__WIN__)
#undef FLUSH_TIME
#define FLUSH_TIME 1800 /**< Flush every half hour */
#define INTERRUPT_PRIOR -2
#define CONNECT_PRIOR -1
#define WAIT_PRIOR 0
#define QUERY_PRIOR 2
#else
#define INTERRUPT_PRIOR 10
#define CONNECT_PRIOR 9
#define WAIT_PRIOR 8
#define QUERY_PRIOR 6
#endif /* __WIN92__ */
#endif /* __WIN__ */
/* Bits from testflag */
#define TEST_PRINT_CACHED_TABLES 1
......
......@@ -48,10 +48,6 @@
#endif
#endif
#ifndef DEFAULT_SKIP_THREAD_PRIORITY
#define DEFAULT_SKIP_THREAD_PRIORITY 0
#endif
#include <thr_alarm.h>
#include <ft_global.h>
#include <errmsg.h>
......@@ -2681,8 +2677,6 @@ static void start_signal_handler(void)
#if !defined(HAVE_DEC_3_2_THREADS)
pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
(void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
if (!(opt_specialflag & SPECIAL_NO_PRIOR))
my_pthread_attr_setprio(&thr_attr,INTERRUPT_PRIOR);
#if defined(__ia64__) || defined(__ia64)
/*
Peculiar things with ia64 platforms - it seems we only have half the
......@@ -2802,8 +2796,6 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
abort_loop=1; // mark abort for threads
#ifdef USE_ONE_SIGNAL_HAND
pthread_t tmp;
if (!(opt_specialflag & SPECIAL_NO_PRIOR))
my_pthread_attr_setprio(&connection_attrib,INTERRUPT_PRIOR);
if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
(void*) &sig))
sql_print_error("Can't create thread to kill server");
......@@ -3629,8 +3621,6 @@ static int init_thread_environment()
(void) pthread_attr_setdetachstate(&connection_attrib,
PTHREAD_CREATE_DETACHED);
pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
if (!(opt_specialflag & SPECIAL_NO_PRIOR))
my_pthread_attr_setprio(&connection_attrib,WAIT_PRIOR);
if (pthread_key_create(&THR_THD,NULL) ||
pthread_key_create(&THR_MALLOC,NULL))
......@@ -4338,8 +4328,6 @@ int main(int argc, char **argv)
unireg_abort(1); // Will do exit
init_signals();
if (!(opt_specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),CONNECT_PRIOR);
#if defined(__ia64__) || defined(__ia64)
/*
Peculiar things with ia64 platforms - it seems we only have half the
......@@ -5029,8 +5017,6 @@ void handle_connections_sockets()
LINT_INIT(new_sock);
(void) my_pthread_getprio(pthread_self()); // For debugging
FD_ZERO(&clientFDs);
if (ip_sock != INVALID_SOCKET)
{
......@@ -6453,8 +6439,9 @@ Can't be set to 1 if --log-slave-updates is used.",
{"skip-symlink", OPT_SKIP_SYMLINKS, "Don't allow symlinking of tables. Deprecated option. Use --skip-symbolic-links instead.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"skip-thread-priority", OPT_SKIP_PRIOR,
"Don't give threads different priorities. Deprecated option.", 0, 0, 0, GET_NO_ARG, NO_ARG,
DEFAULT_SKIP_THREAD_PRIORITY, 0, 0, 0, 0, 0},
"Don't give threads different priorities. This option is deprecated "
"because it has no effect; the implied behavior is already the default.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_REPLICATION
{"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR,
"The location where the slave should put its temporary files when \
......@@ -7922,9 +7909,6 @@ static int mysql_init_variables(void)
#ifdef HAVE_SMEM
shared_memory_base_name= default_shared_memory_base_name;
#endif
#if !defined(my_pthread_setprio) && !defined(HAVE_PTHREAD_SETSCHEDPARAM)
opt_specialflag |= SPECIAL_NO_PRIOR;
#endif
#if defined(__WIN__) || defined(__NETWARE__)
/* Allow Win32 and NetWare users to move MySQL anywhere */
......@@ -8208,8 +8192,8 @@ mysqld_get_one_option(int optid,
case (int) OPT_SKIP_PRIOR:
opt_specialflag|= SPECIAL_NO_PRIOR;
sql_print_warning("The --skip-thread-priority startup option is deprecated "
"and will be removed in MySQL 7.0. MySQL 6.0 and up do not "
"give threads different priorities.");
"and will be removed in MySQL 7.0. This option has no effect "
"as the implied behavior is already the default.");
break;
case (int) OPT_SKIP_LOCK:
opt_external_locking=0;
......
......@@ -612,8 +612,7 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t *start_lock,
pthread_cond_t *start_cond,
volatile uint *slave_running,
volatile ulong *slave_run_id,
Master_info* mi,
bool high_priority)
Master_info* mi)
{
pthread_t th;
ulong start_id;
......@@ -643,8 +642,6 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t *start_lock,
}
start_id= *slave_run_id;
DBUG_PRINT("info",("Creating new slave thread"));
if (high_priority)
my_pthread_attr_setprio(&connection_attrib,CONNECT_PRIOR);
if (pthread_create(&th, &connection_attrib, h_func, (void*)mi))
{
if (start_lock)
......@@ -707,13 +704,13 @@ int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
error=start_slave_thread(handle_slave_io,lock_io,lock_cond_io,
cond_io,
&mi->slave_running, &mi->slave_run_id,
mi, 1); //high priority, to read the most possible
mi);
if (!error && (thread_mask & SLAVE_SQL))
{
error=start_slave_thread(handle_slave_sql,lock_sql,lock_cond_sql,
cond_sql,
&mi->rli.slave_running, &mi->rli.slave_run_id,
mi, 0);
mi);
if (error)
terminate_slave_threads(mi, thread_mask & SLAVE_IO, !need_slave_mutex);
}
......
......@@ -164,8 +164,7 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t* start_lock,
pthread_cond_t* start_cond,
volatile uint *slave_running,
volatile ulong *slave_run_id,
Master_info* mi,
bool high_priority);
Master_info* mi);
/* If fd is -1, dump to NET */
int mysql_table_dump(THD* thd, const char* db,
......
......@@ -1228,9 +1228,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->profiling.set_query_source(thd->query(), thd->query_length());
#endif
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
mysql_parse(thd, thd->query(), thd->query_length(), &end_of_stmt);
while (!thd->killed && (end_of_stmt != NULL) && ! thd->is_error())
......@@ -1283,8 +1280,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt);
}
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),WAIT_PRIOR);
DBUG_PRINT("info",("query ready"));
break;
}
......
......@@ -2615,14 +2615,8 @@ void mysqld_stmt_fetch(THD *thd, char *packet, uint packet_length)
thd->stmt_arena= stmt;
thd->set_n_backup_statement(stmt, &stmt_backup);
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(), QUERY_PRIOR);
cursor->fetch(num_rows);
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(), WAIT_PRIOR);
if (!cursor->is_open())
{
stmt->close_cursor();
......@@ -3386,14 +3380,8 @@ Prepared_statement::execute_loop(String *expanded_query,
thd->m_reprepare_observer = &reprepare_observer;
}
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
error= execute(expanded_query, open_cursor) || thd->is_error();
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(), WAIT_PRIOR);
thd->m_reprepare_observer= NULL;
if (error && !thd->is_fatal_error && !thd->killed &&
......
......@@ -126,7 +126,7 @@
#define SPECIAL_SAME_DB_NAME 16 /* form name = file name */
#define SPECIAL_ENGLISH 32 /* English error messages */
#define SPECIAL_NO_RESOLVE 64 /* Don't use gethostname */
#define SPECIAL_NO_PRIOR 128 /* Don't prioritize threads */
#define SPECIAL_NO_PRIOR 128 /* Obsolete */
#define SPECIAL_BIG_SELECTS 256 /* Don't use heap tables */
#define SPECIAL_NO_HOST_CACHE 512 /* Don't cache hosts */
#define SPECIAL_SHORT_LOG_FORMAT 1024
......
......@@ -2046,13 +2046,6 @@ innobase_init(
ut_a(default_path);
if (specialflag & SPECIAL_NO_PRIOR) {
srv_set_thread_priorities = FALSE;
} else {
srv_set_thread_priorities = TRUE;
srv_query_thread_priority = QUERY_PRIOR;
}
/* Set InnoDB initialization parameters according to the values
read from MySQL .cnf file */
......
......@@ -207,9 +207,6 @@ extern unsigned long long srv_stats_sample_pages;
extern ibool srv_use_doublewrite_buf;
extern ibool srv_use_checksums;
extern ibool srv_set_thread_priorities;
extern int srv_query_thread_priority;
extern ulong srv_max_buf_pool_modified_pct;
extern ulong srv_max_purge_lag;
......
......@@ -133,15 +133,6 @@ os_thread_create(
0, /* thread runs immediately */
&win_thread_id);
if (srv_set_thread_priorities) {
/* Set created thread priority the same as a normal query
in MYSQL: we try to prevent starvation of threads by
assigning same priority QUERY_PRIOR to all */
ut_a(SetThreadPriority(thread, srv_query_thread_priority));
}
if (thread_id) {
*thread_id = win_thread_id;
}
......@@ -200,11 +191,6 @@ os_thread_create(
#ifndef UNIV_HPUX10
pthread_attr_destroy(&attr);
#endif
if (srv_set_thread_priorities) {
my_pthread_setprio(pthread, srv_query_thread_priority);
}
if (thread_id) {
*thread_id = pthread;
}
......
......@@ -369,9 +369,6 @@ UNIV_INTERN unsigned long long srv_stats_sample_pages = 8;
UNIV_INTERN ibool srv_use_doublewrite_buf = TRUE;
UNIV_INTERN ibool srv_use_checksums = TRUE;
UNIV_INTERN ibool srv_set_thread_priorities = TRUE;
UNIV_INTERN int srv_query_thread_priority = 0;
UNIV_INTERN ulong srv_replication_delay = 0;
/*-------------------------------------------*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment