summaryrefslogtreecommitdiff
path: root/storage/innobase/os/os0sync.c
diff options
context:
space:
mode:
authorunknown <tsmith@ramayana.hindu.god>2008-02-19 09:44:09 -0700
committerunknown <tsmith@ramayana.hindu.god>2008-02-19 09:44:09 -0700
commit4b25d5b10cfc47b4ab54f7bcc8dfb4d91c1f4e6d (patch)
tree8af22ca5cf6bdcbc449792ff5facec90aae7fc5f /storage/innobase/os/os0sync.c
parent41b01b7f2142159c17c0180194f1adda8857d5c6 (diff)
downloadmariadb-git-4b25d5b10cfc47b4ab54f7bcc8dfb4d91c1f4e6d.tar.gz
Applied InnoDB snapshot innodb-5.1-ss2298
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
Diffstat (limited to 'storage/innobase/os/os0sync.c')
-rw-r--r--storage/innobase/os/os0sync.c111
1 files changed, 100 insertions, 11 deletions
diff --git a/storage/innobase/os/os0sync.c b/storage/innobase/os/os0sync.c
index 9c6b1134e12..18fd38f3f9b 100644
--- a/storage/innobase/os/os0sync.c
+++ b/storage/innobase/os/os0sync.c
@@ -21,6 +21,7 @@ Created 9/6/1995 Heikki Tuuri
/* Type definition for an operating system mutex struct */
struct os_mutex_struct{
+ os_event_t event; /* Used by sync0arr.c for queing threads */
void* handle; /* OS handle to mutex */
ulint count; /* we use this counter to check
that the same thread does not
@@ -35,6 +36,7 @@ struct os_mutex_struct{
/* Mutex protecting counts and the lists of OS mutexes and events */
os_mutex_t os_sync_mutex;
ibool os_sync_mutex_inited = FALSE;
+ibool os_sync_free_called = FALSE;
/* This is incremented by 1 in os_thread_create and decremented by 1 in
os_thread_exit */
@@ -50,6 +52,10 @@ ulint os_event_count = 0;
ulint os_mutex_count = 0;
ulint os_fast_mutex_count = 0;
+/* Because a mutex is embedded inside an event and there is an
+event embedded inside a mutex, on free, this generates a recursive call.
+This version of the free event function doesn't acquire the global lock */
+static void os_event_free_internal(os_event_t event);
/*************************************************************
Initializes global event and OS 'slow' mutex lists. */
@@ -76,6 +82,7 @@ os_sync_free(void)
os_event_t event;
os_mutex_t mutex;
+ os_sync_free_called = TRUE;
event = UT_LIST_GET_FIRST(os_event_list);
while (event) {
@@ -99,6 +106,7 @@ os_sync_free(void)
mutex = UT_LIST_GET_FIRST(os_mutex_list);
}
+ os_sync_free_called = FALSE;
}
/*************************************************************
@@ -144,17 +152,31 @@ os_event_create(
ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));
#endif
event->is_set = FALSE;
- event->signal_count = 0;
+
+ /* We return this value in os_event_reset(), which can then be
+ be used to pass to the os_event_wait_low(). The value of zero
+ is reserved in os_event_wait_low() for the case when the
+ caller does not want to pass any signal_count value. To
+ distinguish between the two cases we initialize signal_count
+ to 1 here. */
+ event->signal_count = 1;
#endif /* __WIN__ */
- /* Put to the list of events */
- os_mutex_enter(os_sync_mutex);
+ /* The os_sync_mutex can be NULL because during startup an event
+ can be created [ because it's embedded in the mutex/rwlock ] before
+ this module has been initialized */
+ if (os_sync_mutex != NULL) {
+ os_mutex_enter(os_sync_mutex);
+ }
+ /* Put to the list of events */
UT_LIST_ADD_FIRST(os_event_list, os_event_list, event);
os_event_count++;
- os_mutex_exit(os_sync_mutex);
+ if (os_sync_mutex != NULL) {
+ os_mutex_exit(os_sync_mutex);
+ }
return(event);
}
@@ -231,13 +253,20 @@ os_event_set(
/**************************************************************
Resets an event semaphore to the nonsignaled state. Waiting threads will
-stop to wait for the event. */
+stop to wait for the event.
+The return value should be passed to os_even_wait_low() if it is desired
+that this thread should not wait in case of an intervening call to
+os_event_set() between this os_event_reset() and the
+os_event_wait_low() call. See comments for os_event_wait_low(). */
-void
+ib_longlong
os_event_reset(
/*===========*/
+ /* out: current signal_count. */
os_event_t event) /* in: event to reset */
{
+ ib_longlong ret = 0;
+
#ifdef __WIN__
ut_a(event);
@@ -252,9 +281,40 @@ os_event_reset(
} else {
event->is_set = FALSE;
}
+ ret = event->signal_count;
os_fast_mutex_unlock(&(event->os_mutex));
#endif
+ return(ret);
+}
+
+/**************************************************************
+Frees an event object, without acquiring the global lock. */
+static
+void
+os_event_free_internal(
+/*===================*/
+ os_event_t event) /* in: event to free */
+{
+#ifdef __WIN__
+ ut_a(event);
+
+ ut_a(CloseHandle(event->handle));
+#else
+ ut_a(event);
+
+ /* This is to avoid freeing the mutex twice */
+ os_fast_mutex_free(&(event->os_mutex));
+
+ ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
+#endif
+ /* Remove from the list of events */
+
+ UT_LIST_REMOVE(os_event_list, os_event_list, event);
+
+ os_event_count--;
+
+ ut_free(event);
}
/**************************************************************
@@ -293,18 +353,38 @@ os_event_free(
Waits for an event object until it is in the signaled state. If
srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
waiting thread when the event becomes signaled (or immediately if the
-event is already in the signaled state). */
+event is already in the signaled state).
+
+Typically, if the event has been signalled after the os_event_reset()
+we'll return immediately because event->is_set == TRUE.
+There are, however, situations (e.g.: sync_array code) where we may
+lose this information. For example:
+
+thread A calls os_event_reset()
+thread B calls os_event_set() [event->is_set == TRUE]
+thread C calls os_event_reset() [event->is_set == FALSE]
+thread A calls os_event_wait() [infinite wait!]
+thread C calls os_event_wait() [infinite wait!]
+
+Where such a scenario is possible, to avoid infinite wait, the
+value returned by os_event_reset() should be passed in as
+reset_sig_count. */
void
-os_event_wait(
-/*==========*/
- os_event_t event) /* in: event to wait */
+os_event_wait_low(
+/*==============*/
+ os_event_t event, /* in: event to wait */
+ ib_longlong reset_sig_count)/* in: zero or the value
+ returned by previous call of
+ os_event_reset(). */
{
#ifdef __WIN__
DWORD err;
ut_a(event);
+ UT_NOT_USED(reset_sig_count);
+
/* Specify an infinite time limit for waiting */
err = WaitForSingleObject(event->handle, INFINITE);
@@ -318,7 +398,11 @@ os_event_wait(
os_fast_mutex_lock(&(event->os_mutex));
- old_signal_count = event->signal_count;
+ if (reset_sig_count) {
+ old_signal_count = reset_sig_count;
+ } else {
+ old_signal_count = event->signal_count;
+ }
for (;;) {
if (event->is_set == TRUE
@@ -458,6 +542,7 @@ os_mutex_create(
mutex_str->handle = mutex;
mutex_str->count = 0;
+ mutex_str->event = os_event_create(NULL);
if (os_sync_mutex_inited) {
/* When creating os_sync_mutex itself we cannot reserve it */
@@ -534,6 +619,10 @@ os_mutex_free(
{
ut_a(mutex);
+ if (!os_sync_free_called) {
+ os_event_free_internal(mutex->event);
+ }
+
if (os_sync_mutex_inited) {
os_mutex_enter(os_sync_mutex);
}