5 从plugin_init()看存储引擎的初始化

本文详细解析了MySQL中InnoDB存储引擎的初始化过程,包括plugin_init、ha_initialize_handlerton、innobase_init和innobase_start_or_create_for_mysql等步骤。涉及内存分配、哈希表初始化、异步IO系统、表空间管理、事务系统、锁系统、恢复机制等多个关键环节,揭示了InnoDB启动时的内部操作。

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

一、plugin_init

main()------->init_server_components()-------->plugin_init(&remaining_argc, remaining_argv, ...)

1、register_builtin()将plugin(类型为struct st_mysql_plugin)的指针保存到plugin_array这个动态数组和plugin_hash[type]这个哈希表中,内容保存到plugin_mem_root中。

2、调用plugin_initialize(),进一步调用ha_initialize_handlerton(st_plugin_int *plugin)。st_plugin_int结构体实际上是A handle of a plugin,它包含struct st_mysql_plugin *plugin、ref_count引用计数。


二、ha_initialize_handlerton(st_plugin_int *plugin)

1、为handlerton *hton分配内存。

2、调用plugin->plugin->init(hton),进一步调用innobase_init(hton)(位于storage/innobase/handler/ha_innodb.cc中)


三、innobase_init(void *p)

1、handlerton *innobase_hton= (handlerton *)p,并初始化它。

        innobase_hton->state = SHOW_OPTION_YES;   //设置状态
        innobase_hton->db_type= DB_TYPE_INNODB;
        innobase_hton->savepoint_offset=sizeof(trx_named_savept_t);
        innobase_hton->close_connection=innobase_close_connection;
        innobase_hton->savepoint_set=innobase_savepoint;
        innobase_hton->savepoint_rollback=innobase_rollback_to_savepoint;
        innobase_hton->savepoint_release=innobase_release_savepoint;
        innobase_hton->commit=innobase_commit;
        innobase_hton->rollback=innobase_rollback;
        innobase_hton->prepare=innobase_xa_prepare;
        innobase_hton->recover=innobase_xa_recover;
        innobase_hton->commit_by_xid=innobase_commit_by_xid;
        innobase_hton->rollback_by_xid=innobase_rollback_by_xid;
        innobase_hton->create_cursor_read_view=innobase_create_cursor_view;
        innobase_hton->set_cursor_read_view=innobase_set_cursor_view;
        innobase_hton->close_cursor_read_view=innobase_close_cursor_view;
        innobase_hton->create=innobase_create_handler;
        innobase_hton->drop_database=innobase_drop_database;
        innobase_hton->panic=innobase_end;
        innobase_hton->start_consistent_snapshot=innobase_start_trx_and_assign_read_view;
        innobase_hton->flush_logs=innobase_flush_logs;
        innobase_hton->show_status=innobase_show_status;
        innobase_hton->flags=HTON_NO_FLAGS;
        innobase_hton->release_temporary_latches=innobase_release_temporary_latches;
	innobase_hton->alter_table_flags = innobase_alter_table_flags;

2、一些相关设置

innobase_file_format_name 为"Antelope",srv_file_per_table=false,

3、innobase_start_or_create_for_mysql(void)——核心启动函数

Starts InnoDB and creates a new database if database files are not found and the user wants.

4、innobase_open_tables = hash_create(200)

5、初始化innobase_share_mutex、prepare_commit_mutex、commit_cond_m/commit_cond。


四、innobase_start_or_create_for_mysql(void)

1、根据一些变量进行设置,如根据srv_buf_pool_size设置srv_buf_pool_instances = 1。

2、srv_boot()——Boots the InnoDB server.

其中srv_normalize_init_values()计算srv_data_file_sizes(此处为640页,一页16k)等;srv_general_init() Initializes the synchronization primitives, memory system, and the thread local storage;srv_init() Initializes the server。

