1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Task ID 499:Add a new settable string variable(init_connect, init_slave)

to mysqld that is executed for all new connections.
(Similar to the client command: mysql_options(... MYSQL_INIT_COMMAND ...).
This commit is contained in:
gluh@gluh.mysql.r18.ru
2003-12-08 09:13:14 +04:00
parent 333bddb33f
commit b46d75f08b
9 changed files with 55 additions and 102 deletions

View File

@ -499,6 +499,8 @@ bool wait_for_tables(THD *thd);
bool table_is_used(TABLE *table, bool wait_for_name_lock); bool table_is_used(TABLE *table, bool wait_for_name_lock);
bool drop_locked_tables(THD *thd,const char *db, const char *table_name); bool drop_locked_tables(THD *thd,const char *db, const char *table_name);
void abort_locked_tables(THD *thd,const char *db, const char *table_name); void abort_locked_tables(THD *thd,const char *db, const char *table_name);
void execute_init_command(THD *thd, sys_var_str *init_command_var,
rw_lock_t *var_mutex);
extern const Field *not_found_field; extern const Field *not_found_field;
Field *find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, Field *find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
TABLE_LIST **where, bool report_error); TABLE_LIST **where, bool report_error);

View File

@ -3655,10 +3655,10 @@ Disable with --skip-bdb (will save memory).",
#endif /* End HAVE_INNOBASE_DB */ #endif /* End HAVE_INNOBASE_DB */
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
0, 0, 0, 0, 0}, 0, 0, 0, 0, 0},
{"init-connect", OPT_INIT_CONNECT, "Command what executes for all new connections", {"init-connect", OPT_INIT_CONNECT, "Command(s) that are executed for each new connection",
(gptr*) &opt_init_connect, (gptr*) &opt_init_connect, 0, GET_STR_ALLOC, REQUIRED_ARG, (gptr*) &opt_init_connect, (gptr*) &opt_init_connect, 0, GET_STR_ALLOC, REQUIRED_ARG,
0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0, 0},
{"init-slave", OPT_INIT_SLAVE, "Command what is executed when replication is starting", {"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed when a slave connects to this master",
(gptr*) &opt_init_slave, (gptr*) &opt_init_slave, 0, GET_STR_ALLOC, REQUIRED_ARG, (gptr*) &opt_init_slave, (gptr*) &opt_init_slave, 0, GET_STR_ALLOC, REQUIRED_ARG,
0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0, 0},
{"init-file", OPT_INIT_FILE, "Read SQL commands from this file at startup.", {"init-file", OPT_INIT_FILE, "Read SQL commands from this file at startup.",

View File

@ -92,7 +92,6 @@ void send_error(THD *thd, uint sql_errno, const char *err)
/* In bootstrap it's ok to print on stderr */ /* In bootstrap it's ok to print on stderr */
fprintf(stderr,"ERROR: %d %s\n",sql_errno,err); fprintf(stderr,"ERROR: %d %s\n",sql_errno,err);
} }
thd->init_connect_error= 1;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -211,7 +210,6 @@ net_printf(THD *thd, uint errcode, ...)
fprintf(stderr,"ERROR: %d %s\n",errcode,text_pos); fprintf(stderr,"ERROR: %d %s\n",errcode,text_pos);
thd->fatal_error(); thd->fatal_error();
} }
thd->init_connect_error= 1;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }

View File

