[Commits] Rev 3171: MDEV-3861: assertions in TC_LOG_MMAP. in http://bazaar.launchpad.net/~maria-captains/maria/5.1

knielsen at knielsen-hq.org knielsen at knielsen-hq.org
Tue Nov 20 14:28:53 EET 2012


At http://bazaar.launchpad.net/~maria-captains/maria/5.1

------------------------------------------------------------
revno: 3171
revision-id: knielsen at knielsen-hq.org-20121120122853-z8ohgttcq24d18r5
parent: sergii at pisem.net-20121119101840-bpwp9g0yjecrgu8h
committer: knielsen at knielsen-hq.org
branch nick: mariadb-5.1
timestamp: Tue 2012-11-20 13:28:53 +0100
message:
  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.
=== modified file 'sql/log.cc'
--- a/sql/log.cc	2012-11-17 18:04:13 +0000
+++ b/sql/log.cc	2012-11-20 12:28:53 +0000
@@ -5550,8 +5550,9 @@ int TC_LOG_MMAP::open(const char *opt_na
 
   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

=== modified file 'sql/log.h'
--- a/sql/log.h	2012-08-22 09:40:39 +0000
+++ b/sql/log.h	2012-11-20 12:28:53 +0000
@@ -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



More information about the commits mailing list