[Commits] Rev 3902: MDEV-7123: MariaDB 10.0.14 Galera node shutdown with signal 11 in lp:~maria-captains/maria/maria-10.0-galera

Nirbhay Choubey nirbhay at mariadb.com
Sun Nov 23 18:41:23 EET 2014


At lp:~maria-captains/maria/maria-10.0-galera

------------------------------------------------------------
revno: 3902
revision-id: nirbhay at mariadb.com-20141123163533-9ov1yirj26cur301
parent: nirbhay at mariadb.com-20141119183337-n5spskf54beqbhif
committer: Nirbhay Choubey <nirbhay at mariadb.com>
branch nick: maria-10.0-galera
timestamp: Sun 2014-11-23 11:35:33 -0500
message:
  MDEV-7123: MariaDB 10.0.14 Galera node shutdown with signal 11 
  
  wsrep-patch uses same connection name for constructing Master_info
  objects. As a result all existing wsrep Master_info objects refer
  to same rpl_filter object. This could lead to race when multiple
  threads try to destruct/delete Master_info object, as they would all
  try to delete the same relay_log object.
  Fixed by adding a mutex to protect the critical section.
-------------- next part --------------
=== modified file 'sql/keycaches.cc'
--- a/sql/keycaches.cc	2013-09-14 01:09:36 +0000
+++ b/sql/keycaches.cc	2014-11-23 16:35:33 +0000
@@ -72,6 +72,7 @@
   I_List_iterator<NAMED_ILINK> it(*this);
   NAMED_ILINK *element;
   DBUG_ENTER("NAMED_ILIST::delete_element");
+  lock();
   while ((element= it++))
   {
     if (element->cmp(name, length))
@@ -81,6 +82,7 @@
       DBUG_RETURN(0);
     }
   }
+  unlock();
   DBUG_RETURN(1);
 }
 
@@ -88,11 +90,13 @@
 {
   NAMED_ILINK *element;
   DBUG_ENTER("NAMED_ILIST::delete_elements");
+  lock();
   while ((element= get()))
   {
     (*free_element)(element->name, element->data);
     delete element;
   }
+  unlock();
   DBUG_VOID_RETURN;
 }
 
@@ -223,6 +227,7 @@
 void free_rpl_filter(const char *name, Rpl_filter *filter)
 {
   delete filter;
+  filter= 0;
 }
 
 void free_all_rpl_filters()

=== modified file 'sql/keycaches.h'
--- a/sql/keycaches.h	2013-09-14 01:09:36 +0000
+++ b/sql/keycaches.h	2014-11-23 16:35:33 +0000
@@ -20,6 +20,8 @@
 #include <keycache.h>
 #include <rpl_filter.h>
 
+extern PSI_mutex_key key_LOCK_named_ilist;
+
 extern "C"
 {
   typedef int (*process_key_cache_t) (const char *, KEY_CACHE *, void *);
@@ -29,9 +31,29 @@
 
 class NAMED_ILIST: public I_List<NAMED_ILINK>
 {
+  private:
+    mysql_mutex_t mtx;
+
+    void lock() {
+      mysql_mutex_lock(&mtx);
+    };
+
+    void unlock() {
+      mysql_mutex_unlock(&mtx);
+    }
+
   public:
-  void delete_elements(void (*free_element)(const char*, uchar*));
-  bool delete_element(const char *name, uint length, void (*free_element)(const char*, uchar*));
+    NAMED_ILIST() {
+      mysql_mutex_init(key_LOCK_named_ilist, &mtx, MY_MUTEX_INIT_FAST);
+    }
+
+    ~NAMED_ILIST() {
+      mysql_mutex_destroy(&mtx);
+    }
+
+    void delete_elements(void (*free_element)(const char*, uchar*));
+    bool delete_element(const char *name, uint length,
+                        void (*free_element)(const char*, uchar*));
 };
 
 /* For key cache */

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2014-11-17 16:56:03 +0000
+++ b/sql/mysqld.cc	2014-11-23 16:35:33 +0000
@@ -908,7 +908,7 @@
   key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data,
   key_LOCK_error_messages, key_LOG_INFO_lock,
   key_LOCK_thread_count, key_LOCK_thread_cache,
-  key_PARTITION_LOCK_auto_inc;
+  key_PARTITION_LOCK_auto_inc, key_LOCK_named_ilist;
 #ifdef WITH_WSREP
 PSI_mutex_key key_LOCK_wsrep_rollback, key_LOCK_wsrep_thd, 
   key_LOCK_wsrep_replaying, key_LOCK_wsrep_ready, key_LOCK_wsrep_sst, 

=== modified file 'sql/wsrep_thd.cc'
--- a/sql/wsrep_thd.cc	2014-09-22 16:15:44 +0000
+++ b/sql/wsrep_thd.cc	2014-11-23 16:35:33 +0000
@@ -99,10 +99,26 @@
     rli->relay_log.description_event_for_exec=
       new Format_description_log_event(4);
   }
-  static LEX_STRING dbname= { C_STRING_WITH_LEN("mysql") };
-
-  rli->mi = new Master_info( &dbname,  false);
-
+
+  static LEX_STRING wsrep_conn_name= { C_STRING_WITH_LEN("wsrep") };
+
+  /*
+    Master_info's constructor initializes rpl_filter by either an already
+    constructed Rpl_filter object from global 'rpl_filters' list if the
+    specified connection name is same, or it constructs a new Rpl_filter
+    object and adds it to rpl_filters. This object is later destructed by
+    Mater_info's destructor by looking it up based on connection name in
+    rpl_filters list.
+
+    Since all Master_info objects created here would share same connection
+    name ("wsrep"), destruction of any of the existing Master_info objects
+    (in wsrep_return_from_bf_mode()) would free rpl_filter referenced by
+    any/all existing Master_info objects.
+
+    In order to avoid this, we explicitly allocate an Rpl_filter object per
+    Master_info here to initialize Master_info->rpl_filter.
+  */
+  rli->mi = new Master_info(&wsrep_conn_name,  false);
   rli->mi->rpl_filter = new Rpl_filter;
   copy_filter_setting(rli->mi->rpl_filter, get_or_create_rpl_filter("", 0));
 



More information about the commits mailing list