Automatic merge
This commit is contained in:
commit
f81956289a
@ -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->owner= 0; /* no owner yet */
|
||||||
data->status_param=param;
|
data->status_param=param;
|
||||||
data->cond=0;
|
data->cond=0;
|
||||||
|
data->priority= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4280,7 +4280,6 @@ void detach_merge_children(TABLE *table, bool clear_refs)
|
|||||||
{
|
{
|
||||||
TABLE_LIST *child_l;
|
TABLE_LIST *child_l;
|
||||||
TABLE *parent= table->child_l ? table : table->parent;
|
TABLE *parent= table->child_l ? table : table->parent;
|
||||||
bool first_detach;
|
|
||||||
DBUG_ENTER("detach_merge_children");
|
DBUG_ENTER("detach_merge_children");
|
||||||
/*
|
/*
|
||||||
Either table->child_l or table->parent must be set. Parent must have
|
Either table->child_l or table->parent must be set. Parent must have
|
||||||
|
@ -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
|
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->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 */
|
/* Update size for bits */
|
||||||
/* TODO; Make this dependent of the row size */
|
/* 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);
|
pthread_mutex_lock(&share->bitmap.bitmap_lock);
|
||||||
if (share->bitmap.changed)
|
if (share->bitmap.changed)
|
||||||
{
|
{
|
||||||
share->bitmap.changed= 0;
|
|
||||||
res= write_changed_bitmap(share, &share->bitmap);
|
res= write_changed_bitmap(share, &share->bitmap);
|
||||||
|
share->bitmap.changed= 0;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&share->bitmap.bitmap_lock);
|
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);
|
pthread_mutex_lock(&bitmap->bitmap_lock);
|
||||||
if (bitmap->changed || bitmap->changed_not_flushed)
|
if (bitmap->changed || bitmap->changed_not_flushed)
|
||||||
{
|
{
|
||||||
bitmap->flush_all_requested= TRUE;
|
bitmap->flush_all_requested++;
|
||||||
#ifndef WRONG_BITMAP_FLUSH
|
#ifndef WRONG_BITMAP_FLUSH
|
||||||
while (bitmap->non_flushable > 0)
|
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);
|
pthread_cond_wait(&bitmap->bitmap_cond, &bitmap->bitmap_lock);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
DBUG_ASSERT(bitmap->flush_all_requested == 1);
|
||||||
/*
|
/*
|
||||||
Bitmap is in a flushable state: its contents in memory are reflected by
|
Bitmap is in a flushable state: its contents in memory are reflected by
|
||||||
log records (complete REDO-UNDO groups) and all bitmap pages are
|
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)
|
PCFLUSH_PINNED_AND_ERROR)
|
||||||
res= TRUE;
|
res= TRUE;
|
||||||
bitmap->changed_not_flushed= FALSE;
|
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
|
Some well-behaved threads may be waiting for flush_all_requested to
|
||||||
become false, wake them up.
|
become false, wake them up.
|
||||||
@ -404,6 +406,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
|
@brief Unpin all pinned bitmap pages
|
||||||
|
|
||||||
@ -633,11 +699,12 @@ static void _ma_print_bitmap_changes(MARIA_FILE_BITMAP *bitmap)
|
|||||||
{
|
{
|
||||||
uchar *pos, *end, *org_pos;
|
uchar *pos, *end, *org_pos;
|
||||||
ulong page;
|
ulong page;
|
||||||
|
DBUG_ENTER("_ma_print_bitmap_changes");
|
||||||
|
|
||||||
end= bitmap->map + bitmap->used_size;
|
end= bitmap->map + bitmap->used_size;
|
||||||
DBUG_LOCK_FILE;
|
DBUG_LOCK_FILE;
|
||||||
fprintf(DBUG_FILE,"\nBitmap page changes at page %lu\n",
|
fprintf(DBUG_FILE,"\nBitmap page changes at page: %lu bitmap: 0x%lx\n",
|
||||||
(ulong) bitmap->page);
|
(ulong) bitmap->page, (long) bitmap->map);
|
||||||
|
|
||||||
page= (ulong) bitmap->page+1;
|
page= (ulong) bitmap->page+1;
|
||||||
for (pos= bitmap->map, org_pos= bitmap->map + bitmap->block_size ;
|
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);
|
fputc('\n', DBUG_FILE);
|
||||||
DBUG_UNLOCK_FILE;
|
DBUG_UNLOCK_FILE;
|
||||||
memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size);
|
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;
|
uint page, offset, tmp;
|
||||||
uchar *data;
|
uchar *data;
|
||||||
|
DBUG_ENTER("fill_block");
|
||||||
|
|
||||||
/* For each 6 bytes we have 6*8/3= 16 patterns */
|
/* For each 6 bytes we have 6*8/3= 16 patterns */
|
||||||
page= ((uint) (best_data - bitmap->map)) / 6 * 16 + best_pos;
|
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);
|
int2store(data, tmp);
|
||||||
bitmap->changed= 1;
|
bitmap->changed= 1;
|
||||||
DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap););
|
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;
|
MARIA_BITMAP_BLOCK *block;
|
||||||
uchar *data;
|
uchar *data;
|
||||||
uint offset, tmp, offset_page;
|
uint offset, tmp, offset_page;
|
||||||
|
DBUG_ENTER("use_head");
|
||||||
|
|
||||||
DBUG_ASSERT(page % bitmap->pages_covered);
|
DBUG_ASSERT(page % bitmap->pages_covered);
|
||||||
|
|
||||||
block= dynamic_element(&info->bitmap_blocks, block_position,
|
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);
|
int2store(data, tmp);
|
||||||
bitmap->changed= 1;
|
bitmap->changed= 1;
|
||||||
DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap););
|
DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap););
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3592,7 +3592,7 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info)
|
|||||||
MARIA_SHARE *share= info->s;
|
MARIA_SHARE *share= info->s;
|
||||||
DBUG_ENTER("_ma_write_abort_block_record");
|
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,
|
if (delete_head_or_tail(info,
|
||||||
ma_recordpos_to_page(info->cur_row.lastpos),
|
ma_recordpos_to_page(info->cur_row.lastpos),
|
||||||
ma_recordpos_to_dir_entry(info->cur_row.lastpos), 1,
|
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))
|
&lsn, (void*) 0))
|
||||||
res= 1;
|
res= 1;
|
||||||
}
|
}
|
||||||
_ma_bitmap_flushable(info, -1);
|
_ma_bitmap_unlock(share);
|
||||||
_ma_unpin_all_pages_and_finalize_row(info, lsn);
|
_ma_unpin_all_pages_and_finalize_row(info, lsn);
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
void _ma_bitmap_delete_all(MARIA_SHARE *share);
|
||||||
int _ma_bitmap_create_first(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_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,
|
void _ma_bitmap_set_pagecache_callbacks(PAGECACHE_FILE *file,
|
||||||
MARIA_SHARE *share);
|
MARIA_SHARE *share);
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
|
@ -246,7 +246,7 @@ typedef struct st_maria_file_bitmap
|
|||||||
uint used_size; /* Size of bitmap head that is not 0 */
|
uint used_size; /* Size of bitmap head that is not 0 */
|
||||||
my_bool changed; /* 1 if page needs to be written */
|
my_bool changed; /* 1 if page needs to be written */
|
||||||
my_bool changed_not_flushed; /* 1 if some bitmap is not flushed */
|
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 */
|
uint non_flushable; /**< 0 if bitmap and log are in sync */
|
||||||
PAGECACHE_FILE file; /* datafile where bitmap is stored */
|
PAGECACHE_FILE file; /* datafile where bitmap is stored */
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
|
|||||||
a crash on windows if the table is renamed and
|
a crash on windows if the table is renamed and
|
||||||
later on referenced by the merge table.
|
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;
|
error = HA_ERR_NO_SUCH_TABLE;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user