mysqld一直正在启动_MySQL源码阅读1-启动初始化

这篇博客详细介绍了MySQL服务器的启动初始化过程,从配置文件解析到各种组件的初始化,如PSI、定时器、字符集、存储引擎、线程管理等。还提到了MySQL启动时涉及的主要线程及其功能,包括连接监听线程、处理线程、slave/relay线程、信号处理线程等。文章通过函数调用链展示了初始化的步骤,并强调了初始化的复杂性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

94721876ca5ff46efaa11fe962d68bad.png

0. 背景

决定将mysql的代码看一下,并且记录下来,希望能够学习一下mysql的内核相关知识。

目前是采取这么一种策略,即看到哪里记录到哪里,也不知道最后会有多少产出。

当然因为是初次阅读,当然会存在很多错误或遗漏,也希望相关人士能够指出。估计在后续的阅读中也会进一步对之前的笔记进行修改,望见谅。

1. MySQL初始化

当然第一篇就是mysql的启动初始化和终止阶段逻辑。以下是初始化简单的小结,更多的话可以在后面的代码函数栈可以看到。终止阶段的逻辑相对简单些。

代码路径:https://github.com/mysql

入口函数:mysql-server-8.0/sql/mysqld.cc::mysqld_main

初始化的内容

  • 参数配置解析:
    • 分别从/etc/my.conf, /etc/mysql/my.conf, SYSCONFDIR/my.cnf, "$MYSQL_HOME"/my.conf, defaults-extra-file, ~/my.conf, DATADIR/mysqld-auto.cnf, 命令行 加载配置文件中的配置项。SYSCONFDIR/my.cnf是在编译时指定的路径,DATADIR是指定的数据目录 ,如果不指定特定的配置的,将按照上面逐步查找配置。
  • performance schema interface(PSI)初始化;PSI主要用于监控/诊断MySQL服务运行状态,可以阅读官方文档:https://dev.mysql.com/doc/refman/8.0/en/performance-schema.html 和(PFS)初始化
  • 初始化定时器timer;
  • 时间相关的
  • 基础的锁结构;
  • 资源池,通知消息等初始化;
  • 字符集/collation
  • 元数据
  • 系统库表,information_schema
  • DDL/DQL/DML/ACL支持的命令
  • plugin,存储引擎
  • binlog
  • 优化器optimizer代价
  • 恢复持久化中的事务数据,
  • ACL相关的初始化,授权相关的初始化
  • SSL
  • 信号处理
  • 审计相关初始化
  • 各类管理器
  • MySQL中的线程

MySQL中的线程

MySQL中主要会启动以下线程处理各种任务:

  • 连接监听主线程,用于监听处理客户端的连接请求,然后将连接请求分发到单独的线程,并处理该连接上的所有请求;
  • 处理线程,是一个线程池,具体在后面会介绍;
  • slave/relay线程,连接到主服务的线程,并且从主服务器中读取binlog更新,在本机上应用更新;
  • 信号处理线程,用来处理信号,具体的信号包括了:SIGTERM, SIGQUIT, SIGHUP, SIGUSR1 and SIGUSR2
  • event_scheduler_thread,事件调度线程,用来调度执行每个表上定义事件,即Event。
  • compress_gtid_table_thread开启一个线程用来压缩GTID_Table,具体的压缩逻辑在mysql-server-8.0/sql/http://rpl_gtid_persist.cc中,估计后续会进一步阅读。
  • helper_thread,辅助线程来分发计时器timer到期通知消息,具体逻辑在timer_notify_thread_func。
  • admin_socket_thread,如果开启了该线程,并且以端口监听,则可以用handle_admin_socket处理请求的逻辑,具体的连接也会用一个新的线程处理。

2. 函数调用链

代码块为初始化的调用链,每一个缩进表示函数调用。

substitute_progpath:将命令行的程序名替换成全路径的程序名,可能是“全路径”,home路径解释,环境变量PATH解释。 

sysd::notify_connect:在环境变量(“NOTIFY_SOCKET“)中查找socket的文件名,如果存在的话则连接该Socket 

