summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysys/thr_lock.c1
-rw-r--r--sql/sql_base.cc1
-rw-r--r--storage/maria/ma_bitmap.c85
-rw-r--r--storage/maria/ma_blockrec.c4
-rw-r--r--storage/maria/ma_blockrec.h2
-rw-r--r--storage/maria/maria_def.h2
-rw-r--r--storage/myisam/mi_locking.c2
7 files changed, 86 insertions, 11 deletions
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index 9c8236ae0e6..341b2f0058e 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -406,6 +406,7 @@ void thr_lock_data_init(THR_LOCK *lock,THR_LOCK_DATA *data, void *param)
data->owner= 0; /* no owner yet */
data->status_param=param;
data->cond=0;
+ data->priority= 0;
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 708b4d6126b..2be9dcfb777 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -4280,7 +4280,6 @@ void detach_merge_children(TABLE *table, bool clear_refs)
{
TABLE_LIST *child_l;
TABLE *parent= table->child_l ? table : table->parent;
- bool first_detach;
DBUG_ENTER("detach_merge_children");
/*
Either table->child_l or table->parent must be set. Parent must have
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
index c96e0bd7a86..c0763b0612d 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -227,7 +227,8 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
The +1 is to add the bitmap page, as this doesn't have to be covered
*/
bitmap->pages_covered= aligned_bit_blocks * 16 + 1;
- bitmap->flush_all_requested= bitmap->non_flushable= 0;
+ bitmap->flush_all_requested= 0;
+ bitmap->non_flushable= 0;
/* Update size for bits */
/* TODO; Make this dependent of the row size */
@@ -311,8 +312,8 @@ my_bool _ma_bitmap_flush(MARIA_SHARE *share)
pthread_mutex_lock(&share->bitmap.bitmap_lock);
if (share->bitmap.changed)
{
- share->bitmap.changed= 0;
res= write_changed_bitmap(share, &share->bitmap);
+ share->bitmap.changed= 0;
}
pthread_mutex_unlock(&share->bitmap.bitmap_lock);
}
@@ -355,7 +356,7 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share)
pthread_mutex_lock(&bitmap->bitmap_lock);
if (bitmap->changed || bitmap->changed_not_flushed)
{
- bitmap->flush_all_requested= TRUE;
+ bitmap->flush_all_requested++;
#ifndef WRONG_BITMAP_FLUSH
while (bitmap->non_flushable > 0)
{
@@ -363,6 +364,7 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share)
pthread_cond_wait(&bitmap->bitmap_cond, &bitmap->bitmap_lock);
}
#endif
+ DBUG_ASSERT(bitmap->flush_all_requested == 1);
/*
Bitmap is in a flushable state: its contents in memory are reflected by
log records (complete REDO-UNDO groups) and all bitmap pages are
@@ -391,7 +393,7 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share)
PCFLUSH_PINNED_AND_ERROR)
res= TRUE;
bitmap->changed_not_flushed= FALSE;
- bitmap->flush_all_requested= FALSE;
+ bitmap->flush_all_requested--;
/*
Some well-behaved threads may be waiting for flush_all_requested to
become false, wake them up.
@@ -405,6 +407,70 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share)
/**
+ @brief Lock bitmap from being used by another thread
+
+ @fn _ma_bitmap_lock()
+ @param share Table's share
+
+ @notes
+ This is a temporary solution for allowing someone to delete an inserted
+ duplicate-key row while someone else is doing concurrent inserts.
+ This is ok for now as duplicate key errors are not that common.
+
+ In the future we will add locks for row-pages to ensure two threads doesn't
+ work at the same time on the same page.
+*/
+
+void _ma_bitmap_lock(MARIA_SHARE *share)
+{
+ MARIA_FILE_BITMAP *bitmap= &share->bitmap;
+ DBUG_ENTER("_ma_bitmap_lock");
+
+ if (!share->now_transactional)
+ DBUG_VOID_RETURN;
+
+ pthread_mutex_lock(&bitmap->bitmap_lock);
+ bitmap->flush_all_requested++;
+ while (bitmap->non_flushable)
+ {
+ DBUG_PRINT("info", ("waiting for bitmap to be flushable"));
+ pthread_cond_wait(&bitmap->bitmap_cond, &bitmap->bitmap_lock);
+ }
+ /*
+ Ensure that _ma_bitmap_flush_all() and _ma_bitmap_lock() are blocked.
+ ma_bitmap_flushable() is blocked thanks to 'flush_all_requested'.
+ */
+ bitmap->non_flushable= 1;
+ pthread_mutex_unlock(&bitmap->bitmap_lock);
+ DBUG_VOID_RETURN;
+}
+
+/**
+ @brief Unlock bitmap after _ma_bitmap_lock()
+
+ @fn _ma_bitmap_unlock()
+ @param share Table's share
+*/
+
+void _ma_bitmap_unlock(MARIA_SHARE *share)
+{
+ MARIA_FILE_BITMAP *bitmap= &share->bitmap;
+ DBUG_ENTER("_ma_bitmap_unlock");
+
+ if (!share->now_transactional)
+ DBUG_VOID_RETURN;
+ DBUG_ASSERT(bitmap->flush_all_requested > 0 && bitmap->non_flushable == 1);
+
+ pthread_mutex_lock(&bitmap->bitmap_lock);
+ bitmap->flush_all_requested--;
+ bitmap->non_flushable= 0;
+ pthread_mutex_unlock(&bitmap->bitmap_lock);
+ pthread_cond_broadcast(&bitmap->bitmap_cond);
+ DBUG_VOID_RETURN;
+}
+
+
+/**
@brief Unpin all pinned bitmap pages
@param share Table's share
@@ -633,11 +699,12 @@ static void _ma_print_bitmap_changes(MARIA_FILE_BITMAP *bitmap)
{
uchar *pos, *end, *org_pos;
ulong page;
+ DBUG_ENTER("_ma_print_bitmap_changes");
end= bitmap->map + bitmap->used_size;
DBUG_LOCK_FILE;
- fprintf(DBUG_FILE,"\nBitmap page changes at page %lu\n",
- (ulong) bitmap->page);
+ fprintf(DBUG_FILE,"\nBitmap page changes at page: %lu bitmap: 0x%lx\n",
+ (ulong) bitmap->page, (long) bitmap->map);
page= (ulong) bitmap->page+1;
for (pos= bitmap->map, org_pos= bitmap->map + bitmap->block_size ;
@@ -666,6 +733,7 @@ static void _ma_print_bitmap_changes(MARIA_FILE_BITMAP *bitmap)
fputc('\n', DBUG_FILE);
DBUG_UNLOCK_FILE;
memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size);
+ DBUG_VOID_RETURN;
}
@@ -877,6 +945,7 @@ static void fill_block(MARIA_FILE_BITMAP *bitmap,
{
uint page, offset, tmp;
uchar *data;
+ DBUG_ENTER("fill_block");
/* For each 6 bytes we have 6*8/3= 16 patterns */
page= ((uint) (best_data - bitmap->map)) / 6 * 16 + best_pos;
@@ -902,6 +971,7 @@ static void fill_block(MARIA_FILE_BITMAP *bitmap,
int2store(data, tmp);
bitmap->changed= 1;
DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap););
+ DBUG_VOID_RETURN;
}
@@ -1514,6 +1584,8 @@ static void use_head(MARIA_HA *info, pgcache_page_no_t page, uint size,
MARIA_BITMAP_BLOCK *block;
uchar *data;
uint offset, tmp, offset_page;
+ DBUG_ENTER("use_head");
+
DBUG_ASSERT(page % bitmap->pages_covered);
block= dynamic_element(&info->bitmap_blocks, block_position,
@@ -1536,6 +1608,7 @@ static void use_head(MARIA_HA *info, pgcache_page_no_t page, uint size,
int2store(data, tmp);
bitmap->changed= 1;
DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap););
+ DBUG_VOID_RETURN;
}
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index bc2b1d5187f..0eab7c62796 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -3592,7 +3592,7 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info)
MARIA_SHARE *share= info->s;
DBUG_ENTER("_ma_write_abort_block_record");
- _ma_bitmap_flushable(info, 1);
+ _ma_bitmap_lock(share); /* Lock bitmap from other insert threads */
if (delete_head_or_tail(info,
ma_recordpos_to_page(info->cur_row.lastpos),
ma_recordpos_to_dir_entry(info->cur_row.lastpos), 1,
@@ -3630,7 +3630,7 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info)
&lsn, (void*) 0))
res= 1;
}
- _ma_bitmap_flushable(info, -1);
+ _ma_bitmap_unlock(share);
_ma_unpin_all_pages_and_finalize_row(info, lsn);
DBUG_RETURN(res);
}
diff --git a/storage/maria/ma_blockrec.h b/storage/maria/ma_blockrec.h
index d18b20aa387..a5858880dd0 100644
--- a/storage/maria/ma_blockrec.h
+++ b/storage/maria/ma_blockrec.h
@@ -217,6 +217,8 @@ uint _ma_bitmap_get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
void _ma_bitmap_delete_all(MARIA_SHARE *share);
int _ma_bitmap_create_first(MARIA_SHARE *share);
void _ma_bitmap_flushable(MARIA_HA *info, int non_flushable_inc);
+void _ma_bitmap_lock(MARIA_SHARE *share);
+void _ma_bitmap_unlock(MARIA_SHARE *share);
void _ma_bitmap_set_pagecache_callbacks(PAGECACHE_FILE *file,
MARIA_SHARE *share);
#ifndef DBUG_OFF
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 6be34aae98c..bdc4d4c5ed2 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -246,7 +246,7 @@ typedef struct st_maria_file_bitmap
uint used_size; /* Size of bitmap head that is not 0 */
my_bool changed; /* 1 if page needs to be written */
my_bool changed_not_flushed; /* 1 if some bitmap is not flushed */
- my_bool flush_all_requested; /**< If _ma_bitmap_flush_all waiting */
+ uint flush_all_requested; /**< If _ma_bitmap_flush_all waiting */
uint non_flushable; /**< 0 if bitmap and log are in sync */
PAGECACHE_FILE file; /* datafile where bitmap is stored */
diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c
index 19ec8337539..9de043b8867 100644
--- a/storage/myisam/mi_locking.c
+++ b/storage/myisam/mi_locking.c
@@ -246,7 +246,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
a crash on windows if the table is renamed and
later on referenced by the merge table.
*/
- if ((info->open_flags & HA_OPEN_MERGE_TABLE) && (info->s)->kfile < 0)
+ if ((info->open_flag & HA_OPEN_MERGE_TABLE) && (info->s)->kfile < 0)
{
error = HA_ERR_NO_SUCH_TABLE;
}