1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

initialize plugins in the specific order by plugin type

but do MyISAM first - to read mysql.plugin table
This commit is contained in:
Sergei Golubchik
2015-01-05 13:27:44 +01:00
parent 9cdf494197
commit c8997c39b4
2 changed files with 89 additions and 77 deletions

View File

@ -25,6 +25,7 @@
#include "sql_parse.h" // check_table_access
#include "sql_base.h" // close_mysql_tables
#include "key.h" // key_copy
#include "sql_table.h"
#include "sql_show.h" // remove_status_vars, add_status_vars
#include "strfunc.h" // find_set
#include "sql_acl.h" // *_ACL
@ -110,6 +111,25 @@ plugin_type_init plugin_type_deinitialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
finalize_audit_plugin, 0, 0, 0
};
/*
Defines in which order plugin types have to be initialized.
Essentially, we want to initialize MYSQL_KEY_MANAGEMENT_PLUGIN before
MYSQL_STORAGE_ENGINE_PLUGIN, and that before MYSQL_INFORMATION_SCHEMA_PLUGIN
*/
static int plugin_type_initialization_order[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
MYSQL_DAEMON_PLUGIN,
MYSQL_KEY_MANAGEMENT_PLUGIN,
MYSQL_STORAGE_ENGINE_PLUGIN,
MYSQL_INFORMATION_SCHEMA_PLUGIN,
MYSQL_FTPARSER_PLUGIN,
MYSQL_AUTHENTICATION_PLUGIN,
MariaDB_PASSWORD_VALIDATION_PLUGIN,
MYSQL_AUDIT_PLUGIN,
MYSQL_REPLICATION_PLUGIN,
MYSQL_UDF_PLUGIN
};
#ifdef HAVE_DLOPEN
static const char *plugin_interface_version_sym=
"_mysql_plugin_interface_version_";
@ -1197,11 +1217,16 @@ static void plugin_del(struct st_plugin_int *plugin)
/* Free allocated strings before deleting the plugin. */
plugin_vars_free_values(plugin->system_vars);
restore_ptr_backup(plugin->nbackups, plugin->ptr_backup);
my_hash_delete(&plugin_hash[plugin->plugin->type], (uchar*)plugin);
plugin_dl_del(plugin->plugin_dl);
plugin->state= PLUGIN_IS_FREED;
plugin_array_version++;
free_root(&plugin->mem_root, MYF(0));
if (plugin->plugin_dl)
{
my_hash_delete(&plugin_hash[plugin->plugin->type], (uchar*)plugin);
plugin_dl_del(plugin->plugin_dl);
plugin->state= PLUGIN_IS_FREED;
plugin_array_version++;
free_root(&plugin->mem_root, MYF(0));
}
else
plugin->state= PLUGIN_IS_UNINITIALIZED;
DBUG_VOID_RETURN;
}
@ -1233,24 +1258,9 @@ static void reap_plugins(void)
mysql_mutex_unlock(&LOCK_plugin);
/*
First free all normal plugins, last the key management plugin.
This is becasue the storage engines may need the key management plugin
during deinitialization.
*/
list= reap;
while ((plugin= *(--list)))
{
if (plugin->plugin->type != MYSQL_KEY_MANAGEMENT_PLUGIN)
plugin_deinitialize(plugin, true);
}
list= reap;
while ((plugin= *(--list)))
{
if (plugin->state != PLUGIN_IS_UNINITIALIZED)
plugin_deinitialize(plugin, true);
}
mysql_mutex_lock(&LOCK_plugin);
@ -1496,14 +1506,14 @@ static void init_plugin_psi_keys(void)
*/
int plugin_init(int *argc, char **argv, int flags)
{
uint i,j;
bool is_myisam;
uint i;
struct st_maria_plugin **builtins;
struct st_maria_plugin *plugin;
struct st_plugin_int tmp, *plugin_ptr, **reap;
MEM_ROOT tmp_root;
bool reaped_mandatory_plugin= false;
bool mandatory= true;
LEX_STRING MyISAM= { C_STRING_WITH_LEN("MyISAM") };
DBUG_ENTER("plugin_init");
if (initialized)
@ -1587,46 +1597,28 @@ int plugin_init(int *argc, char **argv, int flags)
tmp.state= PLUGIN_IS_UNINITIALIZED;
if (register_builtin(plugin, &tmp, &plugin_ptr))
goto err_unlock;
is_myisam= !my_strcasecmp(&my_charset_latin1, plugin->name, "MyISAM");
/*
strictly speaking, we should to initialize all plugins,
even for mysqld --help, because important subsystems
may be disabled otherwise, and the help will be incomplete.
For example, if the mysql.plugin table is not MyISAM.
But for now it's an unlikely corner case, and to optimize
mysqld --help for all other users, we will only initialize
MyISAM here.
*/
if (plugin_initialize(&tmp_root, plugin_ptr, argc, argv, !is_myisam &&
(flags & PLUGIN_INIT_SKIP_INITIALIZATION)))
{
if (plugin_ptr->load_option == PLUGIN_FORCE)
goto err_unlock;
plugin_ptr->state= PLUGIN_IS_DISABLED;
}
/*
initialize the global default storage engine so that it may
not be null in any child thread.
*/
if (is_myisam)
{
DBUG_ASSERT(!global_system_variables.table_plugin);
global_system_variables.table_plugin=
intern_plugin_lock(NULL, plugin_int_to_ref(plugin_ptr));
DBUG_ASSERT(plugin_ptr->ref_count == 1);
}
}
}
/* should now be set to MyISAM storage engine */
DBUG_ASSERT(global_system_variables.table_plugin);
/* First, we initialize only MyISAM - that should always succeed */
plugin_ptr= plugin_find_internal(&MyISAM, MYSQL_STORAGE_ENGINE_PLUGIN);
DBUG_ASSERT(plugin_ptr);
DBUG_ASSERT(plugin_ptr->load_option == PLUGIN_FORCE);
if (plugin_initialize(&tmp_root, plugin_ptr, argc, argv, false))
goto err_unlock;
/*
initialize the global default storage engine so that it may
not be null in any child thread.
*/
global_system_variables.table_plugin=
intern_plugin_lock(NULL, plugin_int_to_ref(plugin_ptr));
DBUG_ASSERT(plugin_ptr->ref_count == 1);
mysql_mutex_unlock(&LOCK_plugin);
/* Register all dynamic plugins */
/* Register (not initialize!) all dynamic plugins */
if (!(flags & PLUGIN_INIT_SKIP_DYNAMIC_LOADING))
{
I_List_iterator<i_string> iter(opt_plugin_load_list);
@ -1635,7 +1627,18 @@ int plugin_init(int *argc, char **argv, int flags)
plugin_load_list(&tmp_root, item->ptr);
if (!(flags & PLUGIN_INIT_SKIP_PLUGIN_TABLE))
plugin_load(&tmp_root);
{
char path[FN_REFLEN + 1];
build_table_filename(path, sizeof(path) - 1, "mysql", "plugin", reg_ext, 0);
enum legacy_db_type db_type;
frm_type_enum frm_type= dd_frm_type(NULL, path, &db_type);
/* if mysql.plugin table is MyISAM - load it right away */
if (frm_type == FRMTYPE_TABLE && db_type == DB_TYPE_MYISAM)
{
plugin_load(&tmp_root);
flags|= PLUGIN_INIT_SKIP_PLUGIN_TABLE;
}
}
}
/*
@ -1646,24 +1649,34 @@ int plugin_init(int *argc, char **argv, int flags)
reap= (st_plugin_int **) my_alloca((plugin_array.elements+1) * sizeof(void*));
*(reap++)= NULL;
/* first MYSQL_KEY_MANAGEMENT_PLUGIN, then the rest */
for (j= 0 ; j <= 1; j++)
for(;;)
{
for (i= 0; i < plugin_array.elements; i++)
for (i=0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++)
{
plugin_ptr= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
if (((j == 0 && plugin->type == MYSQL_KEY_MANAGEMENT_PLUGIN) || j > 0) &&
plugin_ptr->plugin_dl &&
plugin_ptr->state == PLUGIN_IS_UNINITIALIZED)
HASH *hash= plugin_hash + plugin_type_initialization_order[i];
for (uint idx= 0; idx < hash->records; idx++)
{
if (plugin_initialize(&tmp_root, plugin_ptr, argc, argv,
(flags & PLUGIN_INIT_SKIP_INITIALIZATION)))
plugin_ptr= (struct st_plugin_int *) my_hash_element(hash, idx);
if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED)
{
plugin_ptr->state= PLUGIN_IS_DYING;
*(reap++)= plugin_ptr;
if (plugin_initialize(&tmp_root, plugin_ptr, argc, argv,
(flags & PLUGIN_INIT_SKIP_INITIALIZATION)))
{
plugin_ptr->state= PLUGIN_IS_DYING;
*(reap++)= plugin_ptr;
}
}
}
}
/* load and init plugins from the plugin table (unless done already) */
if (flags & PLUGIN_INIT_SKIP_PLUGIN_TABLE)
break;
mysql_mutex_unlock(&LOCK_plugin);
plugin_load(&tmp_root);
flags|= PLUGIN_INIT_SKIP_PLUGIN_TABLE;
mysql_mutex_lock(&LOCK_plugin);
}
/*
@ -1738,23 +1751,22 @@ static void plugin_load(MEM_ROOT *tmp_root)
new_thd->db= my_strdup("mysql", MYF(0));
new_thd->db_length= 5;
bzero((char*) &new_thd->net, sizeof(new_thd->net));
tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_READ);
tables.open_strategy= TABLE_LIST:: IF_EMBEDDED(OPEN_IF_EXISTS, OPEN_NORMAL);
tables.init_one_table(STRING_WITH_LEN("mysql"), STRING_WITH_LEN("plugin"),
"plugin", TL_READ);
tables.open_strategy= TABLE_LIST::OPEN_NORMAL;
result= open_and_lock_tables(new_thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT);
table= tables.table;
if (IF_EMBEDDED(!table, false))
goto end;
if (result)
{
DBUG_PRINT("error",("Can't open plugin table"));
if (!opt_help)
sql_print_error("Can't open the mysql.plugin table. Please "
"run mysql_upgrade to create it.");
sql_print_error("Could not open mysql.plugin table. "
"Some plugins may be not loaded");
else
sql_print_warning("Could not open mysql.plugin table. Some options may be missing from the help text");
sql_print_warning("Could not open mysql.plugin table. "
"Some options may be missing from the help text");
goto end;
}