diff options
author | tsmith@quadxeon.mysql.com <> | 2006-11-09 05:02:37 +0100 |
---|---|---|
committer | tsmith@quadxeon.mysql.com <> | 2006-11-09 05:02:37 +0100 |
commit | f1e0cf9d285269571e96ac4fc058e7494a69c7c7 (patch) | |
tree | 03d4d71d67b4aaee305c7431903f593ad5229733 /innobase/sync | |
parent | 41117b1226bcb02536bf963d9a18a6140d5ffe1a (diff) | |
download | mariadb-git-f1e0cf9d285269571e96ac4fc058e7494a69c7c7.tar.gz |
This ChangeSet must be null-merged to 5.1. Applied innodb-5.0-ss982, -ss998, -ss1003
Fixes:
- Bug #15815: Very poor performance with multiple queries running concurrently
- Bug #22868: 'Thread thrashing' with > 50 concurrent conns under an upd-intensive workloadw
- Bug #23769: Debug assertion failure with innodb_locks_unsafe_for_binlog
- Bug #24089: Race condition in fil_flush_file_spaces()
Diffstat (limited to 'innobase/sync')
-rw-r--r-- | innobase/sync/sync0arr.c | 119 | ||||
-rw-r--r-- | innobase/sync/sync0rw.c | 2 | ||||
-rw-r--r-- | innobase/sync/sync0sync.c | 8 |
3 files changed, 49 insertions, 80 deletions
diff --git a/innobase/sync/sync0arr.c b/innobase/sync/sync0arr.c index 198ef49ca9f..64f9310bad3 100644 --- a/innobase/sync/sync0arr.c +++ b/innobase/sync/sync0arr.c @@ -62,9 +62,6 @@ struct sync_cell_struct { ibool waiting; /* TRUE if the thread has already called sync_array_event_wait on this cell */ - ibool event_set; /* TRUE if the event is set */ - os_event_t event; /* operating system event - semaphore handle */ time_t reservation_time;/* time when the thread reserved the wait cell */ }; @@ -218,10 +215,7 @@ sync_array_create( for (i = 0; i < n_cells; i++) { cell = sync_array_get_nth_cell(arr, i); cell->wait_object = NULL; - - /* Create an operating system event semaphore with no name */ - cell->event = os_event_create(NULL); - cell->event_set = FALSE; /* it is created in reset state */ + cell->waiting = FALSE; } return(arr); @@ -235,19 +229,12 @@ sync_array_free( /*============*/ sync_array_t* arr) /* in, own: sync wait array */ { - ulint i; - sync_cell_t* cell; ulint protection; ut_a(arr->n_reserved == 0); sync_array_validate(arr); - for (i = 0; i < arr->n_cells; i++) { - cell = sync_array_get_nth_cell(arr, i); - os_event_free(cell->event); - } - protection = arr->protection; /* Release the mutex protecting the wait array complex */ @@ -293,27 +280,19 @@ sync_array_validate( } /*********************************************************************** -Puts the cell event in set state. */ -static -void -sync_cell_event_set( -/*================*/ - sync_cell_t* cell) /* in: array cell */ -{ - os_event_set(cell->event); - cell->event_set = TRUE; -} - -/*********************************************************************** Puts the cell event in reset state. */ static void sync_cell_event_reset( /*==================*/ - sync_cell_t* cell) /* in: array cell */ + ulint type, /* in: lock type mutex/rw_lock */ + void* object) /* in: the rw_lock/mutex object */ { - os_event_reset(cell->event); - cell->event_set = FALSE; + if (type == SYNC_MUTEX) { + os_event_reset(((mutex_t *) object)->event); + } else { + os_event_reset(((rw_lock_t *) object)->event); + } } /********************************************************************** @@ -346,14 +325,7 @@ sync_array_reserve_cell( if (cell->wait_object == NULL) { - /* Make sure the event is reset */ - if (cell->event_set) { - sync_cell_event_reset(cell); - } - - cell->reservation_time = time(NULL); - cell->thread = os_thread_get_curr_id(); - + cell->waiting = FALSE; cell->wait_object = object; if (type == SYNC_MUTEX) { @@ -363,7 +335,6 @@ sync_array_reserve_cell( } cell->request_type = type; - cell->waiting = FALSE; cell->file = file; cell->line = line; @@ -373,6 +344,13 @@ sync_array_reserve_cell( *index = i; sync_array_exit(arr); + + /* Make sure the event is reset */ + sync_cell_event_reset(type, object); + + cell->reservation_time = time(NULL); + + cell->thread = os_thread_get_curr_id(); return; } @@ -408,7 +386,12 @@ sync_array_wait_event( ut_a(!cell->waiting); ut_ad(os_thread_get_curr_id() == cell->thread); - event = cell->event; + if (cell->request_type == SYNC_MUTEX) { + event = ((mutex_t*) cell->wait_object)->event; + } else { + event = ((rw_lock_t*) cell->wait_object)->event; + } + cell->waiting = TRUE; #ifdef UNIV_SYNC_DEBUG @@ -510,10 +493,6 @@ sync_array_cell_print( if (!cell->waiting) { fputs("wait has ended\n", file); } - - if (cell->event_set) { - fputs("wait is ending\n", file); - } } #ifdef UNIV_SYNC_DEBUG @@ -623,7 +602,7 @@ sync_array_detect_deadlock( depth++; - if (cell->event_set || !cell->waiting) { + if (!cell->waiting) { return(FALSE); /* No deadlock here */ } @@ -802,6 +781,7 @@ sync_array_free_cell( ut_a(cell->wait_object != NULL); + cell->waiting = FALSE; cell->wait_object = NULL; ut_a(arr->n_reserved > 0); @@ -811,44 +791,17 @@ sync_array_free_cell( } /************************************************************************** -Looks for the cells in the wait array which refer to the wait object -specified, and sets their corresponding events to the signaled state. In this -way releases the threads waiting for the object to contend for the object. -It is possible that no such cell is found, in which case does nothing. */ +Increments the signalled count. */ void -sync_array_signal_object( -/*=====================*/ - sync_array_t* arr, /* in: wait array */ - void* object) /* in: wait object */ +sync_array_object_signalled( +/*========================*/ + sync_array_t* arr) /* in: wait array */ { - sync_cell_t* cell; - ulint count; - ulint i; - sync_array_enter(arr); arr->sg_count++; - i = 0; - count = 0; - - while (count < arr->n_reserved) { - - cell = sync_array_get_nth_cell(arr, i); - - if (cell->wait_object != NULL) { - - count++; - if (cell->wait_object == object) { - - sync_cell_event_set(cell); - } - } - - i++; - } - sync_array_exit(arr); } @@ -881,7 +834,17 @@ sync_arr_wake_threads_if_sema_free(void) if (sync_arr_cell_can_wake_up(cell)) { - sync_cell_event_set(cell); + if (cell->request_type == SYNC_MUTEX) { + mutex_t* mutex; + + mutex = cell->wait_object; + os_event_set(mutex->event); + } else { + rw_lock_t* lock; + + lock = cell->wait_object; + os_event_set(lock->event); + } } } @@ -911,7 +874,7 @@ sync_array_print_long_waits(void) cell = sync_array_get_nth_cell(sync_primary_wait_array, i); - if (cell->wait_object != NULL + if (cell->wait_object != NULL && cell->waiting && difftime(time(NULL), cell->reservation_time) > 240) { fputs("InnoDB: Warning: a long semaphore wait:\n", stderr); @@ -919,7 +882,7 @@ sync_array_print_long_waits(void) noticed = TRUE; } - if (cell->wait_object != NULL + if (cell->wait_object != NULL && cell->waiting && difftime(time(NULL), cell->reservation_time) > fatal_timeout) { fatal = TRUE; diff --git a/innobase/sync/sync0rw.c b/innobase/sync/sync0rw.c index 973b46fdd50..050de73db9e 100644 --- a/innobase/sync/sync0rw.c +++ b/innobase/sync/sync0rw.c @@ -128,6 +128,7 @@ rw_lock_create_func( lock->last_x_file_name = "not yet reserved"; lock->last_s_line = 0; lock->last_x_line = 0; + lock->event = os_event_create(NULL); mutex_enter(&rw_lock_list_mutex); @@ -163,6 +164,7 @@ rw_lock_free( mutex_free(rw_lock_get_mutex(lock)); mutex_enter(&rw_lock_list_mutex); + os_event_free(lock->event); if (UT_LIST_GET_PREV(list, lock)) { ut_a(UT_LIST_GET_PREV(list, lock)->magic_n == RW_LOCK_MAGIC_N); diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c index 43249f4b96f..95bf83dce79 100644 --- a/innobase/sync/sync0sync.c +++ b/innobase/sync/sync0sync.c @@ -212,6 +212,7 @@ mutex_create_func( os_fast_mutex_init(&(mutex->os_fast_mutex)); mutex->lock_word = 0; #endif + mutex->event = os_event_create(NULL); mutex_set_waiters(mutex, 0); mutex->magic_n = MUTEX_MAGIC_N; #ifdef UNIV_SYNC_DEBUG @@ -288,6 +289,8 @@ mutex_free( mutex_exit(&mutex_list_mutex); } + os_event_free(mutex->event); + #if !defined(_WIN32) || !defined(UNIV_CAN_USE_X86_ASSEMBLER) os_fast_mutex_free(&(mutex->os_fast_mutex)); #endif @@ -564,8 +567,8 @@ mutex_signal_object( /* The memory order of resetting the waiters field and signaling the object is important. See LEMMA 1 above. */ - - sync_array_signal_object(sync_primary_wait_array, mutex); + os_event_set(mutex->event); + sync_array_object_signalled(sync_primary_wait_array); } #ifdef UNIV_SYNC_DEBUG @@ -1114,6 +1117,7 @@ sync_thread_add_level( ut_a(sync_thread_levels_g(array, SYNC_PURGE_SYS)); } else if (level == SYNC_TREE_NODE) { ut_a(sync_thread_levels_contain(array, SYNC_INDEX_TREE) + || sync_thread_levels_contain(array, SYNC_DICT_OPERATION) || sync_thread_levels_g(array, SYNC_TREE_NODE - 1)); } else if (level == SYNC_TREE_NODE_FROM_HASH) { ut_a(1); |