summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2010-12-04 12:27:51 +0200
committerMichael Widenius <monty@askmonty.org>2010-12-04 12:27:51 +0200
commit7fc608619260d6f74e70b990cdf48fff15e9e115 (patch)
tree1782e25c0e1b1472fccd2446535d0314e818be32 /storage
parent91a72ee314ce6b0ac7adfc6546390435c9ba164f (diff)
parent8938ed57a4c533f3e56c5ac5ef5889c7944f7e22 (diff)
downloadmariadb-git-7fc608619260d6f74e70b990cdf48fff15e9e115.tar.gz
Automatic merge with 5.1-release
Diffstat (limited to 'storage')
-rw-r--r--storage/maria/ma_loghandler.c22
-rw-r--r--storage/maria/ma_pagecache.c54
-rw-r--r--storage/xtradb/sync/sync0rw.c5
3 files changed, 72 insertions, 9 deletions
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index 423cd2f0dd7..a29c42cae68 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -1,4 +1,4 @@
-/* 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,11 +2526,10 @@ 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->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 */
@@ -7580,6 +7579,7 @@ my_bool translog_flush(TRANSLOG_ADDRESS lsn)
DBUG_ASSERT(translog_status == TRANSLOG_OK ||
translog_status == TRANSLOG_READONLY);
LINT_INIT(sent_to_disk);
+ LINT_INIT(last_buffer_no);
pthread_mutex_lock(&log_descriptor.log_flush_lock);
DBUG_PRINT("info", ("Everything is flushed up to (%lu,0x%lx)",
@@ -7648,18 +7648,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)
{
diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c
index 1bb82ba92cd..83785e6a1af 100644
--- a/storage/maria/ma_pagecache.c
+++ b/storage/maria/ma_pagecache.c
@@ -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))
{
@@ -1044,6 +1046,7 @@ static inline void dec_counter_for_resize_op(PAGECACHE *pagecache)
("thread %ld", last_thread->next->id));
pagecache_pthread_cond_signal(&last_thread->next->suspend);
}
+ DBUG_ASSERT((longlong) pagecache->cnt_for_resize_op >= 0);
#else
pagecache->cnt_for_resize_op--;
#endif
@@ -1085,6 +1088,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.
SYNOPSIS
@@ -1106,6 +1140,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 +2288,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 +3496,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 +3566,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;
}
@@ -3579,6 +3627,8 @@ my_bool pagecache_delete_by_link(PAGECACHE *pagecache,
*/
DBUG_ASSERT((block->status &
(PCBLOCK_IN_SWITCH | PCBLOCK_REASSIGNED)) == 0);
+
+ inc_counter_for_resize_op(pagecache);
/*
make_lock_and_pin() can't fail here, because we are keeping pin on the
block and it can't be evicted (which is cause of lock fail and retry)
@@ -3695,6 +3745,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 +3758,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. */
diff --git a/storage/xtradb/sync/sync0rw.c b/storage/xtradb/sync/sync0rw.c
index 5dc6b28d4bf..f1018522fdf 100644
--- a/storage/xtradb/sync/sync0rw.c
+++ b/storage/xtradb/sync/sync0rw.c
@@ -247,10 +247,11 @@ rw_lock_create_func(
lock->mutex.cmutex_name = cmutex_name;
ut_d(lock->mutex.mutex_type = 1);
-#else /* INNODB_RW_LOCKS_USE_ATOMICS */
+#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
+#if defined(INNODB_RW_LOCKS_USE_ATOMICS) || !defined(UNIV_DEBUG)
(void) cfile_name;
(void) cline;
-#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
+#endif
lock->lock_word = X_LOCK_DECR;
lock->waiters = 0;