#At file:///home/thek/Development/cpp/mysqlbzr/51-bug19027/ based on
revid:holyfoot@stripped
2877 Kristofer Pettersson 2009-04-29
Bug#19027 MySQL 5.0 starts even with Fatal InnoDB errors
It is not possible to prevent the server from starting if a mandatory
built-in plugin fails to start. This can in some cases lead to data
corruption when the old table name space suddenly is used by a different
storage engine.
A boolean command line option in the form of --foobar is automatically
created for every existing plugin "foobar". By changing this command line
option from a boolean to a tristate { OFF, ON, FORCE } it is possible to
specify the plugin loading policy for each plugin.
The behavior is specified as follows:
OFF = Disable the plugin and start the server
ON = Enable the plugin and start the server even if an error occurrs
during plugin initialization.
FORCE = Enable the plugin but don't start the server if an error occurrs
during plugin initialization.
@ mysql-test/lib/mtr_cases.pm
* Changed --<pluginname> from a boolean to a tristate.
@ mysys/my_getopt.c
* Changed --<pluginname> from boolean to tristate. Optional arguments
must still work for tristates. It is praxis that disable means value 0
and enable is value 1. Since plugin name is the only tristate with
optional arguments this principle will still hold.
@ sql/mysqld.cc
* Changed --<pluginname> option from a boolean type to a tristate.
@ sql/sql_plugin.cc
* Changed --<pluginname> option from a boolean type to a tristate.
@ sql/sql_plugin.h
* Introduced new member to st_plugin_int structure.
modified:
mysql-test/lib/mtr_cases.pm
mysys/my_getopt.c
sql/mysqld.cc
sql/sql_plugin.cc
sql/sql_plugin.h
=== modified file 'mysql-test/lib/mtr_cases.pm'
--- a/mysql-test/lib/mtr_cases.pm 2009-01-21 10:17:16 +0000
+++ b/mysql-test/lib/mtr_cases.pm 2009-04-29 12:08:45 +0000
@@ -887,7 +887,7 @@ sub collect_one_test_case {
if ( $tinfo->{'innodb_test'} )
{
# This is a test that need innodb
- if ( $::mysqld_variables{'innodb'} ne "TRUE" )
+ if ( $::mysqld_variables{'innodb'} eq "OFF" )
{
# innodb is not supported, skip it
$tinfo->{'skip'}= 1;
=== modified file 'mysys/my_getopt.c'
--- a/mysys/my_getopt.c 2009-03-17 17:24:35 +0000
+++ b/mysys/my_getopt.c 2009-04-29 12:08:45 +0000
@@ -410,7 +410,8 @@ invalid value '%s'",
argument= optend;
}
else if (optp->arg_type == OPT_ARG &&
- (optp->var_type & GET_TYPE_MASK) == GET_BOOL)
+ (((optp->var_type & GET_TYPE_MASK) == GET_BOOL) ||
+ (optp->var_type & GET_TYPE_MASK) == GET_ENUM))
{
if (optend == disabled_my_option)
*((my_bool*) value)= (my_bool) 0;
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2009-04-24 11:28:46 +0000
+++ b/sql/mysqld.cc 2009-04-29 12:08:45 +0000
@@ -300,6 +300,16 @@ TYPELIB sql_mode_typelib= { array_elemen
sql_mode_names,
(unsigned int *)sql_mode_names_len };
+/**
+ @note The order of the enumeration is critical.
+ @see construct_options
+*/
+static const char *global_plugin_typelib_names[]=
+ { "OFF", "ON", "FORCE", NULL };
+static const unsigned int global_plugin_typelib_len[]= {2,3,5};
+TYPELIB global_plugin_typelib= { 3, "", global_plugin_typelib_names,
+ (unsigned int *)global_plugin_typelib_len };
+
static const char *optimizer_switch_names[]=
{
"index_merge","index_merge_union","index_merge_sort_union",
=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc 2009-03-16 10:37:13 +0000
+++ b/sql/sql_plugin.cc 2009-04-29 12:08:45 +0000
@@ -28,6 +28,7 @@
#endif
extern struct st_mysql_plugin *mysqld_builtins[];
+extern TYPELIB global_plugin_typelib;
char *opt_plugin_load= NULL;
char *opt_plugin_dir_ptr;
@@ -1099,6 +1100,7 @@ int plugin_init(int *argc, char **argv,
struct st_mysql_plugin *plugin;
struct st_plugin_int tmp, *plugin_ptr, **reap;
MEM_ROOT tmp_root;
+ bool reaped_mandatory_plugin= FALSE;
DBUG_ENTER("plugin_init");
if (initialized)
@@ -1227,6 +1229,8 @@ int plugin_init(int *argc, char **argv,
while ((plugin_ptr= *(--reap)))
{
pthread_mutex_unlock(&LOCK_plugin);
+ if (plugin_ptr->is_mandatory)
+ reaped_mandatory_plugin= TRUE;
plugin_deinitialize(plugin_ptr, true);
pthread_mutex_lock(&LOCK_plugin);
plugin_del(plugin_ptr);
@@ -1234,6 +1238,8 @@ int plugin_init(int *argc, char **argv,
pthread_mutex_unlock(&LOCK_plugin);
my_afree(reap);
+ if (reaped_mandatory_plugin)
+ goto err;
end:
free_root(&tmp_root, MYF(0));
@@ -2934,14 +2940,25 @@ static int construct_options(MEM_ROOT *m
*((my_bool *)(name -1))= **enabled;
*enabled= (my_bool *)(name - 1);
-
options[1].name= (options[0].name= name) + namelen + 1;
options[0].id= options[1].id= 256; /* must be >255. dup id ok */
- options[0].var_type= options[1].var_type= GET_BOOL;
- options[0].arg_type= options[1].arg_type= NO_ARG;
- options[0].def_value= options[1].def_value= **enabled;
- options[0].value= options[0].u_max_value=
- options[1].value= options[1].u_max_value= (uchar**) (name - 1);
+ options[0].var_type= options[1].var_type= GET_ENUM;
+ options[0].arg_type= options[1].arg_type= OPT_ARG;
+ /*
+ Set the default value: 0 = OFF, 1 = ON
+ */
+ options[0].def_value= options[1].def_value= (int)**enabled;
+ options[0].typelib= options[1].typelib= &global_plugin_typelib;
+ /*
+ Allocate temporary space for the value of the tristate.
+ This option will have a limited lifetime and is not used beyond
+ server initialization.
+ */
+ options[0].value= options[1].value= (uchar **)alloc_root(mem_root,
+ sizeof(my_option **));
+ *((uint*) options[0].value)= *((uint*) options[1].value)=
+ (uint) options[0].def_value;
+
options+= 2;
/*
@@ -3162,6 +3179,7 @@ static int test_plugin_options(MEM_ROOT
int *argc, char **argv, my_bool default_enabled)
{
struct sys_var_chain chain= { NULL, NULL };
+ int plugin_load_policy= 0;
my_bool enabled_saved= default_enabled, can_disable;
my_bool *enabled= &default_enabled;
MEM_ROOT *mem_root= alloc_root_inited(&tmp->mem_root) ?
@@ -3208,6 +3226,13 @@ static int test_plugin_options(MEM_ROOT
tmp->name.str);
goto err;
}
+ /*
+ Set plugin loading policy from option value. First element in the option
+ list is always the <plugin name> option value.
+ */
+ plugin_load_policy= (uint)*opts[0].value;
+ if (plugin_load_policy == 0)
+ *enabled= 0;
}
if (!*enabled && !can_disable)
@@ -3216,6 +3241,8 @@ static int test_plugin_options(MEM_ROOT
*enabled= TRUE;
}
+ tmp->is_mandatory= (plugin_load_policy == 2 ? TRUE:FALSE);
+
error= 1;
if (*enabled)
=== modified file 'sql/sql_plugin.h'
--- a/sql/sql_plugin.h 2008-12-17 15:45:34 +0000
+++ b/sql/sql_plugin.h 2009-04-29 12:08:45 +0000
@@ -79,6 +79,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_mandatory; /* If true then plugin must not fail to load */
};
Attachment: [text/bzr-bundle] bzr/kristofer.pettersson@sun.com-20090429120845-twbt2t6zy2oi74bn.bundle