UNIV_INTERN
void
srv_init(void)
/*==========*/
{
	srv_conc_slot_t*	conc_slot;
	srv_slot_t*		slot;
	ulint			i;

	srv_sys = mem_alloc(sizeof(srv_sys_t)); //srv_sys_t 为 The server system struct,元素包含一个线程表和一个task queue

	kernel_mutex_temp = mem_alloc(sizeof(mutex_t)); //mutex protecting the server, trx structs, query threads, and lock table
	mutex_create(kernel_mutex_key, &kernel_mutex, SYNC_KERNEL);

	mutex_create(srv_innodb_monitor_mutex_key,
		     &srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);

	srv_sys->threads = mem_zalloc(OS_THREAD_MAX_N * sizeof(srv_slot_t)); 

	for (i = 0; i < OS_THREAD_MAX_N; i++) { //此处OS_THREAD_MAX_N为10000
		slot = srv_sys->threads + i;
		slot->event = os_event_create(NULL);    //这个之后再看
		ut_a(slot->event);
	}
        //Table for MySQL threads where they will be suspended to wait for locks 
	srv_mysql_table = mem_zalloc(OS_THREAD_MAX_N * sizeof(srv_slot_t)); 

	for (i = 0; i < OS_THREAD_MAX_N; i++) {
		slot = srv_mysql_table + i;
		slot->event = os_event_create(NULL);
		ut_a(slot->event);
	}

	srv_error_event = os_event_create(NULL);

	srv_timeout_event = os_event_create(NULL);

	srv_monitor_event = os_event_create(NULL);

	srv_lock_timeout_thread_event = os_event_create(NULL);

	for (i = 0; i < SRV_MASTER + 1; i++) { //SRV_MASTER此处为1
		srv_n_threads_active[i] = 0;
		srv_n_threads[i] = 0;
	}

	UT_LIST_INIT(srv_sys->tasks);

	/* Create dummy indexes for infimum and supremum records */

	dict_ind_init();

	/* Init the server concurrency restriction data structures */

	os_fast_mutex_init(&srv_conc_mutex);

	UT_LIST_INIT(srv_conc_queue);

	srv_conc_slots = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_conc_slot_t));

	for (i = 0; i < OS_THREAD_MAX_N; i++) {
		conc_slot = srv_conc_slots + i;
		conc_slot->reserved = FALSE;
		conc_slot->event = os_event_create(NULL);
		ut_a(conc_slot->event);
	}

	/* Initialize some INFORMATION SCHEMA internal structures */
	trx_i_s_cache_init(trx_i_s_cache);
}

3、srv_n_file_io_threads = 2+4个readIO+4个writeIO

4、os_aio_init() Initializes the asynchronous io system,初始化异步IO~~~

5、fil_init() Initializes the tablespace memory cache,初始化fil_system_t* fil_system的spaces、name_hash这两个哈希表,初始化fil_system->LRU。之后再看。

6、buf_pool_init()

调用buf_pool_init_instance()初始化buf_pool_t* buf_pool,Add the block to the free list,并设置buf_pool->no_flush[i] = os_event_create(NULL)(pending writes)。


7、log_init()

8、lock_sys_create(srv_lock_table_size)用于Creates the lock system,初始化lock_sys_t*lock_sys,并初始化lock_sys->rec_hash这个哈希表。

9、os_thread_create(io_handler_thread, n + i, thread_ids + i)创建10个IO线程,处理函数io_handler_thread(void *arg)调用fil_aio_wait()等待异步事件的到来。

10、open_or_create_data_files(&create_new_db, ...)打开或创建共享表文件ibdata1,之后关闭。

11、fil_open_log_and_system_tablespace_files():Open all log files and data files in the system tablespace: we keep them open until database shutdown. This should be called at a server startup after the space objects for the log and the system tablespace have been created.

fil_system->space_list连接着不同类型的文件,第一个fil_space_t是表空间,第二个fil_space_t是redolog;fil_space_t->node连接着同一类型下的不同文件,例如对于redolog,有两个文件,所以有两个节点。


12、InnoDB: highest supported file format is Barracuda.

13、recv_recovery_from_checkpoint_start():always try to do a recovery。如何恢复???

14、dict_boot()它会同时初始化insert buffer

15、trx_sys_init_at_db_start()会初始化trx lists。Creates and initializes the central memory structures for the transaction system

16、recv_recovery_from_checkpoint_finish(),这需要上一步先执行。Completes recovery from a checkpoint.

17、recv_recovery_rollback_active() Initiates the rollback of active transactions. 它会创建一个线程,处理函数为trx_rollback_or_clean_all_recovered().

该处理函数的主要作用如下:Rollback or clean up any incomplete transactions which were encountered in crash recovery.  If the transaction already was committed, then we clean up a possible insert undo log. If the transaction was not yet committed, then we roll it back.


18、检查trx_doublewrite_t* trx_doublewrite(两次写缓冲区)是否为空,如果为空,就调用trx_sys_create_doublewrite_buf()创建。(此处不为空)

19、trx_sys_create_rsegs() Creates the rollback segments.

20、创建3个线程:都是由os_thread_create()创建的,处理函数分别如下:

srv_lock_timeout_thread()用于watches the timeouts for lock waits;srv_error_monitor_thread()用于warns of long semaphore waits;srv_monitor_thread() prints InnoDB monitor info.


21、dict_create_or_check_foreign_constraint_tables( ) Creates the foreign key constraints system tables inside InnoDB at database creation or database start。

22、创建主线程,处理函数为srv_master_thread()。本线程会等待主线程启动完毕(直到srv_shutdown_state != SRV_SHUTDOWN_NONE)


本篇文章是对InnoDB初始化过程的一个大概认识,还有很多细节没有深入,需要之后不断分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值