mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 11:01:52 +01:00
4b25d5b10c
Fixes the following bugs: - Bug #33349: possible race condition revolving around data dictionary and repartitioning Introduce retry/sleep logic as a workaround for a transient bug where ::open fails for partitioned tables randomly if we are using one file per table. - Bug #34053: normal users can enable innodb_monitor logging In CREATE TABLE and DROP TABLE check whether the table in question is one of the magic innodb_monitor tables and whether the user has enough rights to mess with it before doing anything else. - Bug #22868: 'Thread thrashing' with > 50 concurrent conns under an upd-intensive workloadw - Bug #29560: InnoDB >= 5.0.30 hangs on adaptive hash rw-lock 'waiting for an X-lock' This is a combination of changes that forward port the scalability fix applied to 5.0 through r1001. It reverts changes r149 and r122 (these were 5.1 specific changes made in lieu of scalability fix of 5.0) Then it applies r1001 to 5.0 which is the original scalability fix. Finally it applies r2082 which fixes an issue with the original fix. - Bug #30930: Add auxiliary function to retrieve THD::thread_id Add thd_get_thread_id() function. Also make check_global_access() function visible to InnoDB under INNODB_COMPATIBILITY_HOOKS #define. include/mysql/plugin.h: Add thd_get_thread_id() accessor function mysql-test/r/innodb.result: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2261: branches/5.1: Merge a change from MySQL AB: ChangeSet@2007-10-13 15:49:42+03:00, aelkin@koti.dsl.inet.fi Bug #29136 erred multi-delete on trans table does not rollback the statement innodb.test, innodb.result: trans table specific test added mysql-test/t/innodb.test: Applied InnoDB snapshot innodb-5.1-ss2298 sql/mysql_priv.h: Make check_global_access() declaration available if when INNODB_COMPATIBILITY_HOOKS is defined. sql/sql_class.cc: Add thd_get_thread_id() accessor function. Add 'extern "C"' to definition for thd_get_xid(). Not strictly needed, but in keeping with our coding style. storage/innobase/btr/btr0cur.c: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2295: branches/5.1: Merge r2294 from branches/5.0: Fix typo and add comma in comment. storage/innobase/handler/ha_innodb.cc: Applied InnoDB snapshot innodb-5.1-ss2298 - But remove the declaration of check_global_access() from ha_innodb.cc, because it is now visible in mysql_priv.h under INNODB_COMPATIBILITY_HOOKS Revision r2270: branches/5.1: Rename the user visible parameter innodb-use-adaptive-hash-indexes to innodb-adaptive-hash-index so that it is in sync with MySQL 5.0. Suggested by: Heikki Approved by: Heikki Revision r2236: branches/5.1: bug#33349 Introduce retry/sleep logic as a workaround for a transient bug where ::open fails for partitioned tables randomly if we are using one file per table. Reviewed by: Heikki Revision r2282: branches/5.1: Fix Bug#34053: * In CREATE TABLE and DROP TABLE check whether the table in question is one of the magic innodb_monitor tables and whether the user has enough rights to mess with it before doing anything else. * Implement a mysql-test testcase. Approved by: Heikki Revision r2246: branches/5.1: Fix formatting of the autoinc-lock-mode command line parameter. Old view (./mysqld --help --verbose): --innodb-autoinc-lock-mode=# The AUTOINC lock modes supported by InnoDB: 0 => Old style AUTOINC locking (for backward compatibility) 1 => New style AUTOINC locking 2 => No AUTOINC locking (unsafe for SBR) New view: --innodb-autoinc-lock-mode=# The AUTOINC lock modes supported by InnoDB: 0 => Old style AUTOINC locking (for backward compatibility) 1 => New style AUTOINC locking 2 => No AUTOINC locking (unsafe for SBR) Looks like these strings are "automatically" wrapped by MySQL in the following way: * newlines (\n) in the string are ignored * newline separator (\n) is inserted every 57 or so characters. * lots of white space is appended to each inserted new line. Approved by: Heikki storage/innobase/include/os0sync.h: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2268: branches/5.1: Port of r2267 This is a combination of changes that forward port the scalability fix applied to 5.0 through r1001. It reverts changes r149 and r122 (these were 5.1 specific changes made in lieu of scalability fix of 5.0) Then it applies r1001 to 5.0 which is the original scalability fix. Finally it applies r2082 which fixes an issue with the original fix. Reviewed by: Heikki storage/innobase/include/read0read.h: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2188: branches/5.1: Remove unused field can_be_too_old from read_view_struct. storage/innobase/include/row0mysql.h: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2282: branches/5.1: Fix Bug#34053: * In CREATE TABLE and DROP TABLE check whether the table in question is one of the magic innodb_monitor tables and whether the user has enough rights to mess with it before doing anything else. * Implement a mysql-test testcase. Approved by: Heikki Revision r2272: branches/5.1: Fix typo in comment. storage/innobase/include/sync0arr.h: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2268: branches/5.1: Port of r2267 This is a combination of changes that forward port the scalability fix applied to 5.0 through r1001. It reverts changes r149 and r122 (these were 5.1 specific changes made in lieu of scalability fix of 5.0) Then it applies r1001 to 5.0 which is the original scalability fix. Finally it applies r2082 which fixes an issue with the original fix. Reviewed by: Heikki storage/innobase/include/sync0rw.h: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2268: branches/5.1: Port of r2267 This is a combination of changes that forward port the scalability fix applied to 5.0 through r1001. It reverts changes r149 and r122 (these were 5.1 specific changes made in lieu of scalability fix of 5.0) Then it applies r1001 to 5.0 which is the original scalability fix. Finally it applies r2082 which fixes an issue with the original fix. Reviewed by: Heikki storage/innobase/include/sync0rw.ic: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2268: branches/5.1: Port of r2267 This is a combination of changes that forward port the scalability fix applied to 5.0 through r1001. It reverts changes r149 and r122 (these were 5.1 specific changes made in lieu of scalability fix of 5.0) Then it applies r1001 to 5.0 which is the original scalability fix. Finally it applies r2082 which fixes an issue with the original fix. Reviewed by: Heikki storage/innobase/include/sync0sync.h: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2268: branches/5.1: Port of r2267 This is a combination of changes that forward port the scalability fix applied to 5.0 through r1001. It reverts changes r149 and r122 (these were 5.1 specific changes made in lieu of scalability fix of 5.0) Then it applies r1001 to 5.0 which is the original scalability fix. Finally it applies r2082 which fixes an issue with the original fix. Reviewed by: Heikki storage/innobase/include/sync0sync.ic: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2268: branches/5.1: Port of r2267 This is a combination of changes that forward port the scalability fix applied to 5.0 through r1001. It reverts changes r149 and r122 (these were 5.1 specific changes made in lieu of scalability fix of 5.0) Then it applies r1001 to 5.0 which is the original scalability fix. Finally it applies r2082 which fixes an issue with the original fix. Reviewed by: Heikki storage/innobase/os/os0sync.c: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2268: branches/5.1: Port of r2267 This is a combination of changes that forward port the scalability fix applied to 5.0 through r1001. It reverts changes r149 and r122 (these were 5.1 specific changes made in lieu of scalability fix of 5.0) Then it applies r1001 to 5.0 which is the original scalability fix. Finally it applies r2082 which fixes an issue with the original fix. Reviewed by: Heikki storage/innobase/read/read0read.c: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2188: branches/5.1: Remove unused field can_be_too_old from read_view_struct. storage/innobase/row/row0mysql.c: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2282: branches/5.1: Fix Bug#34053: * In CREATE TABLE and DROP TABLE check whether the table in question is one of the magic innodb_monitor tables and whether the user has enough rights to mess with it before doing anything else. * Implement a mysql-test testcase. Approved by: Heikki Revision r2272: branches/5.1: Fix typo in comment. storage/innobase/srv/srv0srv.c: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2268: branches/5.1: Port of r2267 This is a combination of changes that forward port the scalability fix applied to 5.0 through r1001. It reverts changes r149 and r122 (these were 5.1 specific changes made in lieu of scalability fix of 5.0) Then it applies r1001 to 5.0 which is the original scalability fix. Finally it applies r2082 which fixes an issue with the original fix. Reviewed by: Heikki storage/innobase/sync/sync0arr.c: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2268: branches/5.1: Port of r2267 This is a combination of changes that forward port the scalability fix applied to 5.0 through r1001. It reverts changes r149 and r122 (these were 5.1 specific changes made in lieu of scalability fix of 5.0) Then it applies r1001 to 5.0 which is the original scalability fix. Finally it applies r2082 which fixes an issue with the original fix. Reviewed by: Heikki storage/innobase/sync/sync0rw.c: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2268: branches/5.1: Port of r2267 This is a combination of changes that forward port the scalability fix applied to 5.0 through r1001. It reverts changes r149 and r122 (these were 5.1 specific changes made in lieu of scalability fix of 5.0) Then it applies r1001 to 5.0 which is the original scalability fix. Finally it applies r2082 which fixes an issue with the original fix. Reviewed by: Heikki storage/innobase/sync/sync0sync.c: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2268: branches/5.1: Port of r2267 This is a combination of changes that forward port the scalability fix applied to 5.0 through r1001. It reverts changes r149 and r122 (these were 5.1 specific changes made in lieu of scalability fix of 5.0) Then it applies r1001 to 5.0 which is the original scalability fix. Finally it applies r2082 which fixes an issue with the original fix. Reviewed by: Heikki mysql-test/r/innodb_bug34053.result: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2282: branches/5.1: Fix Bug#34053: * In CREATE TABLE and DROP TABLE check whether the table in question is one of the magic innodb_monitor tables and whether the user has enough rights to mess with it before doing anything else. * Implement a mysql-test testcase. Approved by: Heikki mysql-test/t/innodb_bug34053.test: Applied InnoDB snapshot innodb-5.1-ss2298 Revision r2282: branches/5.1: Fix Bug#34053: * In CREATE TABLE and DROP TABLE check whether the table in question is one of the magic innodb_monitor tables and whether the user has enough rights to mess with it before doing anything else. * Implement a mysql-test testcase. Approved by: Heikki
260 lines
7.1 KiB
Text
260 lines
7.1 KiB
Text
/******************************************************
|
|
Mutex, the basic synchronization primitive
|
|
|
|
(c) 1995 Innobase Oy
|
|
|
|
Created 9/5/1995 Heikki Tuuri
|
|
*******************************************************/
|
|
|
|
#if defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86)
|
|
/* %z0: Use the size of operand %0 which in our case is *m to determine
|
|
instruction size, it should end up as xchgl. "1" in the input constraint,
|
|
says that "in" has to go in the same place as "out".*/
|
|
#define TAS(m, in, out) \
|
|
asm volatile ("xchg%z0 %2, %0" \
|
|
: "=g" (*(m)), "=r" (out) \
|
|
: "1" (in)) /* Note: "1" here refers to "=r" (out) */
|
|
#endif
|
|
|
|
/**********************************************************************
|
|
Sets the waiters field in a mutex. */
|
|
|
|
void
|
|
mutex_set_waiters(
|
|
/*==============*/
|
|
mutex_t* mutex, /* in: mutex */
|
|
ulint n); /* in: value to set */
|
|
/**********************************************************************
|
|
Reserves a mutex for the current thread. If the mutex is reserved, the
|
|
function spins a preset time (controlled by SYNC_SPIN_ROUNDS) waiting
|
|
for the mutex before suspending the thread. */
|
|
|
|
void
|
|
mutex_spin_wait(
|
|
/*============*/
|
|
mutex_t* mutex, /* in: pointer to mutex */
|
|
const char* file_name, /* in: file name where mutex
|
|
requested */
|
|
ulint line); /* in: line where requested */
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
/**********************************************************************
|
|
Sets the debug information for a reserved mutex. */
|
|
|
|
void
|
|
mutex_set_debug_info(
|
|
/*=================*/
|
|
mutex_t* mutex, /* in: mutex */
|
|
const char* file_name, /* in: file where requested */
|
|
ulint line); /* in: line where requested */
|
|
#endif /* UNIV_SYNC_DEBUG */
|
|
/**********************************************************************
|
|
Releases the threads waiting in the primary wait array for this mutex. */
|
|
|
|
void
|
|
mutex_signal_object(
|
|
/*================*/
|
|
mutex_t* mutex); /* in: mutex */
|
|
|
|
/**********************************************************************
|
|
Performs an atomic test-and-set instruction to the lock_word field of a
|
|
mutex. */
|
|
UNIV_INLINE
|
|
ulint
|
|
mutex_test_and_set(
|
|
/*===============*/
|
|
/* out: the previous value of lock_word: 0 or
|
|
1 */
|
|
mutex_t* mutex) /* in: mutex */
|
|
{
|
|
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
|
|
ulint res;
|
|
ulint* lw; /* assembler code is used to ensure that
|
|
lock_word is loaded from memory */
|
|
ut_ad(mutex);
|
|
ut_ad(sizeof(ulint) == 4);
|
|
|
|
lw = &(mutex->lock_word);
|
|
|
|
__asm MOV ECX, lw
|
|
__asm MOV EDX, 1
|
|
__asm XCHG EDX, DWORD PTR [ECX]
|
|
__asm MOV res, EDX
|
|
|
|
/* The fence below would prevent this thread from
|
|
reading the data structure protected by the mutex
|
|
before the test-and-set operation is committed, but
|
|
the fence is apparently not needed:
|
|
|
|
In a posting to comp.arch newsgroup (August 10, 1997)
|
|
Andy Glew said that in P6 a LOCKed instruction like
|
|
XCHG establishes a fence with respect to memory reads
|
|
and writes and thus an explicit fence is not
|
|
needed. In P5 he seemed to agree with a previous
|
|
newsgroup poster that LOCKed instructions serialize
|
|
all instruction execution, and, consequently, also
|
|
memory operations. This is confirmed in Intel Software
|
|
Dev. Manual, Vol. 3. */
|
|
|
|
/* mutex_fence(); */
|
|
|
|
return(res);
|
|
#elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86)
|
|
ulint res;
|
|
|
|
TAS(&mutex->lock_word, 1, res);
|
|
|
|
return(res);
|
|
#else
|
|
ibool ret;
|
|
|
|
ret = os_fast_mutex_trylock(&(mutex->os_fast_mutex));
|
|
|
|
if (ret == 0) {
|
|
/* We check that os_fast_mutex_trylock does not leak
|
|
and allow race conditions */
|
|
ut_a(mutex->lock_word == 0);
|
|
|
|
mutex->lock_word = 1;
|
|
}
|
|
|
|
return(ret);
|
|
#endif
|
|
}
|
|
|
|
/**********************************************************************
|
|
Performs a reset instruction to the lock_word field of a mutex. This
|
|
instruction also serializes memory operations to the program order. */
|
|
UNIV_INLINE
|
|
void
|
|
mutex_reset_lock_word(
|
|
/*==================*/
|
|
mutex_t* mutex) /* in: mutex */
|
|
{
|
|
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
|
|
ulint* lw; /* assembler code is used to ensure that
|
|
lock_word is loaded from memory */
|
|
ut_ad(mutex);
|
|
|
|
lw = &(mutex->lock_word);
|
|
|
|
__asm MOV EDX, 0
|
|
__asm MOV ECX, lw
|
|
__asm XCHG EDX, DWORD PTR [ECX]
|
|
#elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86)
|
|
ulint res;
|
|
|
|
TAS(&mutex->lock_word, 0, res);
|
|
#else
|
|
mutex->lock_word = 0;
|
|
|
|
os_fast_mutex_unlock(&(mutex->os_fast_mutex));
|
|
#endif
|
|
}
|
|
|
|
/**********************************************************************
|
|
Gets the value of the lock word. */
|
|
UNIV_INLINE
|
|
ulint
|
|
mutex_get_lock_word(
|
|
/*================*/
|
|
const mutex_t* mutex) /* in: mutex */
|
|
{
|
|
const volatile ulint* ptr; /* declared volatile to ensure that
|
|
lock_word is loaded from memory */
|
|
ut_ad(mutex);
|
|
|
|
ptr = &(mutex->lock_word);
|
|
|
|
return(*ptr);
|
|
}
|
|
|
|
/**********************************************************************
|
|
Gets the waiters field in a mutex. */
|
|
UNIV_INLINE
|
|
ulint
|
|
mutex_get_waiters(
|
|
/*==============*/
|
|
/* out: value to set */
|
|
const mutex_t* mutex) /* in: mutex */
|
|
{
|
|
const volatile ulint* ptr; /* declared volatile to ensure that
|
|
the value is read from memory */
|
|
ut_ad(mutex);
|
|
|
|
ptr = &(mutex->waiters);
|
|
|
|
return(*ptr); /* Here we assume that the read of a single
|
|
word from memory is atomic */
|
|
}
|
|
|
|
/**********************************************************************
|
|
Unlocks a mutex owned by the current thread. */
|
|
UNIV_INLINE
|
|
void
|
|
mutex_exit(
|
|
/*=======*/
|
|
mutex_t* mutex) /* in: pointer to mutex */
|
|
{
|
|
ut_ad(mutex_own(mutex));
|
|
|
|
ut_d(mutex->thread_id = ULINT_UNDEFINED);
|
|
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
sync_thread_reset_level(mutex);
|
|
#endif
|
|
mutex_reset_lock_word(mutex);
|
|
|
|
/* A problem: we assume that mutex_reset_lock word
|
|
is a memory barrier, that is when we read the waiters
|
|
field next, the read must be serialized in memory
|
|
after the reset. A speculative processor might
|
|
perform the read first, which could leave a waiting
|
|
thread hanging indefinitely.
|
|
|
|
Our current solution call every second
|
|
sync_arr_wake_threads_if_sema_free()
|
|
to wake up possible hanging threads if
|
|
they are missed in mutex_signal_object. */
|
|
|
|
if (mutex_get_waiters(mutex) != 0) {
|
|
|
|
mutex_signal_object(mutex);
|
|
}
|
|
|
|
#ifdef UNIV_SYNC_PERF_STAT
|
|
mutex_exit_count++;
|
|
#endif
|
|
}
|
|
|
|
/**********************************************************************
|
|
Locks a mutex for the current thread. If the mutex is reserved, the function
|
|
spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting for the mutex
|
|
before suspending the thread. */
|
|
UNIV_INLINE
|
|
void
|
|
mutex_enter_func(
|
|
/*=============*/
|
|
mutex_t* mutex, /* in: pointer to mutex */
|
|
const char* file_name, /* in: file name where locked */
|
|
ulint line) /* in: line where locked */
|
|
{
|
|
ut_ad(mutex_validate(mutex));
|
|
ut_ad(!mutex_own(mutex));
|
|
|
|
/* Note that we do not peek at the value of lock_word before trying
|
|
the atomic test_and_set; we could peek, and possibly save time. */
|
|
|
|
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
|
|
mutex->count_using++;
|
|
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
|
|
|
|
if (!mutex_test_and_set(mutex)) {
|
|
ut_d(mutex->thread_id = os_thread_get_curr_id());
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
mutex_set_debug_info(mutex, file_name, line);
|
|
#endif
|
|
return; /* Succeeded! */
|
|
}
|
|
|
|
mutex_spin_wait(mutex, file_name, line);
|
|
}
|