Commit d0ad135b authored by Michael Widenius's avatar Michael Widenius

Fixed compiler warnings.

Fixed timing test failures.
Fixed a failure in the Aria engines page cache and log handler (found with maria.maria-big test)
- This could cause a core dump when deleting big blobs.
- Added test to end_pagecache() to verify that page cache was correctly used.
  - inc_counter_for_resize_op and dec_counter_for_resize_op are called same number of times.
  - All page cache blocks was properly deallocated (empty)


mysql-test/suite/innodb/t/innodb_bug38231.test:
  Fixed timing issue (code comment says it all)
mysql-test/suite/innodb_plugin/t/innodb_bug38231.test:
  Fixed timing issue (code comment says it all)
sql/debug_sync.cc:
  Fixed compiler warning
storage/maria/ma_loghandler.c:
  Fixed bug found by maria.maria-big test:
  - Fixed race condition between update thread logging a very big blog and checkpoint thread.
storage/maria/ma_pagecache.c:
  Added assert to ensure mutex was properly locked.
  Added test to end_pagecache() to verify that page cache was correctly used.
  - inc_counter_for_resize_op and dec_counter_for_resize_op are called same number of times.
  - All page cache blocks was properly deallocated (empty)
  In pagecache_delete_internal(), properly reset counters and pins if functions aborts.
  Added missing inc_counter_for_resize_op() to pagecache_wait_lock().
  Added missing dec_counter_for_resize_op() to pagecache_delete()
