List:Commits« Previous MessageNext Message »
From:Kristofer Pettersson Date:November 21 2008 3:36pm
Subject:bzr commit into mysql-5.1 branch (kristofer.pettersson:2675) Bug#19027
View as plain text  
#At file:///home/thek/Development/cpp/mysqlbzr/mysql-5.1-bug19027/

 2675 Kristofer Pettersson	2008-11-21
      Bug#19027 MySQL 5.0 starts even with Fatal InnoDB errors
      
      If the InnoDB SE fails to initialize during server start up, there is
      no automatic mechanism for client applications to detect that the meta data
      has changed.
                  
      This patch provide a solution to this issue so that if the InnoDB SE plugins
      fail the server won't go online unless the plugin loading mechanism was 
      "--loose-plugin-load" in which case the server will start with best effort.
modified:
  sql/handler.cc
  sql/mysqld.cc
  sql/sql_plugin.cc
  sql/sql_plugin.h

per-file messages:
  sql/handler.cc
    * Added documentation
  sql/mysqld.cc
    * Added new server option
  sql/sql_plugin.cc
    * Added support for loose plugin loading
    * Added hard coded restriction for built-in InnoDB SE which prevents the
    server from going online if the SE fails to initialize.
  sql/sql_plugin.h
    * Introduced new property in the st_plugin_int structure to reflect if
    a plugin must succeed in loading and initializing before the server goes online.
    * Introduced the server option "loose-plugin-load" which allows plugin
    to be loaded and initialized on a best effort without explicitly causing
    the server to shutdown.
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2008-10-08 13:52:57 +0000
+++ b/sql/handler.cc	2008-11-21 14:45:30 +0000
@@ -419,6 +419,16 @@ int ha_finalize_handlerton(st_plugin_int
 }
 
 
