List:Commits« Previous MessageNext Message »
From:Sergey Vojtovich Date:March 31 2010 12:04pm
Subject:bzr commit into mysql-5.1-bugteam branch (svoj:3436) Bug#39053
View as plain text  
#At file:///home/svoj/devel/bzr-mysql/mysql-5.1-bugteam-bug39053/ based on revid:sergey.glukhov@stripped

 3436 Sergey Vojtovich	2010-03-31
      BUG#39053 - UNISTALL PLUGIN does not allow the storage engine
                  to cleanup open connections
      
      It was possible to UNINSTALL storage engine plugin when binding
      between THD object and storage engine is still active (e.g. in
      the middle of transaction).
      
      To avoid unclean deactivation (uninstall) of storage engine plugin
      in the middle of transaction, additional storage engine plugin
      locks are acquired by thd_set_ha_data().
      
      If ha_data is not null and storage engine plugin was not locked
      by thd_set_ha_data() in this connection before, storage engine
      plugin gets locked.
      
      If ha_data is null and storage engine plugin was locked by
      thd_set_ha_data() in this connection before, storage engine
      plugin lock gets released.
      
      If handlerton::close_connection() didn't reset ha_data, server does
      it immediately after calling handlerton::close_connection().
      
      Note that this is just a framework fix, storage engines must switch
      to thd_set_ha_data() from thd_ha_data() if they want to see fit.
     @ include/mysql/plugin.h
        As thd_{get|set}_ha_data() have some extra logic now, they
        must be implemented on server side.
     @ include/mysql/plugin.h.pp
        As thd_{get|set}_ha_data() have some extra logic now, they
        must be implemented on server side.
     @ sql/handler.cc
        Make sure ha_data is reset and ha_data_lock is released.
     @ sql/sql_class.cc
        As thd_{get|set}_ha_data() have some extra logic now, they
        must be implemented on server side.
     @ sql/sql_class.h
        Added ha_data_lock.

    modified:
      include/mysql/plugin.h
      include/mysql/plugin.h.pp
      sql/handler.cc
      sql/sql_class.cc
      sql/sql_class.h
=== modified file 'include/mysql/plugin.h'
--- a/include/mysql/plugin.h	2010-03-16 13:15:19 +0000
+++ b/include/mysql/plugin.h	2010-03-31 12:04:11 +0000
@@ -801,30 +801,37 @@ void mysql_query_cache_invalidate4(MYSQL
                                    const char *key, unsigned int key_length,
                                    int using_trx);
 
-#ifdef __cplusplus
-}
-#endif
 
-#ifdef __cplusplus
 /**
   Provide a handler data getter to simplify coding
 */
-inline
-void *
-thd_get_ha_data(const MYSQL_THD thd, const struct handlerton *hton)
-{
-  return *thd_ha_data(thd, hton);
-}
+void *thd_get_ha_data(const MYSQL_THD thd, const struct handlerton *hton);
+
 
 /**
   Provide a handler data setter to simplify coding
+
+  @details
+  Set ha_data pointer (storage engine per-connection information).
+
+  To avoid unclean deactivation (uninstall) of storage engine plugin
+  in the middle of transaction, additional storage engine plugin
+  locks are acquired.
+
+  If ha_data is not null and storage engine plugin was not locked
+  by thd_set_ha_data() in this connection before, storage engine
+  plugin gets locked.
+
+  If ha_data is null and storage engine plugin was locked by
+  thd_set_ha_data() in this connection before, storage engine
+  plugin lock gets released.
+
+  If handlerton::close_connection() didn't reset ha_data, server does
+  it immediately after calling handlerton::close_connection().
 */
-inline
-void
-thd_set_ha_data(const MYSQL_THD thd, const struct handlerton *hton,
-                const void *ha_data)
-{
-  *thd_ha_data(thd, hton)= (void*) ha_data;
+void thd_set_ha_data(const MYSQL_THD thd, const struct handlerton *hton,
+                     const void *ha_data);
+#ifdef __cplusplus
 }
 #endif
 

