服务端启动流程
int mysqld_main(int argc, char **argv)
#执行基本线程库和malloc初始化,以便能够读取默认文件和解析选项。
|--> my_progname= argv[0];
|--> pre_initialize_performance_schema();
|--> if (my_init())
|--> if (load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv))
|--> init_pfs_instrument_array();
|--> ho_error= handle_early_options();
|--> init_sql_statement_names()
|--> sys_var_init();
|--> if (mysql_add_sys_var_chain(all_sys_vars.first))
|--> adjust_related_options(&requested_open_files);
|--> adjust_open_files_limit(requested_open_files);
|--> adjust_max_connections(*requested_open_files);
|--> adjust_table_cache_size(*requested_open_files);
|--> adjust_table_def_size();
|--> {
pfs_param.m_hints.m_table_definition_cache= table_def_size;
pfs_param.m_hints.m_table_open_cache= table_cache_size;
pfs_param.m_hints.m_max_connections= max_connections;
pfs_param.m_hints.m_open_files_limit= requested_open_files;
pfs_param.m_hints.m_max_prepared_stmt_count= max_prepared_stmt_count;
PSI_hook= initialize_performance_schema(&pfs_param);
}
|--> #ifdef HAVE_PSI_INTERFACE
|--> set_psi_server(psi_server);
|--> init_server_psi_keys();
|--> PSI_thread *psi= PSI_THREAD_CALL(new_thread)(key_thread_main, NULL, 0);
|--> PSI_THREAD_CALL(set_thread_os_id)(psi);
|--> PSI_THREAD_CALL(set_thread)(psi);
|--> my_thread_global_reinit();
|--> init_error_log();
|--> mysql_audit_initialize();
|--> Srv_session::module_init();
|--> query_logger.init();
|--> if (init_common_variables())
|--> my_init_signals();
|--> my_thread_attr_setstacksize(&connection_attrib,
my_thread_stack_size + guardize);
|--> test_lc_time_sz();
|--> if ((user_info= check_user(mysqld_user)))
|--> set_user(mysqld_user, user_info);
|--> if (my_setwd(mysql_real_data_home,MYF(MY_WME)) && !opt_help)
|--> if (opt_bin_log && !(server_id_supplied) )
|--> if (init_server_components())
|--> if (gtid_server_init())
|--> if (ha_init())
|--> if (init_server_auto_options())
|--> int gtid_ret= gtid_state->init();
|--> if (gtid_state->read_gtid_executed_from_table() == -1)
|--> int Gtid_state::read_gtid_executed_from_table()
{
return gtid_table_persistor->fetch_gtids(&executed_gtids);
}
|--> int Gtid_table_persistor::fetch_gtids(Gtid_set *gtid_set)
|--> if (gtid_set->add_gtid_text(encode_gtid_text(table).c_str()) !=RETURN_STATUS_OK)
|--> if (opt_bin_log)
|--> if (init_ssl())
|--> if (network_init())
|--> set_ports();
|--> Mysqld_socket_listener()
|--> init_connection_acceptor()
|--> setup_listener()
|--> my_str_malloc= &my_str_malloc_mysqld;
my_str_free= &my_str_free_mysqld;
my_str_realloc= &my_str_realloc_mysqld;
|--> create_pid_file();
|--> reload_optimizer_cost_constants();
|--> if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
my_tz_init((THD *)0, default_tz_name, opt_bootstrap) ||
grant_init(opt_noacl))
|--> servers_init(0);
|--> udf_init();
|--> init_status_vars();
|--> check_binlog_cache_size(NULL);
|--> check_binlog_stmt_cache_size(NULL);
|--> binlog_unsafe_map_init();
|--> set_slave_skip_errors(&opt_slave_skip_errors);
|--> init_slave();
|--> initialize_performance_schema_acl(opt_bootstrap);
|--> check_performance_schema();
|--> initialize_information_schema_acl();
|--> execute_ddl_log_recovery();
|--> start_signal_handler();
|--> if (opt_bootstrap)
{
start_processing_signals();
}
|--> if (opt_init_file && *opt_init_file)
{
if (read_init_file(opt_init_file))
unireg_abort(MYSQLD_ABORT_EXIT);
}
|--> if (mysql_audit_notify(AUDIT_EVENT(MYSQL_AUDIT_SERVER_STARTUP_STARTUP),
(const char **) argv, argc))
|--> start_handle_manager();
|--> create_compress_gtid_table_thread();
|--> start_processing_signals();
|--> set_super_read_only_post_init();
|--> server_operational_state= SERVER_OPERATING;
|--> mysql_mutex_lock(&LOCK_socket_listener_active);
|--> socket_listener_active= true;
|--> mysql_mutex_unlock(&LOCK_socket_listener_active);
|--> mysqld_socket_acceptor->connection_event_loop();
|--> void connection_event_loop()
{
Connection_handler_manager *mgr= Connection_handler_manager::get_instance();
while (!abort_loop)
{
Channel_info *channel_info= m_listener->listen_for_connection_event();
if (channel_info != NULL)
mgr->process_new_connection(channel_info);
}
}
客户端连接认证
#接上mysqld启动后,输入连接mysql客户端的命令:mysql -uroot -p
|--> void Connection_handler_manager::process_new_connection(Channel_info* channel_info)
|--> check_and_incr_conn_count()
|--> add_connection(channel_info)
bool Per_thread_connection_handler::add_connection(Channel_info* channel_info)
{
if (!check_idle_thread_and_enqueue_connection(channel_info))
DBUG_RETURN(false);
channel_info->set_prior_thr_create_utime();
error= mysql_thread_create(key_thread_one_connection, &id,
&connection_attrib,
handle_connection,
(void*) channel_info);
extern "C" void *handle_connection(void *arg)
|--> if (my_thread_init())
|-->for(;;) {
|--> init_new_thd()
|--> if (pthread_reused)
|--> mysql_thread_set_psi_THD(thd)
|--> add_thd(thd)
|--> if (thd_prepare_connection(thd))
|--> lex_start
|--> login_connection()
|--> check_connection()
|--> acl_check_host
|--> vio_keepalive(net->vio, TRUE)
|--> acl_authenticate(thd, COM_CONNECT)
|--> do_auth_once
|--> native_password_authenticate
|--> generate_user_salt
|--> write_packet
|-->send_server_handshake_packet
|--> read_packet
|--> server_mpvio_read_packet
|--> parse_client_handshake_packet
|--> check_scramble
|-->check_scramble_sha1
|--> acl_log_connect
|--> send_statement_status
|--> prepare_new_connection_state(thd)
else{
while{
|--> do_command(thd)
}
|--> end_connection(thd)
}
|--> close_connection
|--> release_resources
|--> Per_thread_connection_handler::block_until_new_connection()
|--> }