@ -674,14 +674,23 @@ struct show_var_st init_vars[]= {
*/ */
static bool sys_update_init_connect(THD *thd, set_var *var) /*
Update variables 'init_connect, init_slave'.
In case of 'DEFAULT' value
(for example: 'set GLOBAL init_connect=DEFAULT')
'var' parameter is NULL pointer.
*/
bool update_sys_var_str(sys_var_str *var_str, rw_lock_t *var_mutex,
set_var *var)
{ {
char *res= 0, *old_value; char *res= 0, *old_value;
uint new_length; uint new_length= 0;
/* If the string is "", delete old init command */ /* If the string is "", delete old init command */
if ((new_length= var->value->str_value.length())) if (var && (new_length= var->value->str_value.length()))
{ {
if (!(res= my_strdup_with_length(var->value->str_value.c_ptr(), if (!(res= my_strdup_with_length(var->value->str_value.ptr(),
new_length, new_length,
MYF(0)))) MYF(0))))
return 1; return 1;
@ -690,63 +699,37 @@ static bool sys_update_init_connect(THD *thd, set_var *var)
Replace the old value in such a way that the any thread using Replace the old value in such a way that the any thread using
the value will work. the value will work.
*/ */
rw_wrlock(&LOCK_sys_init_connect); rw_wrlock(var_mutex);
old_value= sys_init_connect.value; old_value= var_str->value;
sys_init_connect.value= res; var_str->value= res;
sys_init_connect.value_length= new_length; var_str->value_length= new_length;
rw_unlock(&LOCK_sys_init_connect); rw_unlock(var_mutex);
my_free(old_value, MYF(MY_ALLOW_ZERO_PTR)); my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
return 0; return 0;
} }
static bool sys_update_init_connect(THD *thd, set_var *var)
{
return update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, var);
}
static void sys_default_init_connect(THD* thd, enum_var_type type) static void sys_default_init_connect(THD* thd, enum_var_type type)
{ {
char *old_value; update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, 0);
rw_wrlock(&LOCK_sys_init_connect);
old_value= sys_init_connect.value;
sys_init_connect.value= 0;
sys_init_connect.value_length= 0;
rw_unlock(&LOCK_sys_init_connect);
my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
} }
static bool sys_update_init_slave(THD *thd, set_var *var) static bool sys_update_init_slave(THD *thd, set_var *var)
{ {
char *res= 0, *old_value; return update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, var);
uint new_length;
/* If the string is "", delete old init command */
if ((new_length= var->value->str_value.length()))
{
if (!(res= my_strdup_with_length(var->value->str_value.c_ptr(),
new_length,
MYF(0))))
return 1;
}
/*
Replace the old value in such a way that the any thread using
the value will work.
*/
rw_wrlock(&LOCK_sys_init_slave);
old_value= sys_init_slave.value;
sys_init_slave.value= res;
sys_init_slave.value_length= new_length;
rw_unlock(&LOCK_sys_init_slave);
my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
return 0;
} }
static void sys_default_init_slave(THD* thd, enum_var_type type) static void sys_default_init_slave(THD* thd, enum_var_type type)
{ {
char *old_value; update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, 0);
rw_wrlock(&LOCK_sys_init_slave);
old_value= sys_init_slave.value;
sys_init_slave.value= 0;
sys_init_slave.value_length= 0;
rw_unlock(&LOCK_sys_init_slave);
my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
} }

View File

