购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.4 MySQL启动流程

在深入探讨MySQL的启动流程前,我们已经对Server层与InnoDB层的基本架构有所了解。接下来,我们将聚焦于MySQL在初始化及启动过程中,如何分别针对Server层与InnoDB层的相关组件进行配置与激活。MySQL的启动架构如图2-4所示,本书详细阐述了MySQL如何系统地准备并启动其核心组件。

图2-4 MySQL的启动架构

从图2-4可知,MySQL的启动主要经历三个大的阶段:

❑第一阶段 :初始化变量、锁、MySQL命令、参数等。

❑第二阶段 :初始化各组件、插件,包括各种存储引擎。

❑第三阶段 :准备提供服务,初始化ssl、权限、信号量,监听套接字提供服务。

在MySQL的启动流程中,InnoDB存储引擎的启动与初始化被安排在第二阶段进行。作为MySQL的一个重要组成部分,InnoDB存储引擎被视作一个插件。因此,在MySQL系统加载并激活各类插件的过程中,InnoDB存储引擎也随之被加载并启动,进而执行其初始化流程。

MySQL的启动入口在mysqld.cc文件中的mysqld_main方法中。

2.4.1 第一阶段

下面重点介绍下第一阶段几个较为重要的步骤。

1)初始化performance_schema的内存结构。

performance_schema本身是一个内存内的数据库系统,专门用于存储MySQL的各类性能指标。自MySQL启动之初,performance_schema即被初始化,旨在持续追踪并记录一系列关键的性能指标数据,代码如下。

2)初始化MySQL sys线程、锁相关变量。

MySQL内部封装了一系列系统库,统称为my_sys,这些库涵盖了文件操作、日志记录、输入输出处理、字符集管理等核心功能。在此阶段,my_sys的主要任务是初始化后续过程中将要使用的线程及锁相关变量,以确保MySQL数据库系统的稳定运行和高效性能。

3)获取配置文件。

此步骤涉及获取用于启动MySQL服务的特定my.cnf配置文件。根据MySQL的默认行为,它会在一系列预设的目录下搜索此配置文件,例如/etc目录。若用户已明确指定了配置文件的路径,则MySQL将直接访问并开启该路径下的配置文件,随后将其内容载入内存,以便在后续操作中使用。

4)初始化early参数变量。

early参数变量是指在程序或系统启动流程的早期阶段就已被定义并可能随即在后续流程中使用的变量。这些变量通常具有关键性作用,对于确保流程的顺畅进行以及实现预期功能至关重要。例如,在软件初始化过程中设置的skip-grant-tables、help、initialize等参数变量均属于此类,它们为后续的程序执行或数据处理提供了必要的上下文或条件。

5)初始化MySQL命令。

我们平常会用到多种MySQL命令,例如alter_table、alter_tablespace、alter_user、begin等,该阶段主要初始化这些命令的内存结构。

6)调整open_files相关参数。

open file limit、max connection、table_cache_size、table_def_size参数跟open_files参数之间存在比例关系,MySQL会根据open_files的大小来调整这些参数的值。

7)初始化相关模块互斥锁。

在MySQL的内部实现中,广泛采用了互斥锁(Mutex)这一同步机制,以确保多线程环境下数据的一致性和完整性。具体而言,互斥锁被应用于多个关键组件中,包括但不限于日志模块、审计系统以及查询日志等,以保障这些模块在并发访问时能够安全、有序地执行各自的任务。

8)初始化所有参数变量的值。

在上述阶段中,MySQL已经将配置文件读取到内存中,这里会根据参数文件的值和默认值对MySQL的所有参数进行赋值。

9)初始化信号。

初始化MySQL进程用到的信号,MySQL会为一些信号设置相关的处理函数。

10)设置MySQL工作目录。

设置MySQL的工作目录,也是对应的datadir参数。

11)设置启动用户。

设置MySQL进程的启动用户,一般用户为mysql。

2.4.2 第二阶段

本阶段的核心任务是加载MySQL的各项组件,特别是插件部分,此部分尤为关键。在插件的架构中,各类存储引擎得以实现,而InnoDB存储引擎则占据了主导地位。因此,本小节将详尽阐述InnoDB存储引擎的初始化与启动流程。在深入探讨InnoDB存储引擎之前,我们有必要先对其他几个关键组件的初始化流程进行简要的概览。