sysd::notify:向Notify Socket发送正在启动的消息。 

my_init:初始化my_sys函数,资源和变量 
	my_thread_global_init:初始化线程的环境(初始化一堆资源锁) 
		PSI_mutex_key 结构 
	my_thread_init:申请mysys线程的内存,主要用于debug 

load_defaults -> my_load_defaults:从配置文件中读取配置项 
	init_default_directories:获取配置的目录 
	my_search_option_files:处理在缺省目录下的配置文件,即上一步结果 
		get_defaults_options:从命令行中获取配置选项; 
		init_variable_default_paths:初始化配置文件的作用域(enum_variable_source) 
		search_default_file:如果是绝对路径,直接读取; 
		search_default_file_with_ext:从输入配置的文件中读取; 
	my_default_get_login_file:从login集群中读取配置。 
		my_search_option_files 
	set_args_separator:分隔符 

persisted_variables_cache:持久化的参数配置缓存,采用JSON进行存储, 
	Init:初始化,从命令行或者是环境变量“MYSQL_DATADIR“中获取文件 
		my_handle_options:主要处理参数的逻辑。 
	load_persist_file:加载持久化文件的配置,并且转成JSON格式,分析出K/V结构; 
	append_read_only_variables:将上一步分解出的只读配置参数追加到命令行参数中。 

init_variable_default_paths:初始化配置文件的作用域(enum_variable_source) 

init_pfs_instrument_array: PSI: performance schema interface; PFS:performance storage 

handle_early_options:处理早期的选项,包括:performance schema;与help或者启动相关的参数 
	sys_var_add_options:增加系统参数; 
	增加命令行中的早期选项; 
	add_terminator:增加终结。 
	handle_options->my_handle_options:处理参数 

init_sql_statement_names: 初始化与sql语句相关的名字(com_status_vars),包括各种dml/ddl/acl/dql等 

sys_var_init:初始化系统变量(mysql-server-8.0/sql/sys_vars.cc中定义静态变量) 
	mysql_add_sys_var_chain 

init_error_log:初始化错误日志 

adjust_related_options:调整相关的参数, 
	adjust_open_files_limit 
	adjust_max_connections 
	adjust_table_cache_size 
	adjust_table_def_size 

initialize_performance_schema:初始化performance_schema 
	pfs_automated_sizing:将ps相关的参数都置为0; 
	init_timers:根据系统进行初始化performance_schema的计数器,并且获得当前值;可以从performance_timers表获取 
		my_timer_init 
		my_timer_cycles 
		my_timer_nanoseconds 
		my_timer_milliseconds 
	初始化histograms(表的统计量)的定时器, 
	init_event_name_sizing:初始化全局表I/O,表锁/元数据等的事件 
	register_global_classes:初始化全局的仪表,包括类型有:表I/O,表锁,Idle类,元数据类,错误类,事物类。 
	接下来是申请一堆仪表的内存 
	并且从参数里头获取配置 
	init_pfs_plugin_table:初始化pfs内置的table 
		PFS_dynamic_table_shares::init_mutex 
		init_pfs_plugin_table 

LO_init:初始化Lock Order,主要用Lock Order Graph描述锁依赖关系:https://dev.mysql.com/doc/refman/8.0/en/lock-order-tool.html 

//START与psi相关的服务  
设置psi相关的服务:thread_service,mutex_service,rwlock_service,cond_service,file_service,socket_service,table_service,mdl_service,idle_service,stage_service,statement_service,transaction_service,memory_service,error_service,data_lock_service,system_service 

init_server_psi_keys:注册psi key的函数,包括psi服务的mutex,rwlock,conds,threads,files,stage,socket;内存的key,sql语句的信息(init_sql_statement_names中提到的),psi_api,与store procedures相关的key,与调度(scheduler)相关的(主要是evengt),与client公用的key,vio的key(与通信相关的) 

my_thread_global_reinit:重新初始化一些比较开始与锁相关的,因为需要考虑一些仪表 
// 与psi相关的服务 END 

