diff options
-rw-r--r-- | mysys/thr_lock.c | 1 | ||||
-rw-r--r-- | sql/sql_base.cc | 1 | ||||
-rw-r--r-- | storage/maria/ma_bitmap.c | 85 | ||||
-rw-r--r-- | storage/maria/ma_blockrec.c | 4 | ||||
-rw-r--r-- | storage/maria/ma_blockrec.h | 2 | ||||
-rw-r--r-- | storage/maria/maria_def.h | 2 | ||||
-rw-r--r-- | storage/myisam/mi_locking.c | 2 |
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; } |