@ -2448,24 +2448,6 @@ err:
} }
void init_slave_execute(THD *thd, sys_var_str *init_slave_var)
{
Vio* save_vio;
ulong save_client_capabilities;
thd->proc_info= "Execution of init_slave";
thd->query= init_slave_var->value;
thd->query_length= init_slave_var->value_length;
save_client_capabilities= thd->client_capabilities;
thd->client_capabilities|= CLIENT_MULTI_QUERIES;
save_vio= thd->net.vio;
thd->net.vio= 0;
dispatch_command(COM_QUERY, thd, thd->query, thd->query_length+1);
thd->client_capabilities= save_client_capabilities;
thd->net.vio= save_vio;
}
/* Slave SQL Thread entry point */ /* Slave SQL Thread entry point */
extern "C" pthread_handler_decl(handle_slave_sql,arg) extern "C" pthread_handler_decl(handle_slave_sql,arg)
@ -2551,9 +2533,7 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
/* execute init_slave variable */ /* execute init_slave variable */
if (sys_init_slave.value) if (sys_init_slave.value)
{ {
rw_wrlock(&LOCK_sys_init_slave); execute_init_command(thd, &sys_init_slave, &LOCK_sys_init_slave);
init_slave_execute(thd, &sys_init_slave);
rw_unlock(&LOCK_sys_init_slave);
if (thd->query_error) if (thd->query_error)
{ {
sql_print_error("\ sql_print_error("\

View File

@ -121,7 +121,6 @@ THD::THD():user_time(0), is_fatal_error(0),
system_thread=cleanup_done=0; system_thread=cleanup_done=0;
peer_port= 0; // For SHOW PROCESSLIST peer_port= 0; // For SHOW PROCESSLIST
transaction.changed_tables = 0; transaction.changed_tables = 0;
init_connect_error= 0;
#ifdef __WIN__ #ifdef __WIN__
real_id = 0; real_id = 0;
#endif #endif

View File

@ -560,7 +560,6 @@ public:
bool prepare_command; bool prepare_command;
bool tmp_table_used; bool tmp_table_used;
bool init_connect_error;
/* /*
If we do a purge of binary logs, log index info of the threads If we do a purge of binary logs, log index info of the threads
that are currently reading it needs to be adjusted. To do that that are currently reading it needs to be adjusted. To do that

View File

@ -794,19 +794,31 @@ check_connections(THD *thd)
} }
void init_connect_execute(THD *thd, sys_var_str *init_connect_var) void execute_init_command(THD *thd, sys_var_str *init_command_var,
rw_lock_t *var_mutex)
{ {
Vio* save_vio; Vio* save_vio;
ulong save_client_capabilities; ulong save_client_capabilities;
thd->proc_info= "Execution of init_connect"; thd->proc_info= "Execution of init_command";
thd->query= init_connect_var->value; /*
thd->query_length= init_connect_var->value_length; We need to lock init_command_var because
during execution of init_command_var query
values of init_command_var can't be changed
*/
rw_rdlock(var_mutex);
thd->query= init_command_var->value;
thd->query_length= init_command_var->value_length;
save_client_capabilities= thd->client_capabilities; save_client_capabilities= thd->client_capabilities;
thd->client_capabilities|= CLIENT_MULTI_QUERIES; thd->client_capabilities|= CLIENT_MULTI_QUERIES;
/*
We don't need return result of execution to client side.
To forbid this we should set thd->net.vio to 0.
*/
save_vio= thd->net.vio; save_vio= thd->net.vio;
thd->net.vio= 0; thd->net.vio= 0;
dispatch_command(COM_QUERY, thd, thd->query, thd->query_length+1); dispatch_command(COM_QUERY, thd, thd->query, thd->query_length+1);
rw_unlock(var_mutex);
thd->client_capabilities= save_client_capabilities; thd->client_capabilities= save_client_capabilities;
thd->net.vio= save_vio; thd->net.vio= save_vio;
} }
@ -887,29 +899,9 @@ pthread_handler_decl(handle_one_connection,arg)
thd->version= refresh_version; thd->version= refresh_version;
if (sys_init_connect.value && !(thd->master_access & SUPER_ACL)) if (sys_init_connect.value && !(thd->master_access & SUPER_ACL))
{ {
rw_wrlock(&LOCK_sys_init_connect); execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect);
init_connect_execute(thd, &sys_init_connect); if (thd->query_error)
rw_unlock(&LOCK_sys_init_connect); thd->killed= 1;
if (thd->init_connect_error)
{
if (thd->user_connect)
decrease_user_connections(thd->user_connect);
free_root(&thd->mem_root,MYF(0));
if (!thd->killed && thd->variables.log_warnings)
{
sql_print_error(ER(ER_NEW_ABORTING_CONNECTION),
thd->thread_id,(thd->db ? thd->db : "unconnected"),
thd->user ? thd->user : "unauthenticated",
thd->host_or_ip,
"Can't execute init_connect query");
statistic_increment(aborted_threads,&LOCK_status);
}
else if (thd->killed)
{
statistic_increment(aborted_threads,&LOCK_status);
}
goto end_thread;
}
} }
thd->proc_info=0; thd->proc_info=0;

View File

@ -1618,10 +1618,10 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
break; break;
case SHOW_CHAR_PTR: case SHOW_CHAR_PTR:
{ {
if (!(pos= *(char**) value)) if (!(pos= *(char**) value))
pos= ""; pos= "";
end= strend(pos); end= strend(pos);
break; break;
} }
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
/* First group - functions relying on CTX */ /* First group - functions relying on CTX */