component_infrastructure_init 
	mysql_services_bootstrap:启动服务注册,动态加载器,和基础的服务 
		registry_init:创建注册服务套件,内部的结构mysql_registry 
		把加载器的实现写入到服务注册表 
		dynamic_loader_init:初始化动态加载器,其实就是初始化锁 
		dynamic_loader_scheme_file_init:初始化scheme文件 
	pfs_init_services: ps是performance storage 

register_pfs_notification_service 

register_pfs_resource_group_service 

Resource_group_mgr::init:初始化资源组管理器, 
	与资源相关的服务,包括: registry service,mysql_service_pfs_resource_group_v3_t,mysql_service_pfs_notification_v3_t 
	注册线程创建/断开连接的回调
	创建用户级/系统级的资源组对象 

调用psi_thread_service相关函数:new_thread,set_thread_os_id,set_thread 

mysql_audit_initialize:初始化与audit相关的变量; 

Srv_session::module_init:初始化srv_session模块 

query_logger.init:查询日志初始化 

init_common_variables: 
	init_thread_environment:初始化与线程相关的锁; 
	mysql_init_variables:初始化全局变量为缺省值 
	mysql_bin_log.set_psi_keys完成bin log的初始化,让仪表相关的对bin log可见 
	mysql_bin_log.init_pthread_objects:初始化bin log与线程相关的锁 
	get_options,剩余的可选项,binlog,压缩算法,页的大小,线程缓存大小,back_log 
		Connection_handler_manager::init,初始化连接池
			Per_thread_connection_handler::init,初始化Per_thread_connection_handler,初始化锁
	初始化mysql client的plugin 
	选字符集/collation 
	日志配置 
	创建数据目录 
	表的大小写等 

my_init_signals:初始化信号处理 

线程栈大小检查 

Migrate_keyring::init:初始化Migrate_keyring(一种mysql数据搬运模式)相关的,如压缩方式,并且连接到数据源主机 
Migrate_keyring::execute 
	fetch_and_store_keys
// 如果启动方式为Migrate_keyring,则数据搬完后退出

set_ports:确定tcp端口 

init_server_components 
	mdl_init:metadata locking subsystem元数据锁子系统, 
	MDL_map::init, MDL_key,一个重要的数据结构:元数据锁 
	partitioning_init 
	table_def_init:表定义缓存(Table_definition_cache) 
		Table_cache_manager::init:表缓存初始化 
			Table_cache::init 
	hostname_cache_init:初始化(client)主机名缓存,Host_entry 
	my_timer_initialize:初始化内部组建,fd, 
		start_helper_thread:时间通知线程,timer_notify_thread_func 
	init_slave_list:初始化从机列表 
	transaction_cache_init:初始化事务缓存的psi键 
	MDL_context_backup_manager::init,MDL_context_backup_manager 
	:维护XA事务中元数据锁 
	delegates_init:初始化外部observer的委托,包括事务,bin log,服务状态,bin log传输,relay IO 
	与bin/relay log相关的初始化 
	process_key_caches:用ha_init_key_cache函数初始化所有的key缓存 
	ha_init_errors:初始化错误信息 
	gtid_server_init:GTID server初始化 
	udf_init_globals:初始化udf结构体 
	init_ssl:配置SSL包 
		ssl_start: 
			SSL_library_init 
			OpenSSL_add_all_algorithms 
			init_ssl_locks:初始化ssl锁, 
			init_lock_callback_functions:锁回调函数 
	plugin_register_early_plugins 
		plugin_init_internals:初始化内部plugin,资源/锁 
		plugin_load_list 
			plugin_dl_add 
			plugin_add 
			plugin_init_initialize_and_reap:重试失败的plugin 
	plugin_register_builtin_and_init_core_se,初始化内置plugin,包含MyIsam,CSV,InnoDB 
	init_sql_command_flags:初始化sql命令flag 
	dd::init: 
		cache::Shared_dictionary_cache::init,包括字符/collation,抽象表,事件,routine,schema,column,tablespace,资源组等字典初始化 
		System_tables::instance()->add_inert_dd_tables() 
		System_views::instance()->init() 系统视图,主要是information_schema下的 
		Dictionary_impl::init 
	plugin_register_dynamic_and_init_all,注册动态的plugin和初始化所有的plugin 
	确定线程池组织方式:SCHEDULER_ONE_THREAD_PER_CONNECTION/SCHEDULER_NO_THREADS 
	从5.7升级到8.0相关的处理 
	dd::performance_schema::init_pfs_tables:处理好pfs相关的表 
	upgrade_system_schemas:升级系统库表 
	Resource_group_mgr::post_init从磁盘读取资源组数据 
	handle_options:处理剩余的参数可选项 
	ha_init:初始化 
	query_logger相关的处理 
	initialize_storage_engine:初始化缺省(或临时)的存储引擎 
	Recovered_xa_transactions::init:恢复XA事务初始化 
	Recovered_xa_transactions::recover_prepared_xa_transactions恢复预处理的XA事务 
	init_server_auto_options:初始化服务自动项, 
	MYSQL_BIN_LOG::open_binlog,打开一个bin log文件,分析主备bin log,也会purge一些日志 
	init_optimizer_cost_module:初始化优化器(应该是物理优化器)代价的模块 
		init_cache_tmp_engine_properties 
			Cache_temp_engine_properties::init,临时的引擎特性,HEAP/TempTable/INNODB 
	ft_init_stopwords:停用词 
	init_max_user_conn:client连接 

