Commit 15e0e266 authored by marko's avatar marko

branches/zip: Allow a dynamically loaded InnoDB storage engine plugin

to replace a built-in instance of InnoDB in mysqld.  This is work in
progress, with several limitations:

* Other plugins defined in the builtin InnoDB are not disabled.
  However, InnoDB in MySQL 5.1 only defines the storage engine plugin,
  no INFORMATION_SCHEMA plugins.

* The global C symbols in ha_innodb.so except innodb_hton_ptr and
  builtin_innobase_plugin will have to be redefined, e.g., by objcopy.

* The storage engine cannot be called "InnoDB" to avoid a conflict with
  the builtin name.  Here we call it InnoDBzip.

innobase_hton_name[]: Rename to "InnoDBzip" when building a dynamic plugin.

innodb_plugin_init(): New function for the dynamic plugin, to copy
and redirect configuration parameters from the builtin InnoDB.

innodb_dynamic: New configuration parameter.  This has to be added
to the builtin InnoDB in MySQL 5.1.  Also, innodb_hton_ptr must be made
global there.

innobase_init(): Interpret the parameter innodb_dynamic.

Makefile.am: Redefine class ha_innobase to ha_innodb by a preprocessor
define.  Apparently, C++ classes cannot be easily renamed by objcopy.
parent 6c9bfe78
...@@ -178,8 +178,12 @@ libinnobase_a_CFLAGS = $(AM_CFLAGS) ...@@ -178,8 +178,12 @@ libinnobase_a_CFLAGS = $(AM_CFLAGS)
EXTRA_LTLIBRARIES = ha_innodb.la EXTRA_LTLIBRARIES = ha_innodb.la
pkglib_LTLIBRARIES = @plugin_innobase_shared_target@ pkglib_LTLIBRARIES = @plugin_innobase_shared_target@
# To avoid symbol clashes between the InnoDB plugin and a built-in InnoDB,
# we must rename class ha_innobase to something else. Also global symbols
# will have to be redefined, but that can be done by objcopy --redefine-syms.
ha_innodb_la_LDFLAGS = -module -rpath $(MYSQLLIBdir) ha_innodb_la_LDFLAGS = -module -rpath $(MYSQLLIBdir)
ha_innodb_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_innodb_la_CXXFLAGS= $(AM_CFLAGS) \
-DMYSQL_DYNAMIC_PLUGIN -Dha_innobase=ha_innodb
ha_innodb_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_innodb_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
ha_innodb_la_SOURCES = $(libinnobase_a_SOURCES) ha_innodb_la_SOURCES = $(libinnobase_a_SOURCES)
......
...@@ -53,11 +53,22 @@ static pthread_cond_t commit_cond; ...@@ -53,11 +53,22 @@ static pthread_cond_t commit_cond;
static pthread_mutex_t commit_cond_m; static pthread_mutex_t commit_cond_m;
static bool innodb_inited = 0; static bool innodb_inited = 0;
/* #ifdef MYSQL_DYNAMIC_PLUGIN
This needs to exist until the query cache callback is removed /* These must be weak global variables in the dynamic plugin. */
or learns to pass hton. struct handlerton* innodb_hton_ptr;
*/ int builtin_innobase_plugin;
static handlerton *innodb_hton_ptr; /********************************************************************
Copy InnoDB system variables from the static InnoDB to the dynamic
plugin. */
static
bool
innodb_plugin_init(void);
/*====================*/
/* out: TRUE if the dynamic InnoDB plugin should start */
#else /* MYSQL_DYNAMIC_PLUGIN */
/* This must be a global variable in the statically linked InnoDB. */
struct handlerton* innodb_hton_ptr = NULL;
#endif /* MYSQL_DYNAMIC_PLUGIN */
/* Include necessary InnoDB headers */ /* Include necessary InnoDB headers */
extern "C" { extern "C" {
...@@ -131,6 +142,8 @@ static my_bool innobase_use_adaptive_hash_indexes = TRUE; ...@@ -131,6 +142,8 @@ static my_bool innobase_use_adaptive_hash_indexes = TRUE;
static char* internal_innobase_data_file_path = NULL; static char* internal_innobase_data_file_path = NULL;
static my_bool innobase_dynamic;
/* The following counter is used to convey information to InnoDB /* The following counter is used to convey information to InnoDB
about server activity: in selects it is not sensible to call about server activity: in selects it is not sensible to call
srv_active_wake_master_thread after each fetch or search, we only do srv_active_wake_master_thread after each fetch or search, we only do
...@@ -169,8 +182,11 @@ innobase_alter_table_flags( ...@@ -169,8 +182,11 @@ innobase_alter_table_flags(
/*=======================*/ /*=======================*/
uint flags); uint flags);
#ifdef MYSQL_DYNAMIC_PLUGIN
static const char innobase_hton_name[]= "InnoDBzip";
#else
static const char innobase_hton_name[]= "InnoDB"; static const char innobase_hton_name[]= "InnoDB";
#endif
static MYSQL_THDVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG, static MYSQL_THDVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG,
"Enable InnoDB support for the XA two-phase commit", "Enable InnoDB support for the XA two-phase commit",
...@@ -1422,6 +1438,27 @@ innobase_init( ...@@ -1422,6 +1438,27 @@ innobase_init(
DBUG_ENTER("innobase_init"); DBUG_ENTER("innobase_init");
handlerton *innobase_hton= (handlerton *)p; handlerton *innobase_hton= (handlerton *)p;
#ifdef MYSQL_DYNAMIC_PLUGIN
if (!innodb_plugin_init()) {
sql_print_error("InnoDB plugin init failed."
" Did you set innodb_dynamic=1?");
DBUG_RETURN(-1);
}
if (innodb_hton_ptr) {
/* Patch the statically linked handlerton and variables */
innobase_hton = innodb_hton_ptr;
}
#else /* MYSQL_DYNAMIC_PLUGIN */
if (innobase_dynamic) {
innobase_hton->state = SHOW_OPTION_NO;
/* Disable the built-in InnoDB */
sql_print_error("Builtin InnoDB disabled by innodb_dynamic");
DBUG_RETURN(-1);
}
#endif /* MYSQL_DYNAMIC_PLUGIN */
innodb_hton_ptr = innobase_hton; innodb_hton_ptr = innobase_hton;
innobase_hton->state = SHOW_OPTION_YES; innobase_hton->state = SHOW_OPTION_YES;
...@@ -1672,6 +1709,12 @@ innobase_init( ...@@ -1672,6 +1709,12 @@ innobase_init(
pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST); pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
pthread_cond_init(&commit_cond, NULL); pthread_cond_init(&commit_cond, NULL);
innodb_inited= 1; innodb_inited= 1;
#ifdef MYSQL_DYNAMIC_PLUGIN
if (innobase_hton != p) {
innobase_hton = reinterpret_cast<handlerton*>(p);
*innobase_hton = *innodb_hton_ptr;
}
#endif /* MYSQL_DYNAMIC_PLUGIN */
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
error: error:
...@@ -8007,6 +8050,11 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite, ...@@ -8007,6 +8050,11 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
"Disable with --skip-innodb-doublewrite.", "Disable with --skip-innodb-doublewrite.",
NULL, NULL, TRUE); NULL, NULL, TRUE);
static MYSQL_SYSVAR_BOOL(dynamic, innobase_dynamic,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
"Enable a dynamic InnoDB plugin (and disable a built-in InnoDB).",
NULL, NULL, FALSE);
static MYSQL_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown, static MYSQL_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
PLUGIN_VAR_OPCMDARG, PLUGIN_VAR_OPCMDARG,
"Speeds up the shutdown process of the InnoDB storage engine. Possible " "Speeds up the shutdown process of the InnoDB storage engine. Possible "
...@@ -8196,6 +8244,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { ...@@ -8196,6 +8244,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(data_file_path), MYSQL_SYSVAR(data_file_path),
MYSQL_SYSVAR(data_home_dir), MYSQL_SYSVAR(data_home_dir),
MYSQL_SYSVAR(doublewrite), MYSQL_SYSVAR(doublewrite),
MYSQL_SYSVAR(dynamic),
MYSQL_SYSVAR(fast_shutdown), MYSQL_SYSVAR(fast_shutdown),
MYSQL_SYSVAR(file_io_threads), MYSQL_SYSVAR(file_io_threads),
MYSQL_SYSVAR(file_per_table), MYSQL_SYSVAR(file_per_table),
...@@ -8230,6 +8279,87 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { ...@@ -8230,6 +8279,87 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
NULL NULL
}; };
#ifdef MYSQL_DYNAMIC_PLUGIN
struct st_mysql_sys_var
{
MYSQL_PLUGIN_VAR_HEADER;
void* value;
};
/********************************************************************
Copy InnoDB system variables from the static InnoDB to the dynamic
plugin. */
static
bool
innodb_plugin_init(void)
/*====================*/
/* out: TRUE if the dynamic InnoDB plugin should start */
{
# if !MYSQL_STORAGE_ENGINE_PLUGIN
# error "MYSQL_STORAGE_ENGINE_PLUGIN must be nonzero."
# endif
switch (builtin_innobase_plugin) {
case 0:
return(TRUE);
case MYSQL_STORAGE_ENGINE_PLUGIN:
break;
default:
return(FALSE);
}
/* Copy the system variables. */
struct st_mysql_plugin* builtin
= (struct st_mysql_plugin*) &builtin_innobase_plugin;
struct st_mysql_sys_var** v = builtin->system_vars;
struct st_mysql_sys_var** w = innobase_system_variables;
for (; *v; v++, w++) {
if (UNIV_UNLIKELY(!*w)) {
fprintf(stderr, "InnoDB: unknown parameter %s,0x%x\n",
(*v)->name, (*v)->flags);
return(FALSE);
}
if (UNIV_UNLIKELY((*v)->flags != (*w)->flags
|| strcmp((*v)->name, (*w)->name))) {
fprintf(stderr,
"InnoDB: parameter mismatch:"
" %s,%s,0x%x,0x%x\n",
(*v)->name, (*w)->name,
(*v)->flags, (*w)->flags);
return(FALSE);
}
if ((*v)->flags & PLUGIN_VAR_THDLOCAL) {
continue;
}
switch ((*v)->flags
& ~(PLUGIN_VAR_MASK | PLUGIN_VAR_UNSIGNED)) {
# define COPY_VAR(label, type) \
case label: \
*(type*)(*w)->value = *(type*)(*v)->value; \
break;
COPY_VAR(PLUGIN_VAR_BOOL, char);
COPY_VAR(PLUGIN_VAR_INT, int);
COPY_VAR(PLUGIN_VAR_LONG, long);
COPY_VAR(PLUGIN_VAR_LONGLONG, long long);
COPY_VAR(PLUGIN_VAR_STR, char*);
default:
fprintf(stderr, "InnoDB: unknown flags 0x%x for %s\n",
(*v)->flags, (*v)->name);
}
/* Make the static InnoDB variable point to the dynamic one */
(*v)->value = (*w)->value;
}
return(innobase_dynamic);
}
#endif /* MYSQL_DYNAMIC_PLUGIN */
mysql_declare_plugin(innobase) mysql_declare_plugin(innobase)
{ {
MYSQL_STORAGE_ENGINE_PLUGIN, MYSQL_STORAGE_ENGINE_PLUGIN,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment