Execute bootstrap in main thread

Bootstrap in a separate thread was introduced in 746f0b3b7 to workaround
OS/2 small stack size. OS/2 support was discontinued in 2006 and modern
operating systems have default stack size a few times larger than
default thread_stack and it is tunable.

Aim is to reduce usage of LOCK_thread_count and COND_thread_count.
Part of MDEV-15135.
This commit is contained in:
Sergey Vojtovich 2019-01-20 12:16:46 +04:00
parent 7ad742b265
commit c88fd54d17
7 changed files with 23 additions and 126 deletions

View File

@ -400,20 +400,6 @@ uint volatile global_disable_checkpoint;
#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
ulong slow_start_timeout;
#endif
/*
True if the bootstrap thread is running. Protected by LOCK_start_thread.
Used in bootstrap() function to determine if the bootstrap thread
has completed. Note, that we can't use 'thread_count' instead,
since in 5.1, in presence of the Event Scheduler, there may be
event threads running in parallel, so it's impossible to know
what value of 'thread_count' is a sign of completion of the
bootstrap thread.
At the same time, we can't start the event scheduler after
bootstrap either, since we want to be able to process event-related
SQL commands in the init file and in --bootstrap mode.
*/
bool volatile in_bootstrap= FALSE;
/**
@brief 'grant_option' is used to indicate if privileges needs
to be checked, in which case the lock, LOCK_grant, is used
@ -663,7 +649,6 @@ Lt_creator lt_creator;
Ge_creator ge_creator;
Le_creator le_creator;
MYSQL_FILE *bootstrap_file;
int bootstrap_error;
I_List<THD> threads;
@ -736,7 +721,6 @@ mysql_mutex_t LOCK_thread_count;
other threads.
It also protects these variables:
in_bootstrap
select_thread_in_use
slave_init_thread_running
check_temp_dir() call
@ -1542,7 +1526,6 @@ void handle_connections_sockets();
#endif
pthread_handler_t kill_server_thread(void *arg);
static void bootstrap(MYSQL_FILE *file);
static bool read_init_file(char *file_name);
pthread_handler_t handle_slave(void *arg);
static void clean_up(bool print_message);
@ -6320,54 +6303,6 @@ int mysqld_main(int argc, char **argv)
#endif
/**
Execute all commands from a file. Used by the mysql_install_db script to
create MySQL privilege tables without having to start a full MySQL server
and by read_init_file() if mysqld was started with the option --init-file.
*/
static void bootstrap(MYSQL_FILE *file)
{
DBUG_ENTER("bootstrap");
THD *thd= new THD(next_thread_id());
#ifdef WITH_WSREP
thd->variables.wsrep_on= 0;
#endif
thd->bootstrap=1;
my_net_init(&thd->net,(st_vio*) 0, thd, MYF(0));
thd->max_client_packet_length= thd->net.max_packet;
thd->security_ctx->master_access= ~(ulong)0;
in_bootstrap= TRUE;
bootstrap_file=file;
#ifndef EMBEDDED_LIBRARY // TODO: Enable this
int error;
if ((error= mysql_thread_create(key_thread_bootstrap,
&thd->real_id, &connection_attrib,
handle_bootstrap,
(void*) thd)))
{
sql_print_warning("Can't create thread to handle bootstrap (errno= %d)",
error);
bootstrap_error=-1;
delete thd;
DBUG_VOID_RETURN;
}
/* Wait for thread to die */
mysql_mutex_lock(&LOCK_thread_count);
while (in_bootstrap)
mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
mysql_mutex_unlock(&LOCK_thread_count);
#else
thd->mysql= 0;
do_handle_bootstrap(thd);
#endif
DBUG_VOID_RETURN;
}
static bool read_init_file(char *file_name)
{
MYSQL_FILE *file;

View File

@ -128,7 +128,6 @@ extern bool opt_ignore_builtin_innodb;
extern my_bool opt_character_set_client_handshake;
extern my_bool debug_assert_on_not_freed_memory;
extern bool volatile abort_loop;
extern bool volatile in_bootstrap;
extern uint connection_count;
extern my_bool opt_safe_user_create;
extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap;
@ -297,7 +296,6 @@ extern int mysqld_server_started, mysqld_server_initialized;
extern "C" MYSQL_PLUGIN_IMPORT int orig_argc;
extern "C" MYSQL_PLUGIN_IMPORT char **orig_argv;
extern pthread_attr_t connection_attrib;
extern MYSQL_FILE *bootstrap_file;
extern my_bool old_mode;
extern LEX_STRING opt_init_connect, opt_init_slave;
extern int bootstrap_error;

View File

@ -3318,7 +3318,7 @@ static int check_alter_user(THD *thd, const char *host, const char *user)
if (IF_WSREP((!WSREP(thd) || !thd->wsrep_applier), 1) &&
!thd->slave_thread && !thd->security_ctx->priv_user[0] &&
!in_bootstrap)
!thd->bootstrap)
{
my_message(ER_PASSWORD_ANONYMOUS_USER,
ER_THD(thd, ER_PASSWORD_ANONYMOUS_USER),

View File

@ -882,7 +882,7 @@ mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db, bool if_exists, bool silen
lock_db_routines(thd, dbnorm))
goto exit;
if (!in_bootstrap && !rm_mysql_schema)
if (!thd->bootstrap && !rm_mysql_schema)
{
for (table= tables; table; table= table->next_local)
{

View File

@ -979,15 +979,28 @@ static char *fgets_fn(char *buffer, size_t size, fgets_input_t input, int *error
}
static void handle_bootstrap_impl(THD *thd)
void bootstrap(MYSQL_FILE *file)
{
MYSQL_FILE *file= bootstrap_file;
DBUG_ENTER("handle_bootstrap_impl");
DBUG_ENTER("handle_bootstrap");
THD *thd= new THD(next_thread_id());
#ifdef WITH_WSREP
thd->variables.wsrep_on= 0;
#endif
thd->bootstrap=1;
my_net_init(&thd->net,(st_vio*) 0, thd, MYF(0));
thd->max_client_packet_length= thd->net.max_packet;
thd->security_ctx->master_access= ~(ulong)0;
#ifndef EMBEDDED_LIBRARY
pthread_detach_this_thread();
mysql_thread_set_psi_id(thd->thread_id);
#else
thd->mysql= 0;
#endif
/* The following must be called before DBUG_ENTER */
thd->thread_stack= (char*) &thd;
#endif /* EMBEDDED_LIBRARY */
thd->store_globals();
thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
thd->security_ctx->priv_user[0]= thd->security_ctx->priv_host[0]=
@ -1095,56 +1108,8 @@ static void handle_bootstrap_impl(THD *thd)
free_root(&thd->transaction.mem_root,MYF(MY_KEEP_PREALLOC));
thd->lex->restore_set_statement_var();
}
DBUG_VOID_RETURN;
}
/**
Execute commands from bootstrap_file.
Used when creating the initial grant tables.
*/
pthread_handler_t handle_bootstrap(void *arg)
{
THD *thd=(THD*) arg;
mysql_thread_set_psi_id(thd->thread_id);
do_handle_bootstrap(thd);
return 0;
}
void do_handle_bootstrap(THD *thd)
{
/* The following must be called before DBUG_ENTER */
thd->thread_stack= (char*) &thd;
if (my_thread_init() || thd->store_globals())
{
#ifndef EMBEDDED_LIBRARY
close_connection(thd, ER_OUT_OF_RESOURCES);
#endif
thd->fatal_error();
goto end;
}
handle_bootstrap_impl(thd);
end:
delete thd;
mysql_mutex_lock(&LOCK_thread_count);
in_bootstrap = FALSE;
mysql_cond_broadcast(&COND_thread_count);
mysql_mutex_unlock(&LOCK_thread_count);
#ifndef EMBEDDED_LIBRARY
my_thread_end();
pthread_exit(0);
#endif
return;
DBUG_VOID_RETURN;
}

View File

@ -99,10 +99,9 @@ void create_table_set_open_action_and_adjust_tables(LEX *lex);
void mysql_init_multi_delete(LEX *lex);
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex);
void create_table_set_open_action_and_adjust_tables(LEX *lex);
pthread_handler_t handle_bootstrap(void *arg);
void bootstrap(MYSQL_FILE *file);
int mysql_execute_command(THD *thd);
bool do_command(THD *thd);
void do_handle_bootstrap(THD *thd);
bool dispatch_command(enum enum_server_command command, THD *thd,
char* packet, uint packet_length,
bool is_com_multi, bool is_next_command);

View File

@ -2104,7 +2104,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, bool if_exists,
}
}
/* We remove statistics for table last, after we have the DDL lock */
if (!in_bootstrap)
if (!thd->bootstrap)
{
for (table= tables; table; table= table->next_local)
{