Gtid_state::init,将server_uuid放至sid_map中 

MYSQL_BIN_LOG::init_gtid_sets,从gtid_executed表和binlog文件中初始化GLOBAL.GTID_EXECUTED 和 GLOBAL.GTID_PURGED 的值,分别应该是已经执行的GTID和回收的GTID

init_ssl_communication: 
	set_fips_mode:设置openssl包的fips 
	SslAcceptorContext::singleton_init,初始化ssl接收器 
		do_auto_cert_generation,生成证书 
	init_rsa_keys,从磁盘中加载RSA键值对,sha256 

network_init,初始化服务的listener,三种,Mysqld_socket_listener/Named_pipe_listener/Shared_mem_listener,后两者仅在windows下会启动
	Connection_acceptor::init_connection_acceptor 
		Mysqld_socket_listener::setup_listener,如果是Mysqld_socket_listener,并且需要开通管理员socket
			spawn_admin_thread,启动admin的listener线程。 
				admin_socket_thread
					handle_admin_socket,开始监听管理请求

create_pid_file,创建pid文件 

reload_optimizer_cost_constants,重新加载优化器的计算成本常量 
	Cost_constant_cache::reload 

mysql_component_infrastructure_init,通过初始化动态加载器来初始化mysql服务组建 
	persistent_dynamic_loader_init,恢复持久化文件中的数据
		mysql_persistent_dynamic_loader_imp::init 
			open_component_table 
			读取组件table中的数据 
			mysql_dynamic_loader_imp::load 
				dd::sdi_file::load 
	trans_rollback_stmt:回滚单语句的事务 
		ha_rollback_trans 
	trans_rollback:回滚当前的事务
	server_component_init,除第一个函数外,其他均为dummy空函数,
		mysql_comp_sys_var_services_init 
		mysql_string_services_init(); 
		mysql_comp_status_var_services_init(); 
		mysql_comp_system_variable_source_init(); 
		mysql_backup_lock_service_init(); 
		clone_protocol_service_init(); 
		page_track_service_init(); 
		mysql_security_context_init(); 
		mysql_server_ongoing_transactions_query_init(); 
		host_application_signal_imp_init(); 
		mysql_audit_api_service_init(); 
		mysql_current_thread_reader_imp_init(); 
		mysql_keyring_iterator_service_init(); 
		mysql_comp_udf_extension_init(); 
		mysql_connection_attributes_iterator_imp_init(); 
	trans_commit_stmt,提交语句事务 
	trans_commit,提交当前事务 

mysql_rm_tmp_tables,删除之前服务遗留的临时文件 

acl_init 
	init_acl_cache 
	check_engine_type_for_acl_table, 
	check_acl_tables_intact 
	notify_flush_event 