+/**
+  Apply handler initialization methods on a plugin.
+  
+  @param plugin A pointer to a plugin
+  
+  @return Status code.
+    @retval 0 Success
+    @retval 1 Failure
+*/
+
 int ha_initialize_handlerton(st_plugin_int *plugin)
 {
   handlerton *hton;

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2008-10-13 10:22:36 +0000
+++ b/sql/mysqld.cc	2008-11-21 14:45:30 +0000
@@ -5385,8 +5385,8 @@ error:
 
 enum options_mysqld
 {
-  OPT_ISAM_LOG=256,            OPT_SKIP_NEW, 
-  OPT_SKIP_GRANT,              OPT_SKIP_LOCK, 
+  OPT_ISAM_LOG=256,            OPT_SKIP_NEW,
+  OPT_SKIP_GRANT,              OPT_SKIP_LOCK,
   OPT_ENABLE_LOCK,             OPT_USE_LOCKING,
   OPT_SOCKET,                  OPT_UPDATE_LOG,
   OPT_BIN_LOG,                 OPT_SKIP_RESOLVE,
@@ -5415,11 +5415,11 @@ enum options_mysqld
 #ifndef DBUG_OFF
   OPT_BINLOG_SHOW_XID,
 #endif
-  OPT_BINLOG_ROWS_EVENT_MAX_SIZE, 
+  OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
   OPT_WANT_CORE,               OPT_CONCURRENT_INSERT,
   OPT_MEMLOCK,                 OPT_MYISAM_RECOVER,
   OPT_REPLICATE_REWRITE_DB,    OPT_SERVER_ID,
-  OPT_SKIP_SLAVE_START,        OPT_SAFE_SHOW_DB, 
+  OPT_SKIP_SLAVE_START,        OPT_SAFE_SHOW_DB,
   OPT_SAFEMALLOC_MEM_LIMIT,    OPT_REPLICATE_DO_TABLE,
   OPT_REPLICATE_IGNORE_TABLE,  OPT_REPLICATE_WILD_DO_TABLE,
   OPT_REPLICATE_WILD_IGNORE_TABLE, OPT_REPLICATE_SAME_SERVER_ID,
@@ -5529,6 +5529,7 @@ enum options_mysqld
   OPT_LOG_SLOW_ADMIN_STATEMENTS,
   OPT_TABLE_LOCK_WAIT_TIMEOUT,
   OPT_PLUGIN_LOAD,
+  OPT_LOOSE_PLUGIN_LOAD,
   OPT_PLUGIN_DIR,
   OPT_LOG_OUTPUT,
   OPT_PORT_OPEN_TIMEOUT,
@@ -5547,7 +5548,6 @@ enum options_mysqld
   OPT_SLOW_QUERY_LOG_FILE
 };
 
-
 #define LONG_TIMEOUT ((ulong) 3600L*24L*365L)
 
 struct my_option my_long_options[] =
@@ -6671,6 +6671,11 @@ The minimum value for this variable is 4
    "identified by name and path to library seperated by an equals.",
    (uchar**) &opt_plugin_load, (uchar**) &opt_plugin_load, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"loose_plugin_load", OPT_LOOSE_PLUGIN_LOAD,
+   "Optional colon separated list of plugins to load, where each plugin is "
+   "identified by name and path to library seperated by an equals.",
+   (uchar**) &opt_loose_plugin_load, (uchar**) &opt_loose_plugin_load, 0,
+   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
    "The size of the buffer that is allocated when preloading indexes",
    (uchar**) &global_system_variables.preload_buff_size,

=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc	2008-10-06 20:36:15 +0000
+++ b/sql/sql_plugin.cc	2008-11-21 14:45:30 +0000
@@ -30,6 +30,7 @@
 extern struct st_mysql_plugin *mysqld_builtins[];
 
 char *opt_plugin_load= NULL;
+char *opt_loose_plugin_load= NULL;
 char *opt_plugin_dir_ptr;
 char opt_plugin_dir[FN_REFLEN];
 /*
@@ -188,7 +189,7 @@ public:
 
 
 /* prototypes */
-static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv);
+static bool plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv);
 static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
                              const char *list);
 static int test_plugin_options(MEM_ROOT *, struct st_plugin_int *,
@@ -614,7 +615,7 @@ static plugin_ref intern_plugin_lock(LEX
 
   safe_mutex_assert_owner(&LOCK_plugin);
 
-  if (pi->state & (PLUGIN_IS_READY | PLUGIN_IS_UNINITIALIZED))
+  if (pi && pi->state & (PLUGIN_IS_READY | PLUGIN_IS_UNINITIALIZED))
   {
     plugin_ref plugin;
 #ifdef DBUG_OFF
@@ -753,6 +754,15 @@ static bool plugin_add(MEM_ROOT *tmp_roo
       tmp.state= PLUGIN_IS_UNINITIALIZED;
       if (!test_plugin_options(tmp_root, &tmp, argc, argv, true))
       {
+        /*
+          Was this plugin installed using the '--loose-' prefix?
+          If not, it should not be allowed to fail while loading or
+          initializing.
+        */
+        if (opt_loose_plugin_load)
+          tmp.is_server_requirement= FALSE;
+        else
+          tmp.is_server_requirement= TRUE;
         if ((tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
         {
           plugin_array_version++;
@@ -990,7 +1000,6 @@ void plugin_unlock_list(THD *thd, plugin
   DBUG_VOID_RETURN;
 }
 
-
 static int plugin_initialize(struct st_plugin_int *plugin)
 {
   DBUG_ENTER("plugin_initialize");
@@ -1094,6 +1103,7 @@ int plugin_init(int *argc, char **argv, 
 {
   uint i;
   bool def_enabled, is_myisam;
+  bool mandatory_plugin_failed_to_load= FALSE;
   struct st_mysql_plugin **builtins;
   struct st_mysql_plugin *plugin;
   struct st_plugin_int tmp, *plugin_ptr, **reap;
@@ -1184,12 +1194,32 @@ int plugin_init(int *argc, char **argv, 
   /* Register all dynamic plugins */
   if (!(flags & PLUGIN_INIT_SKIP_DYNAMIC_LOADING))
   {
+    if (opt_loose_plugin_load)
+    {
+      plugin_load_list(&tmp_root, argc, argv, opt_loose_plugin_load);
+      /*
+        The opt_loose_plugin_load is also used as a flag to help 
+        plugin_add set the is_server_requirement flag. Hence we need to
+        set it to zero now, so that other execution paths won't be affected
+        by it.
+      */
+      opt_loose_plugin_load= NULL;
+    }
+    
     if (opt_plugin_load)
-      plugin_load_list(&tmp_root, argc, argv, opt_plugin_load);
-    if (!(flags & PLUGIN_INIT_SKIP_PLUGIN_TABLE))
-      plugin_load(&tmp_root, argc, argv);
+    {
+      if (plugin_load_list(&tmp_root, argc, argv, opt_plugin_load))
+        goto err;
+    }
   }
 
+  if (!(flags & PLUGIN_INIT_SKIP_PLUGIN_TABLE))
+  {
+    if (plugin_load(&tmp_root, argc, argv))
+      goto err;
+  }
+
+
   if (flags & PLUGIN_INIT_SKIP_INITIALIZATION)
     goto end;
 
@@ -1220,6 +1250,14 @@ int plugin_init(int *argc, char **argv, 
   while ((plugin_ptr= *(--reap)))
   {
     pthread_mutex_unlock(&LOCK_plugin);
+    /*
+      InnoDB must succeed in loading before the server is allowed to start.
+      This is a temporary solution until a dependency checker is implemented.
+    */
+    if (!my_strcasecmp(&my_charset_latin1, plugin_ptr->name.str, "InnoDB")
&&
+        plugin_ptr->is_server_requirement)
+      mandatory_plugin_failed_to_load= TRUE;
+
     plugin_deinitialize(plugin_ptr, true);
     pthread_mutex_lock(&LOCK_plugin);
     plugin_del(plugin_ptr);
@@ -1227,6 +1265,8 @@ int plugin_init(int *argc, char **argv, 
 
   pthread_mutex_unlock(&LOCK_plugin);
   my_afree(reap);
+  if (mandatory_plugin_failed_to_load)
+    goto err;
 
 end:
   free_root(&tmp_root, MYF(0));
@@ -1309,10 +1349,16 @@ end:
 #endif /* NOT_USED_YET */
 
 
-/*
-  called only by plugin_init()
+/**
+  Helper function called only by plugin_init()
+  @param tmp_root Memory allocator
+  @param argc A pointer to the number of argument strings
+  @param argv A list of pointers to argument strings
+
+  @retval FALSE Plugins were successfully loaded
+  @retval TRUE Plugins failed to load
 */
-static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
+static bool plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
 {
   TABLE_LIST tables;
   TABLE *table;
@@ -1328,7 +1374,7 @@ static void plugin_load(MEM_ROOT *tmp_ro
   {
     sql_print_error("Can't allocate memory for plugin structures");
     delete new_thd;
-    DBUG_VOID_RETURN;
+    DBUG_RETURN(FALSE);
   }
   new_thd->thread_stack= (char*) &tables;
   new_thd->store_globals();
@@ -1358,6 +1404,7 @@ static void plugin_load(MEM_ROOT *tmp_ro
     DBUG_PRINT("error",("Can't open plugin table"));
     sql_print_error("Can't open the mysql.plugin table. Please "
                     "run mysql_upgrade to create it.");
+    error= 1;
     goto end;
   }
   table= tables.table;
@@ -1395,13 +1442,23 @@ end:
   delete new_thd;
   /* Remember that we don't have a THD */
   my_pthread_setspecific_ptr(THR_THD, 0);
-  DBUG_VOID_RETURN;
+  DBUG_RETURN(error>0);
 }
 
 
-/*
-  called only by plugin_init()
+/**
+  Helper function called only by plugin_init().
+
+  @param tmp_root Memory allocator
+  @param argc Pointer to the number of arguments
+  @param argv List of pointers to argument
+  @param list ??
+
+  @return Success status
+   @retval TRUE Failure: At least one item in the list failed
+   @retval FALSE Success: All items were successfully loaded
 */
+
 static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
                              const char *list)
 {
@@ -1411,6 +1468,7 @@ static bool plugin_load_list(MEM_ROOT *t
   struct st_mysql_plugin *plugin;
   char *p= buffer;
   DBUG_ENTER("plugin_load_list");
+
   while (list)
   {
     if (p == buffer + sizeof(buffer) - 1)
@@ -1444,7 +1502,6 @@ static bool plugin_load_list(MEM_ROOT *t
           {
             name.str= (char *) plugin->name;
             name.length= strlen(name.str);
-
             free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
             if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
               goto error;
@@ -3129,19 +3186,23 @@ static my_option *construct_help_options
 }
 
 
-/*
-  SYNOPSIS
-    test_plugin_options()
-    tmp_root                    temporary scratch space
-    plugin                      internal plugin structure
-    argc                        user supplied arguments
-    argv                        user supplied arguments
-    default_enabled             default plugin enable status
-  RETURNS:
-    0 SUCCESS - plugin should be enabled/loaded
-  NOTE:
+/**
+   Evaluate if a plugin should be enabled or not and also map command line
+   options against server variables.
+ 
+   @param tmp_root  Memory allocator handle
+   @param tmp Internal plugin handle
+   @param argc The number of user supplied arguments
+   @param argv An array of user supplied arguments
+   @param default_enabled Default plugin enable status
+  
+ NOTE:
     Requires that a write-lock is held on LOCK_system_variables_hash
+ @return Status value
+   @retval 0 Yes; plugin should be enabled
+   @retval -1 No; plugin should not be enabled
 */
+
 static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
                                int *argc, char **argv, my_bool default_enabled)
 {
@@ -3306,4 +3367,3 @@ void my_print_help_inc_plugins(my_option
   delete_dynamic(&all_options);
   free_root(&mem_root, MYF(0));
 }
-

=== modified file 'sql/sql_plugin.h'
--- a/sql/sql_plugin.h	2007-06-12 15:41:56 +0000
+++ b/sql/sql_plugin.h	2008-11-21 14:45:30 +0000
@@ -66,8 +66,7 @@ struct st_plugin_dl
   uint ref_count;            /* number of plugins loaded from the library */
 };
 
-/* A handle of a plugin */
-
+/* An internal handle of a plugin */
 struct st_plugin_int
 {
   LEX_STRING name;
@@ -78,6 +77,7 @@ struct st_plugin_int
   void *data;                   /* plugin type specific, e.g. handlerton */
   MEM_ROOT mem_root;            /* memory for dynamic plugin structures */
   sys_var *system_vars;         /* server variables for this plugin */
+  bool is_server_requirement;   /* must succeed to initialize or abort server */
 };
 
 
@@ -106,6 +106,7 @@ typedef struct st_plugin_int **plugin_re
 typedef int (*plugin_type_init)(struct st_plugin_int *);
 
 extern char *opt_plugin_load;
+extern char *opt_loose_plugin_load;
 extern char *opt_plugin_dir_ptr;
 extern char opt_plugin_dir[FN_REFLEN];
 extern const LEX_STRING plugin_type_names[];

Thread
bzr commit into mysql-5.1 branch (kristofer.pettersson:2675) Bug#19027Kristofer Pettersson21 Nov
  • Re: bzr commit into mysql-5.1 branch (kristofer.pettersson:2675)Bug#19027Sergei Golubchik2 Apr 2009
    • Re: bzr commit into mysql-5.1 branch (kristofer.pettersson:2675)Bug#19027Sergei Golubchik2 Apr 2009