summaryrefslogtreecommitdiff
path: root/storage/xtradb/sync
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2015-03-17 20:35:05 +0200
committerJan Lindström <jan.lindstrom@mariadb.com>2015-03-17 20:35:05 +0200
commit99a2c061d7bfc181b04a0adc14ce036fab821d85 (patch)
tree1cad5eb0c4e6becc4aa1c5c4dc25a01b25d7bf19 /storage/xtradb/sync
parent3d4850158fdd62a57cf76515db99f07457f344d5 (diff)
downloadmariadb-git-99a2c061d7bfc181b04a0adc14ce036fab821d85.tar.gz
MDEV-7754: innodb assert "array->n_elems < array->max_elems" on a huge blob update
Problem was that static array was used for storing thread mutex sync levels. Fixed by using std::vector instead. Does not contain test case to avoid too big memory/disk space usage on buildbot VMs.
Diffstat (limited to 'storage/xtradb/sync')
-rw-r--r--storage/xtradb/sync/sync0sync.cc78
1 files changed, 15 insertions, 63 deletions
diff --git a/storage/xtradb/sync/sync0sync.cc b/storage/xtradb/sync/sync0sync.cc
index d02a0df70ca..7e104202f36 100644
--- a/storage/xtradb/sync/sync0sync.cc
+++ b/storage/xtradb/sync/sync0sync.cc
@@ -48,6 +48,8 @@ Created 9/5/1995 Heikki Tuuri
#include "ha_prototypes.h"
#include "my_cpu.h"
+#include <vector>
+
/*
REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX
============================================
@@ -229,12 +231,9 @@ static const ulint SYNC_THREAD_N_LEVELS = 10000;
/** Array for tracking sync levels per thread. */
struct sync_arr_t {
- ulint in_use; /*!< Number of active cells */
ulint n_elems; /*!< Number of elements in the array */
- ulint max_elems; /*!< Maximum elements */
- ulint next_free; /*!< ULINT_UNDEFINED or index of next
- free slot */
- sync_level_t* elems; /*!< Array elements */
+
+ std::vector<sync_level_t> elems; /*!< Vector of elements */
};
/** Mutexes or rw-locks held by a thread */
@@ -1177,10 +1176,9 @@ sync_thread_add_level(
SYNC_LEVEL_VARYING, nothing is done */
ibool relock) /*!< in: TRUE if re-entering an x-lock */
{
- ulint i;
- sync_level_t* slot;
sync_arr_t* array;
sync_thread_t* thread_slot;
+ sync_level_t sync_level;
if (!sync_order_checks_on) {
@@ -1205,21 +1203,11 @@ sync_thread_add_level(
thread_slot = sync_thread_level_arrays_find_slot();
if (thread_slot == NULL) {
- ulint sz;
-
- sz = sizeof(*array)
- + (sizeof(*array->elems) * SYNC_THREAD_N_LEVELS);
/* We have to allocate the level array for a new thread */
- array = static_cast<sync_arr_t*>(calloc(sz, sizeof(char)));
+ array = static_cast<sync_arr_t*>(calloc(1, sizeof(sync_arr_t)));
ut_a(array != NULL);
-
- array->next_free = ULINT_UNDEFINED;
- array->max_elems = SYNC_THREAD_N_LEVELS;
- array->elems = (sync_level_t*) &array[1];
-
thread_slot = sync_thread_level_arrays_find_free();
-
thread_slot->levels = array;
thread_slot->id = os_thread_get_curr_id();
}
@@ -1446,26 +1434,11 @@ sync_thread_add_level(
}
levels_ok:
- if (array->next_free == ULINT_UNDEFINED) {
- ut_a(array->n_elems < array->max_elems);
-
- i = array->n_elems++;
- } else {
- i = array->next_free;
- array->next_free = array->elems[i].level;
- }
-
- ut_a(i < array->n_elems);
- ut_a(i != ULINT_UNDEFINED);
-
- ++array->in_use;
- slot = &array->elems[i];
-
- ut_a(slot->latch == NULL);
-
- slot->latch = latch;
- slot->level = level;
+ array->n_elems++;
+ sync_level.latch = latch;
+ sync_level.level = level;
+ array->elems.push_back(sync_level);
mutex_exit(&sync_thread_mutex);
}
@@ -1483,7 +1456,6 @@ sync_thread_reset_level(
{
sync_arr_t* array;
sync_thread_t* thread_slot;
- ulint i;
if (!sync_order_checks_on) {
@@ -1512,36 +1484,16 @@ sync_thread_reset_level(
array = thread_slot->levels;
- for (i = 0; i < array->n_elems; i++) {
- sync_level_t* slot;
-
- slot = &array->elems[i];
+ for (std::vector<sync_level_t>::iterator it = array->elems.begin(); it != array->elems.end(); ++it) {
+ sync_level_t level = *it;
- if (slot->latch != latch) {
+ if (level.latch != latch) {
continue;
}
- slot->latch = NULL;
-
- /* Update the free slot list. See comment in sync_level_t
- for the level field. */
- slot->level = array->next_free;
- array->next_free = i;
-
- ut_a(array->in_use >= 1);
- --array->in_use;
-
- /* If all cells are idle then reset the free
- list. The assumption is that this will save
- time when we need to scan up to n_elems. */
-
- if (array->in_use == 0) {
- array->n_elems = 0;
- array->next_free = ULINT_UNDEFINED;
- }
-
+ array->elems.erase(it);
+ array->n_elems--;
mutex_exit(&sync_thread_mutex);
-
return(TRUE);
}