init_acl_memory,出事acl的内存 

my_tz_init:初始化时区 
	open_trans_system_tables_for_read 
		open_tables 
			open_tables_check_upgradable_mdl 
				find_table_for_mdl_upgrade 
			lock_table_names 
		lock_tables 
			mysql_lock_tables 
				lock_tables_check 
				get_lock_data:获得表的锁结构 
			check_lock_and_start_stmt 
	闰秒相关的初始化逻辑 

grant_init: 
	grant_reload:加载授权 
		open_and_lock_tables 
		grant_load:从授权表中加载表/列的权限检查信息 
		grant_reload_procs_priv:从procs_priv表中读取权限信息 
		commit_and_close_mysql_tables: 

dynamic_privilege_init: 
	mysql_plugin_registry_acquire 
	初始化管理相关的权限 

servers_init:从mysql库中初始化结构数据 
	servers_reload:初始化mysql.servers表的数据 

udf_read_functions_table:从mysql.func中加载数据 

init_status_vars: 

init_slave:初始化slave线程,并开启 
	Rpl_info_factory::create_slave_info_objects 
	start_slave_threads,对多个channel开启 
		start_slave_thread::handle_slave_sql处理relay日志 

initialize_performance_schema_acl 
	ACL_internal_schema_registry::register_schema 

Events::init:初始化event结构 
	load_events_from_db 
	Event_scheduler::start 
		pre_init_event_thread 
		event_scheduler_thread 

start_signal_handler,启动单独的线程signal_hand来处理信号,如SIGTERM, SIGQUIT, SIGHUP, SIGUSR1 and SIGUSR2  

process_bootstrap: 
	server_components_initialized 
	run_bootstrap_thread:启动单独处理init_file 中的sql语句 
		handle_bootstrap 
			handle_bootstrap_impl 
				process_iterator 
	dd::init 

mysql_audit_notify: 
	mysql_audit_acquire_plugins,获取plugins
	event_class_dispatch
		plugins_dispatch,通过调用plugin的event_notify函数分发时间

start_handle_manager,开启handler管理线程
	handle_manager,线程函数,监听COND_manager信号等

create_compress_gtid_table_thread,开启一个线程调用以下函数 
	compress_gtid_table,根据压缩COND_compress_gtid_table信号对gtid_executed表进行压缩 
		Gtid_state::compress
			Gtid_table_persistor::compress,更多详细的逻辑在mysql-server-8.0/sql/rpl_gtid_persist.cc中

Connection_acceptor::connection_event_loop:开启监听服务。 window会进入setup_conn_event_handler_threads函数,并启动三个单独线程处理不同的连接方式,即Mysqld_socket_listener/Named_pipe_listener/Shared_mem_listener

// 以下为结束阶段的代码
待收到结束信号后,
terminate_compress_gtid_table_thread,终止compress_gtid_table_thread

save_gtids_of_last_binlog_into_table,保存gtid的最新值到表中

发送信号给监听线程

close_connections:关闭连接,SIGQUIT信号
	Per_thread_connection_handler::kill_blocked_pthreads
	Mysqld_socket_listener/Shared_mem_listener/Named_pipe_listener::close_listener
		mysql_socket_shutdown
		mysql_socket_close
			Connection_acceptor::close_listener
	Events::stop,停止Event调度器
	Set_kill_conn,对连接设置KILL_CONNECTION flag
	Events::deinit,清理调度器的资源,
	关闭所有连接,Call_close_conn::close_connection
	Connection_handler_manager::wait_till_no_connection,等待所有连接结束
	delete_slave_info_objects,释放slave线程占用的资源

终止仪表线程

3. 总结

mysql服务的初始化还是很复杂的,但是一般情况下都不会被关注到。这次也是阅读不是细致,肯定会存在一些问题,也希望在后续能够继续阅读初始化/终止的每一块代码。

下篇:

Wenguang Liu:MySQL源码阅读2-连接与线程管理​zhuanlan.zhihu.com
0ba81cc7f41acc98231d28d2537c3af9.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值