初始化元数据锁的内存结构。

初始化表缓存的哈希表结构。

初始化table def cache哈希表结构。

初始化查询缓存内存结构。

初始化错误日志文件。

初始化事务缓存哈希表结构。

初始化键缓存内存结构。

初始化gtid相关内存结构。

在完成了上述组件的初始化步骤之后,随即进入插件的初始化阶段。值得注意的是,各个插件的初始化过程各具特色,无统一模式可循。以binlog插件为例,其初始化的核心在于配置与binlog紧密相关的功能方法,为后续操作奠定基础。鉴于本书中涉及的插件种类繁多,无法逐一详尽阐述。因此,此处将聚焦于InnoDB存储引擎的初始化过程,如图2-5所示。

图2-5 初始化InnoDB存储引擎

InnoDB存储引擎的初始化过程包含多个阶段,且每个阶段均较为复杂,为便于理解,参考图2-5我们将其概括为以下四个主要阶段:

❑准备阶段 。在正式执行之前,需要进行一系列的准备工作。首先,设定一个明确的数据目录,方便数据的存储与管理。随后,进行I/O配置,确保系统能够顺畅地进行数据的读写操作。紧接着,创建I/O线程,以并行处理的方式提升数据处理的效率。最后,初始化缓冲池,用以暂存数据,优化内存使用,加速数据访问。这一系列步骤的严谨执行是系统稳定运行与高效运作的基础。

❑初始化阶段 。在数据处理流程中,首要步骤是读取数据,这一过程涵盖了打开数据文件以及各类日志文件。随后,系统进入初始化阶段,包括事务系统的启动、数据字典的构建,以及回滚段的创建等关键步骤。至此,InnoDB已具备基础的服务提供能力,能够支持后续的数据操作与事务处理。

❑崩溃恢复阶段 。作为InnoDB数据库系统中极为关键的特性,崩溃恢复被独立划分为一个独立且重要的处理环节,因此我们特别将其视为一个独立的阶段进行详细探讨。

❑启动后台线程阶段 。在完成崩溃恢复流程后,InnoDB引擎已恢复并正式进入服务状态。然而,还需启动一系列服务于InnoDB周边环境的后台线程,以确保系统的全面运作。

1.准备阶段

首先,初始化目录。为了后续文件读取的顺利进行,MySQL将预先设立data、undo、redo三个目录结构。

接下来设置参数。在配置InnoDB存储引擎时,应当依据具体的需求和场景,精确设定各项参数,以确保数据库系统的稳定、高效运行。这些参数包括但不限于:

❑srv_io_capacity, 用于调整InnoDB在后台线程中执行I/O操作的能力。

❑srv_log_buffer_size, 用于设定InnoDB日志缓冲区的大小,该缓冲区用于存储即将写入磁盘的日志信息。

❑srv_buf_pool_size ,直接关联到InnoDB缓冲池的大小,它是InnoDB用来缓存数据、索引等内容的内存区域。

❑srv_n_read_io_threads和srv_n_write_io_threads, 分别用于配置InnoDB执行读I/O操作和写I/O操作的线程数量,以优化并发处理性能。

❑srv_use_doublewrite_buf ,一个关键的配置项,用于启用或禁用InnoDB的双写缓冲区功能,该功能旨在提高数据页的写入可靠性。因此,在调整这些参数时,需要综合考虑系统资源、工作负载以及数据安全性等多方面因素。

在数据库管理中,为了支持后续操作的高效执行,需要构建专用的临时表空间。此空间被广泛应用于临时表的创建,确保常用临时表能够依托此表空间实现数据的临时存储与处理。

MySQL数据库系统支持异步I/O操作,这一特性将在后续的章节中进行详尽的阐述。目前,此处的重点仅在于构建与异步I/O相关的内存结构。

初始化表空间缓存。启动并初始化fil_system表空间管理结构,该结构旨在全面管理和维护系统中的所有表空间。

创建I/O线程,提供读写数据文件、日志文件能力。

创建page cleaner线程,旨在专门负责将脏页有效地刷新到数据文件中,以确保数据的完整性和持久性。