=== modified file 'include/mysql/plugin.h.pp'
--- a/include/mysql/plugin.h.pp	2008-06-17 12:27:04 +0000
+++ b/include/mysql/plugin.h.pp	2010-03-31 12:04:11 +0000
@@ -137,3 +137,6 @@ void thd_get_xid(const void* thd, MYSQL_
 void mysql_query_cache_invalidate4(void* thd,
                                    const char *key, unsigned int key_length,
                                    int using_trx);
+void *thd_get_ha_data(const void* thd, const struct handlerton *hton);
+void thd_set_ha_data(const void* thd, const struct handlerton *hton,
+                     const void *ha_data);

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2009-12-01 09:19:51 +0000
+++ b/sql/handler.cc	2010-03-31 12:04:11 +0000
@@ -601,9 +601,13 @@ static my_bool closecon_handlerton(THD *
     there's no need to rollback here as all transactions must
     be rolled back already
   */
-  if (hton->state == SHOW_OPTION_YES && hton->close_connection &&
-      thd_get_ha_data(thd, hton))
-    hton->close_connection(hton, thd);
+  if (hton->state == SHOW_OPTION_YES && thd_get_ha_data(thd, hton))
+  {
+    if (hton->close_connection)
+      hton->close_connection(hton, thd);
+    /* make sure ha_data is reset and ha_data_lock is released */
+    thd_set_ha_data(thd, hton, NULL);
+  }
   return FALSE;
 }
 

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2010-03-29 02:32:30 +0000
+++ b/sql/sql_class.cc	2010-03-31 12:04:11 +0000
@@ -284,6 +284,36 @@ void **thd_ha_data(const THD *thd, const
   return (void **) &thd->ha_data[hton->slot].ha_ptr;
 }
 
+
+/**
+  Provide a handler data getter to simplify coding
+*/
+extern "C"
+void *thd_get_ha_data(const THD *thd, const struct handlerton *hton)
+{
+  return *thd_ha_data(thd, hton);
+}
+
+
+/**
+  Provide a handler data setter to simplify coding
+*/
+extern "C"
+void thd_set_ha_data(const THD *thd, const struct handlerton *hton,
+                     const void *ha_data)
+{
+  if (ha_data && !thd->ha_data_lock[hton->slot])
+    ((THD*) thd)->ha_data_lock[hton->slot]=
+      ha_lock_engine(NULL, (handlerton*) hton);
+  else if (!ha_data && thd->ha_data_lock[hton->slot])
+  {
+    plugin_unlock(NULL, thd->ha_data_lock[hton->slot]);
+    ((THD*) thd)->ha_data_lock[hton->slot]= 0;
+  }
+  *thd_ha_data(thd, hton)= (void*) ha_data;
+}
+
+
 extern "C"
 long long thd_test_options(const THD *thd, long long test_options)
 {
@@ -639,6 +669,7 @@ THD::THD()
   warn_id= 0;
   db_charset= global_system_variables.collation_database;
   bzero(ha_data, sizeof(ha_data));
+  bzero(ha_data_lock, sizeof(ha_data_lock));
   mysys_var=0;
   binlog_evt_union.do_union= FALSE;
   enable_slow_log= 0;

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2010-03-29 02:32:30 +0000
+++ b/sql/sql_class.h	2010-03-31 12:04:11 +0000
@@ -1424,6 +1424,7 @@ public:
 
   /* container for handler's private per-connection data */
   Ha_data ha_data[MAX_HA];
+  plugin_ref ha_data_lock[MAX_HA];
 
 #ifndef MYSQL_CLIENT
   int binlog_setup_trx_data();


Attachment: [text/bzr-bundle] bzr/svoj@sun.com-20100331120411-u2kmoqnzf5m451t0.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (svoj:3436) Bug#39053Sergey Vojtovich31 Mar
  • Re: bzr commit into mysql-5.1-bugteam branch (svoj:3436) Bug#39053Ingo Strüwing1 Apr
    • Re: bzr commit into mysql-5.1-bugteam branch (svoj:3436) Bug#39053Sergey Vojtovich1 Apr
      • Re: bzr commit into mysql-5.1-bugteam branch (svoj:3436) Bug#39053Ingo Strüwing3 Apr
        • Re: bzr commit into mysql-5.1-bugteam branch (svoj:3436) Bug#39053Sergey Vojtovich5 Apr
  • Re: bzr commit into mysql-5.1-bugteam branch (svoj:3436) Bug#39053Ingo Strüwing6 Apr
    • Re: bzr commit into mysql-5.1-bugteam branch (svoj:3436) Bug#39053Sergey Vojtovich12 Apr
      • Re: bzr commit into mysql-5.1-bugteam branch (svoj:3436) Bug#39053Ingo Strüwing13 Apr
        • Re: bzr commit into mysql-5.1-bugteam branch (svoj:3436) Bug#39053Sergey Vojtovich13 Apr
  • Re: bzr commit into mysql-5.1-bugteam branch (svoj:3436) Bug#39053Davi Arnaut10 Apr
Re: bzr commit into mysql-5.1-bugteam branch (svoj:3436) Bug#39053Davi Arnaut11 Apr
Re: bzr commit into mysql-5.1-bugteam branch (svoj:3436) Bug#39053Davi Arnaut11 Apr
Re: bzr commit into mysql-5.1-bugteam branch (svoj:3436) Bug#39053Davi Arnaut12 Apr