diff options
author | unknown <knielsen@knielsen-hq.org> | 2012-11-20 13:28:53 +0100 |
---|---|---|
committer | unknown <knielsen@knielsen-hq.org> | 2012-11-20 13:28:53 +0100 |
commit | 47c5018f592b61b5e000842bdf5862ff458de488 (patch) | |
tree | 5f20f3e187ca419f218a1bfea363f3cbfd962f7f | |
parent | 9e7d870b360b165ac7960814a2fa5bf6011eab1a (diff) | |
download | mariadb-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.
-rw-r--r-- | sql/log.cc | 19 | ||||
-rw-r--r-- | sql/log.h | 2 |
2 files changed, 11 insertions, 10 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 diff --git a/sql/log.h b/sql/log.h index f42ef514307..9fb233fed86 100644 --- a/sql/log.h +++ b/sql/log.h @@ -81,7 +81,7 @@ class TC_LOG_MMAP: public TC_LOG my_off_t file_length; uint npages, inited; uchar *data; - struct st_page *pages, *syncing, *active, *pool, *pool_last; + struct st_page *pages, *syncing, *active, *pool, **pool_last_ptr; /* note that, e.g. LOCK_active is only used to protect 'active' pointer, to protect the content of the active page |