parent d08e5cfa
......@@ -76,6 +76,11 @@ UNLOCK TABLES;
UNLOCK TABLES;
-- connection con3
#
# We may get a timeout error here if the tables are locked in a different
# order than expected. This is ok as the purpose of this patch is to ensure
# we don't get a crash in the previous unlock tables.
-- error 0, 1205
-- reap
UNLOCK TABLES;
......
......@@ -72,8 +72,12 @@ UNLOCK TABLES;
# clean up
-- connection con2
-- reap
#
# We may get a timeout error here if the tables are locked in a different
# order than expected. This is ok as the purpose of this patch is to ensure
# we don't get a crash in the previous unlock tables.
-- error 0, 1205
-- reap
UNLOCK TABLES;
-- connection con3
......
......@@ -1719,6 +1719,7 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
if (action->execute)
{
const char *old_proc_info;
LINT_INIT(old_proc_info);
action->execute--;
......
/* Copyright (C) 2007 MySQL AB & Sanja Belkin
/* Copyright (C) 2007 MySQL AB & Sanja Belkin. 2010 Monty Program Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -2526,10 +2526,9 @@ static my_bool translog_buffer_flush(struct st_translog_buffer *buffer)
{
/* some other flush in progress */
translog_wait_for_closing(buffer);
}
if (buffer->file != file || buffer->offset != offset || buffer->ver != ver)
DBUG_RETURN(0); /* some the thread flushed the buffer already */
}
if (buffer->overlay && translog_prev_buffer_flush_wait(buffer))
DBUG_RETURN(0); /* some the thread flushed the buffer already */
......@@ -7648,18 +7647,28 @@ my_bool translog_flush(TRANSLOG_ADDRESS lsn)
struct st_translog_buffer *buffer= log_descriptor.bc.buffer;
lsn= log_descriptor.bc.buffer->last_lsn; /* fix lsn if it was horizon */
DBUG_PRINT("info", ("LSN to flush fixed to last lsn: (%lu,0x%lx)",
LSN_IN_PARTS(log_descriptor.bc.buffer->last_lsn)));
LSN_IN_PARTS(lsn)));
last_buffer_no= log_descriptor.bc.buffer_no;
log_descriptor.is_everything_flushed= 1;
translog_force_current_buffer_to_finish();
translog_buffer_unlock(buffer);
}
else
else if (log_descriptor.bc.buffer->prev_last_lsn != LSN_IMPOSSIBLE)
{
/* fix lsn if it was horizon */
lsn= log_descriptor.bc.buffer->prev_last_lsn;
DBUG_PRINT("info", ("LSN to flush fixed to prev last lsn: (%lu,0x%lx)",
LSN_IN_PARTS(lsn)));
last_buffer_no= ((log_descriptor.bc.buffer_no + TRANSLOG_BUFFERS_NO -1) %
TRANSLOG_BUFFERS_NO);
translog_unlock();
}
else if (log_descriptor.bc.buffer->last_lsn == LSN_IMPOSSIBLE)
{
DBUG_PRINT("info", ("There is no LSNs yet generated => do nothing"));
translog_unlock();
goto out;
}
sent_to_disk= translog_get_sent_to_disk();
if (cmp_translog_addr(lsn, sent_to_disk) > 0)
{
......
......@@ -1025,6 +1025,7 @@ finish:
*/
static inline void inc_counter_for_resize_op(PAGECACHE *pagecache)
{
safe_mutex_assert_owner(&pagecache->cache_lock);
pagecache->cnt_for_resize_op++;
}
......@@ -1037,6 +1038,7 @@ static inline void dec_counter_for_resize_op(PAGECACHE *pagecache)
{
#ifdef THREAD
struct st_my_thread_var *last_thread;
safe_mutex_assert_owner(&pagecache->cache_lock);
if (!--pagecache->cnt_for_resize_op &&
(last_thread= pagecache->resize_queue.last_thread))
{
......@@ -1084,6 +1086,37 @@ void change_pagecache_param(PAGECACHE *pagecache, uint division_limit,
}
/*
Check that pagecache was used and cleaned up properly.
*/
#ifndef DBUG_OFF
void check_pagecache_is_cleaned_up(PAGECACHE *pagecache)
{
DBUG_ENTER("check_pagecache_is_cleaned_up");
/*
Ensure we called inc_counter_for_resize_op and dec_counter_for_resize_op
the same number of times. (If not, a resize() could never happen.
*/
DBUG_ASSERT(pagecache->cnt_for_resize_op == 0);
if (pagecache->disk_blocks > 0)
{
if (pagecache->block_mem)
{
uint i;
for (i=0 ; i < pagecache->blocks_used ; i++)
{
DBUG_ASSERT(pagecache->block_root[i].status == 0);
DBUG_ASSERT(pagecache->block_root[i].type == PAGECACHE_EMPTY_PAGE);
}
}
}
DBUG_VOID_RETURN;
}
#endif
/*
Removes page cache from memory. Does NOT flush pages to disk.
......@@ -1106,6 +1139,10 @@ void end_pagecache(PAGECACHE *pagecache, my_bool cleanup)
if (pagecache->disk_blocks > 0)
{
#ifndef DBUG_OFF
check_pagecache_is_cleaned_up(pagecache);
#endif
if (pagecache->block_mem)
{
my_large_free(pagecache->block_mem, MYF(0));
......@@ -2250,6 +2287,7 @@ static my_bool pagecache_wait_lock(PAGECACHE *pagecache,
&pagecache->cache_lock);
}
while(thread->next);
inc_counter_for_resize_op(pagecache);
#else
DBUG_ASSERT(0);
#endif
......@@ -3457,7 +3495,7 @@ static my_bool pagecache_delete_internal(PAGECACHE *pagecache,
{
/*
this call is just 'hint' for the cache to free the page so we will
not interferes with flushing process but gust return success
not interferes with flushing process but must return success
*/
goto out;
}
......@@ -3527,8 +3565,17 @@ static my_bool pagecache_delete_internal(PAGECACHE *pagecache,
page_link->requests--;
/* See NOTE for pagecache_unlock about registering requests. */
free_block(pagecache, block);
dec_counter_for_resize_op(pagecache);
return 0;
out:
/* Cache is locked, so we can relese page before freeing it */
if (make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, FALSE))
DBUG_ASSERT(0);
page_link->requests--;
unreg_request(pagecache, block, 1);
dec_counter_for_resize_op(pagecache);
return error;
}
......@@ -3695,6 +3742,7 @@ restart:
if (!page_link)
{
DBUG_PRINT("info", ("There is no such page in the cache"));
dec_counter_for_resize_op(pagecache);
pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
DBUG_RETURN(0);
}
......@@ -3707,6 +3755,7 @@ restart:
"reassigned" : "in switch")));
PCBLOCK_INFO(block);
page_link->requests--;
dec_counter_for_resize_op(pagecache);
goto end;
}
/* See NOTE for pagecache_unlock about registering requests. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment