summaryrefslogtreecommitdiff
path: root/sql/log.cc
diff options
context:
space:
mode:
authorunknown <knielsen@knielsen-hq.org>2012-11-20 13:28:53 +0100
committerunknown <knielsen@knielsen-hq.org>2012-11-20 13:28:53 +0100
commit47c5018f592b61b5e000842bdf5862ff458de488 (patch)
tree5f20f3e187ca419f218a1bfea363f3cbfd962f7f /sql/log.cc
parent9e7d870b360b165ac7960814a2fa5bf6011eab1a (diff)
downloadmariadb-git-47c5018f592b61b5e000842bdf5862ff458de488.tar.gz
MDEV-3861: assertions in TC_LOG_MMAP.
Fix some problems in the TC_LOG_MMAP commit processing, which could lead to assertions in some cases. Problems are mostly reproducible in MariaDB 10.0 with asynchroneous commit checkpoints, but most of the problems were present in earlier versions also.
Diffstat (limited to 'sql/log.cc')
-rw-r--r--sql/log.cc19
1 files changed, 10 insertions, 9 deletions
diff --git a/sql/log.cc b/sql/log.cc
index eb248c63b19..e44f8ff3067 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -5550,8 +5550,9 @@ int TC_LOG_MMAP::open(const char *opt_name)
syncing= 0;
active=pages;
+ DBUG_ASSERT(npages >= 2);
pool=pages+1;
- pool_last=pages+npages-1;
+ pool_last_ptr= &((pages+npages-1)->next);
return 0;
@@ -5582,8 +5583,8 @@ void TC_LOG_MMAP::get_active_from_pool()
do
{
best_p= p= &pool;
- if ((*p)->waiters == 0) // can the first page be used ?
- break; // yes - take it.
+ if ((*p)->waiters == 0 && (*p)->free > 0) // can the first page be used ?
+ break; // yes - take it.
best_free=0; // no - trying second strategy
for (p=&(*p)->next; *p; p=&(*p)->next)
@@ -5600,10 +5601,10 @@ void TC_LOG_MMAP::get_active_from_pool()
safe_mutex_assert_owner(&LOCK_active);
active=*best_p;
- if ((*best_p)->next) // unlink the page from the pool
- *best_p=(*best_p)->next;
- else
- pool_last=*best_p;
+ /* Unlink the page from the pool. */
+ if (!(*best_p)->next)
+ pool_last_ptr= best_p;
+ *best_p=(*best_p)->next;
pthread_mutex_unlock(&LOCK_pool);
pthread_mutex_lock(&active->lock);
@@ -5764,8 +5765,8 @@ int TC_LOG_MMAP::sync()
/* page is synced. let's move it to the pool */
pthread_mutex_lock(&LOCK_pool);
- pool_last->next=syncing;
- pool_last=syncing;
+ (*pool_last_ptr)=syncing;
+ pool_last_ptr=&(syncing->next);
syncing->next=0;
syncing->state= err ? ERROR : POOL;
pthread_cond_signal(&COND_pool); // in case somebody's waiting