初始化缓冲池内存结构,主要用于在内存中缓存数据页。

可以看到这些准备工作就是服务于接下来的打开数据文件等操作,比如创建I/O线程、初始化缓冲池等。

2.初始化阶段

启动数据文件处理流程,将相关必要信息从数据文件中读取并加载至系统内存中,以确保后续能够顺畅地读取与扫描数据文件内容。

启动并打开redo文件,以便在该文件中继续保存和记录后续的redo操作。

打开系统表空间数据文件,该文件存储了MySQL数据库所有至关重要的内部核心信息。在此阶段,MySQL首先执行打开操作,以便在后续的步骤中能够顺利读取数据文件中与系统相关的数据页内容。

初始化Undo表空间,这里实际上是打开回滚表空间,最终打开对应的回滚日志文件。

初始化trx_sys结构,该结构是用于管理事务系统的。

初始化数据字典内存结构,后续读取表结构信息将存储在该结构中。

创建回滚段,用于后续管理回滚记录。

此时,InnoDB相关文件已成功打开,且相关系统已完成初始化,标志着系统已基本具备向用户提供服务的能力。

3.崩溃恢复阶段

崩溃恢复作为InnoDB数据库管理系统中的一个至关重要的特性,其影响力广泛,几乎覆盖了InnoDB的每一个核心组件。鉴于其复杂性和重要性,我们将在后续章节中对其进行详尽而深入的剖析,以确保内容的完整性和准确性。在此,我们仅就崩溃恢复的大致流程进行概括性描述。

该流程的核心在于对redo日志文件和binlog日志文件进行扫描与分析,以识别并判断在系统崩溃时,是否存在尚未完成的事务需要被回滚或提交。这一过程对于确保数据库的一致性和完整性至关重要,是InnoDB实现高效、可靠数据管理不可或缺的一环。

4.启动后台线程阶段

在本阶段,我们主要聚焦于创建一系列相关线程,其各自的功能已在本章先前内容中进行了详尽阐述,故在此不再重复说明。以下仅为相关代码的简要列举,供有兴趣的读者自行探究与学习。

创建lock_wait_timeout_thread、error_monitor_thread、monitor_thread线程。

创建外键约束系统表。

创建SYS_TABLESPACES系统表。

创建SYS_VIRTUAL表。

创建master线程。

创建purge调度和worker线程。

创建buf_dump\dict_stats\optimize FTS线程。

创建buf_resize_thread线程。

至此InnODB存储引擎全部初始化完成。

2.4.3 第三阶段

第三阶段主要是准备提供服务,初始化ssl、权限、信号量,监听套接字提供服务。

首先创建auto.cnf。在InnoDB中,每个实例都需要有一个UUID(Universally Unique Identifier,通用唯一识别码),这个UUID会保存到auto.cnf文件中,如果没有该文件,则InnoDB会创建一个。

接着初始化ssl相关内存结构,加载RSA密钥对,并存储在全局。

然后初始化网络相关对象,例如设置端口,使用ip、port、backlog等配置创建TCP套接字和UNIX套接字对象。

创建PID(Process Identifier,进程标识符)文件。

清理上次创建的临时表。

初始化user/db和table/column-level级别的权限。

初始化自定义函数,从mysql.func表中读取所有的用户自定义func。

初始化global status。让show status可以读取到all_status_vars变量,这样用户执行时就可以看到所有的变量了。

初始化slave。如果是从库,则会开启I/O和SQL线程。

执行ddl recovery。在线的ddl会将ddl日志写到对应的recovery log中,重启后通过该方法恢复。

初始化event scheduler。

创建signal handler线程,用于监听signal。

加载审计插件。

创建gtid table压缩线程。

在正式提供服务之前设置super_read_only参数,该参数启用之后数据库为只读。

开启套接字监听,如果监听到请求则创建对应的连接,MySQL的启动最终会阻塞在这里。

至此,MySQL已经正式对外提供服务。 tgUuESHhQd99mLWvDCIP7Gk0D9dGhgI1rRruTy9vISkssjoijWI5GQgFaZXD6eM7

点击中间区域
呼出菜单
上一章
目录
下一章
×