Mysql 体系架构
2020-04-27 09:35:26 3 举报
AI智能生成
Mysql体系架构--Mysql优化读书笔记。数据库完整架构
作者其他创作
大纲/内容
数据目录结构
配置文件:my.cnf。MySQL读取配置文件的顺序为(非Windows系统)/etc/my.cnf、/etc/mysql/my.cnf、/usr/local/mysql/etc/my.cnf、~/.my.cnf,可以使用mysql--help |grep '/etc/my.cnf'命令查看。如果启动MySQL时没有显式指定配置文件,则MySQL会依次按照该顺序进行读取,直到读取到最后一个配置文件为止。其间,如果读取到相同的配置参数,则以最后读取到的配置参数值为准,覆盖前面的相同参数值。
数据文件
.frm:表结构定义文件
.MYI:MyISAM存储引擎索引文件
.MYD:MyISAM存储引擎数据文件
.ibd:InnoDB存储引擎独立表空间文件
.ibdata*:InnoDB存储引擎共享表空间文件
.ib_logfile*:InnoDB存储引擎redo log文件
undo*:InnoDB存储引擎独立undo文件
ibtmp1:InnoDB存储引擎临时表空间文件
auto.cnf:用于存放MySQL实例的全局唯一的server-uuid的文件
db.opt:用于存放MySQL实例的schema级别的默认字符集和默认校对规则的文件
.CSM:用于存放CSV存储引擎的元数据等相关信息的文件
.CSV:用于存放CSV存储引擎的数据文件,每行数据的列值之间使用逗号分隔
.TRN:用于存放与触发器相关的元数据
.TRG:用于存放触发器定义语句以及与定义相关的信息
日志文件
error.log(error log):错误日志,记录着MySQL启动之后mysqld打印的相关信息。错误日志文件在MySQL Server启动之后必须存在;否则,在使用mysqld_safe启动数据库时会因为找不到错误日志文件而报错,终止启动过程(如果直接使用mysqld程序来启动数据库,则不会有这个问题,因为mysqld进程发现错误日志不存在时会重新创建)。
localhost.log(general log):一般查询日志,启用该日志之后,在MySQL Server中执行的所有SQL语句都会被记录。查询日志可以在MySQL Server启动之后动态开关、自动创建
mysql-bin.*(binlog):二进制日志,用于复制架构中的数据同步(从库I/O线程从主库读取),MySQL Server中涉及数据变更的SQL语句都会被记录,可以指定单个文件的大小,写满指定大小的文件之后自动切换到一个新文件
mysql-relay-bin.*(relay log):中继日志,用于复制架构中的数据同步(从库I/O线程从主库读取binlog之后写入自身的中继日志中)
slow-query.log(slow log):慢查询日志,SQL语句的执行时间超过指定时间,被认为执行缓慢,会被记录到该文件中
其他文件
mysql.pid(pid):MySQL Server启动之后存放进程号的文件
mysql.sock(socket):MySQL Server启动之后用于本地UNIX Domain通信的sock文件
mysql.sock.lock(socket lock):MySQL Server启动之后用于锁定本地socket文件的锁标记文件。这是MySQL 5.7.x版本中新增的,如果MySQL Server非正常关闭,该文件可能残留而导致MySQL重新启动失败,删除该文件重新启动即可
MySQL Server体系结构
Connectors(连接者):指的是不同语言中与SQL的交互,目前流行的语言都支持MySQL客户端连接
Connection Pool(连接池):管理缓冲用户连接、线程处理等需要缓存的需求在这里也会进行用户账号、密码和库表权限验证
SQL Interface(SQL接口):接收用户执行的SQL语句,并返回查询的结果
Parser(查询解析器):SQL语句被传递到解析器时会进行验证和解析(解析成MySQL认识的语法,查询什么表、什么字段)解析器是由Lex和YACC实现的,是一个很长的脚本其主要功能是将SQL语句分解成数据结构,并将这个结构传递到后续步骤中,后续SQL语句的传递和处理就是基于这个结构的如果在分解构成中遇到错误,则说明该SQL语句可能有语法错误或者不合理
Optimizer(查询优化器):在查询之前,SQL语句会使用查询优化器对查询进行优化(生成查询路径树,并选举一条最优的查询路径)它使用“选取—投影—连接”策略进行查询
Caches& Buffers(缓存&缓冲):主要包含QC以及表缓存、权限缓存等对于QC,以往主要用于MyISAM存储引擎,目前在MySQL 8.0中已放弃,对于现在非常流行的InnoDB存储引擎来讲,QC已无任何意义,因为InnoDB存储引擎有自己的且非常完善的缓存功能除QC之外(记录缓存、key缓存,可使用参数单独关闭),该缓存机制还包括表缓存和权限缓存等,这些是属于Server层的功能,其他存储引擎仍需要使用
Pluggable Storage Engines(插件式存储引擎):存储引擎是MySQL中具体的与文件打交道的子系统,也是MySQL最具特色的一个地方MySQL的存储引擎是插件式的,它根据MySQL AB公司提供的文件访问层的一个抽象接口来定制一种文件访问机制(这种访问机制就叫存储引擎)目前存储引擎众多,且它们的优势各不相同,现在最常用于OLTP场景的是InnoDB(当然也支持OLAP存储引擎,但MySQL自身的机制并不擅长OLAP场景)
Files& Logs(磁盘物理文件):包含MySQL的各个引擎的数据、索引的文件,以及redo log、undo log、binary log、error log、query log、slow log等各种日志文件
File System(文件系统):对存储设备的空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统它负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取常见的文件系统包括XFS、NTFS、EXT4、EXT3、NFS等,通常数据库服务器使用的磁盘建议用XFS
MySQL前台线程
compress_gtid_table(GTID压缩线程):用于压缩MySQL 5.7新增的mysql.gtid_executed表中的GTID记录数量。在MySQL 5.7版本中,当从库关闭log-bin或者log_slave_ updates参数之后,SQL线程每应用一个事务就会实时更新一次mysql.gtid_executed表(在MySQL 5.7中启用GTID复制时可以关闭log_slave_updates参数,使用该表来记录GTID。但在MySQL 5.6中由于没有此表,所以不能关闭log_slave_updates参数),时间一长,该表中就会存在大量的GTID记录(每个事务一行),使用该线程可以把多行记录压缩成一行。
one_connection(用户连接线程):用于处理用户请求的线程
slave_io(I/O线程):用于拉取主库binlog日志的线程
slave_sql(SQL线程):用于应用从主库拉取的binlog日志的线程。注意:在多线程复制中,该线程为协调器线程,用于分发binlog日志给工作线程(slave_worker)应用,并对多个工作线程进行协调
slave_worker(工作线程):在多线程复制场景中,接收并应用SQL线程(slave_sql)分发的主库binlog日志,多个工作线程之间的一致性依靠SQL线程(slave_sql)进行协调
InnoDB存储引擎体系结构
内存结构
Buffer Pool:缓冲池是InnoDB在启动时分配的一个内存区域,用于InnoDB在访问数据时缓存表和索引数据。利用缓冲池,可以合并一些对经常访问的数据的操作,直接从内存中处理,加快了处理速度。通常,在专用数据库服务器上,可以将80%的物理内存分配给InnoDB缓冲池。为了提高缓存管理的效率,使用页面链表的方式+LRU(最近最少使用)算法进行管理
Change Buffer(Insert buffer part of buffer pool):这是一种特殊的数据结构(早期只支持INSERT操作的缓冲,所以也叫作Insert Buffer),当受影响的页面不在缓冲池中时,将会缓存对辅助索引页的更改。这些更改可能是由INSERT、UPDATE、DELETE(DML)语句执行时所导致的,当其他读取操作从磁盘中加载数据页时,如果这些数据页包含Change Buffer中缓存的更改操作页,那么将进行合并操作
Adaptive Hash Index:自适应哈希索引(AHI),用于管理缓冲池中的内部数据结构,并对缓冲池中的相关工作负载和内存操作组合进行自动调节,且不会牺牲任何事务功能、性能和可靠性
Log Buffer(Redo Log Buffer):重做日志缓冲区是用于保存将要写入重做日志磁盘文件中的数据的内存缓冲区域。重做日志缓冲区的大小由innodb_log_buffer_size配置参数定义。重做日志缓冲区中的内容会定期刷新到磁盘上的日志文件中。更大的重做日志缓冲区允许运行更大的事务,这在一定程度上避免提交大事务之前需要将重做日志写入磁盘中。因此,如果在应用场景中经常有大事务,则可以考虑增大重做日志缓冲区以减少磁盘I/O操作。innodb_flush_log_at_trx_commit参数控制如何将重做日志缓冲区的内容写入日志文件中(例如,设置为1时,每个事务提交时都需要执行一次将重做日志缓冲区的内容写入日志文件中)。innodb_flush_log_at_timeout参数控制重做日志的刷新频率
磁盘结构
System Tablespace:InnoDB系统表空间包含InnoDB数据字典(InnoDB相关对象的元数据)、Doublewrite Buffer、Change Buffer磁盘部分和Undo Logs,还包含在系统表空间中创建的任何表和索引数据。它之所以被称为系统表空间,是因为它可以被多个用户表共享。系统表空间可以由一个或多个数据文件构成。在默认情况下,只会创建一个名为ibdata1的共享表空间文件。但可以使用innodb_data_file_path启动选项控制共享表空间的数量和大小
Data Dictionary(InnoDB Data Dictionary):InnoDB数据字典由内部系统表组成,这些系统表包含用于跟踪对象(如表、索引和表列)的元数据。元数据存放在InnoDB系统表空间中。由于历史原因,数据字典元数据在一定程度上与存储在InnoDB表的.frm文件中的信息重叠
Doublewrite Buffer:双写缓冲区是一个位于系统表空间的存储区域,InnoDB在进行刷脏操作时,在将脏数据写入数据文件中的正确位置之前先把脏页从InnoDB缓冲池写入双写缓冲区中。只有将脏页成功写入并落盘到ibdata1共享表空间中的双写缓冲区之后,InnoDB才能将脏页从缓冲池中写入数据文件中的正确位置。如果操作系统、存储子系统或mysqld进程在刷新脏页过程中发生崩溃,那么可能发生部分写(InnoDB默认的页大小为16KB,而文件系统默认的块大小为4KB,如果InnoDB的一个页在写入磁盘过程中发生异常,则可能导致数据页只写入了一部分到磁盘中),InnoDB在重新启动时的崩溃恢复期间从双写缓冲区中找到正确的页面副本进行覆盖恢复。虽然双写会导致脏页被两次写入磁盘中,但双写缓冲区不需要两倍的I/O开销或两倍的I/O操作。因为脏页在双写时是以一次1MB,作为一个大的顺序块被写入双写缓冲区中,并执行一次fsync()调用的。另外,如果系统表空间文件(ibdata文件)被存放在支持原子写入的Fusion-io设备上,则会自动禁用双写缓冲区功能,并将Fusion-io原子写入功能用于所有的数据文件。注意:由于双写缓冲区设置参数(innodb_doublewrite)是全局的,因此对于存放在非Fusion-io设备上的数据文件,也会禁用双写缓冲区功能(对于这部分数据文件可能造成部分写)。所以,原子写功能仅在Fusion-io设备上且在Linux中启用了Fusion-io NVMFS时生效。要充分使用该功能,建议将innodb_flush_method参数设置为O_DIRECT
Undo Logs:用于存放事务修改之前的旧数据(undo log记录了有关如何撤销事务对聚集索引记录的最新更改的信息),基于undo实现了MVCC和一致性非锁定读。InnoDB总共支持128个回滚段,每个回滚段有1023个事务槽位,在并行事务场景中一个事务槽位对应一个事务。其中32个回滚段位于临时表空间(Temporary Tablespace),也就是说,对临时表操作的最大并行事务数大约为32×1023个;96个回滚段位于非临时表空间(系统表空间至少一个,因为MySQL 5.7新增的在线undo truncate功能需要,Undo Tablespace最多95个),也就是说,对非临时表操作的最大并行事务数大约为96×1023个
File-Per-Table Tablespaces:设置参数innodb_file_per_table=1启用独立表空间时,每个表都会对应生成一个.ibd文件用于存放自己的索引和数据等;否则,在创建表时数据和索引将被存放在ibdata系统表空间文件中(系统表空间)
General Tablespaces:常规表空间,在datadir路径下使用CREATE TABLESPACE语法创建的InnoDB共享表空间(tablespace_name.ibd)。可以在MySQL datadir之外创建,能够保存多个表,并支持所有行格式的表。使用CREATE TABLE tbl_name ... TABLESPACE [=] tablespace_name或ALTER TABLE tbl_name TABLESPACE [=] tablespace_name语法将表添加到常规表空间中,该功能是MySQL 5.7新增的
Undo Tablespace:undo表空间,包含一个或多个undo log文件,文件个数由配置参数innodb_undo_tablespaces控制
Temporary Tablespace:临时表空间用于存放非压缩的InnoDB临时表和相关对象。配置参数innodb_temp_data_file_path为临时表空间的数据文件定义了相对路径和初始大小等。如果未设置innodb_temp_data_file_path参数,则会在数据目录中创建一个名为ibtmp1的自动扩展的12MB初始大小的文件。临时表空间文件在服务器每次重启时都会重新创建(正常停止或终止初始化时会自动删除,但发生崩溃时不会自动删除),并使用动态生成的空间标识ID来避免与现有空间标识ID冲突。另外,在INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO表中可以查看有关InnoDB临时表的元数据(可以看到InnoDB实例中处于活动状态的所有用户和系统创建的临时表)。注意:如果无法创建临时表空间,则Server将启动失败。该功能是MySQL 5.7新增的
Redo Logs:重做日志是在崩溃恢复期间使用的基于磁盘的数据结构文件,用于恢复不完整提交事务写入的数据。在MySQL实例正常运行期间,重做日志对事务产生的数据变更部分进行编码并持久化到磁盘中(重做日志中的数据就是对受影响的行记录进行编码,利用这些编码数据把事务进行前滚的操作就叫作重做)。在默认情况下,重做日志在磁盘中创建一组名为ib_logfile0和ib_logfile1的文件。MySQL以循环滚动方式写入重做日志文件,并使用一个不断增加的LSN值表示重做日志的写入量,以及标记写入重做日志文件中的位置。根据WAL(Write-Ahead Logging,日志先行)原则,在提交事务时会先使用redo log持久化事务发生修改的部分数据(只要redo log落盘并打上commit标记就表示事务已经持久化)
Mysqlz中的存储引擎
CSV
MRG_MYISAM
MEMORY
BLACKHOLE
SPHINX
TokuDB
ARCHIVE
MyISAM
PERFORMANCE_SCHEMA
FEDERATED
InnoDB
MRG_MYISAM
MEMORY
BLACKHOLE
SPHINX
TokuDB
ARCHIVE
MyISAM
PERFORMANCE_SCHEMA
FEDERATED
InnoDB
InnoDB存储引擎后台线程
srv_master_thread(主线程):InnoDB存储引擎主线程,由4个循环组成,即主循环(loop)、后台循环(background loop)、刷新循环(flush loop)、暂停循环(suspend loop),其中大多数工作都在主循环中完成,主循环主要负责将脏缓存页刷新到数据文件中,执行undo purge操作,触发检查点,合并插入缓冲区,刷新redo log到磁盘中等
io_ibuf_thread(插入缓冲线程):主要负责插入缓冲区的合并操作。将对辅助索引页的修改操作从随机变成顺序I/O,大幅度提升了效率(会先判断发生修改的辅助索引页是否在缓冲池中,如果在则直接修改;如果不在,则先存放在一个Change Buffer对象中。当其他读取操作把该修改对应的页从磁盘读取到缓冲池中时,就会合并该Change Buffer对象中保存的记录到辅助索引页中)
io_read_thread(读I/O操作线程):负责数据库的AIO(异步I/O)读取操作,可以配置多个读线程,由参数innodb_read_io_threads设置,默认值为4
io_write_thread(写I/O操作线程):负责数据库的AIO写操作,可配置多个写线程,由参数innodb_write_io_threads设置,默认值为4
io_log_thread(日志线程):用于将重做日志刷新到日志文件中
srv_purge_thread(undo清理线程):主要负责undo页清理操作,在MySQL 5.6之后可设置独立的线程执行undo purge操作,以减少主线程负载
srv_lock_timeout_thread(锁线程):负责锁控制和死锁检测等
srv_error_monitor_thread(错误监控线程),主要负责错误控制和错误处理
page_cleaner_thread(脏页清理线程):负责刷脏操作在MySQL 5.6之后可设置独立的线程执行刷脏操作,以减少主线程负载刷脏分为两种方式,其中一种是基于LRU list(最近最少访问的列表)的最近访问时间顺序刷新的;另一种是基于flush list(刷新列表)的最近修改时间和LSN值的顺序刷新的
thread_timer_notifier(计时器过期通知线程):超过计时器时间,通知线程处理一般在超过MAX_EXECUTION_TIME时自动中止SQL语句的执行
main(主线程):MySQL服务的主线程(请与InnoDB存储引擎主线程区别开),包括初始化、读取配置文件等功能
srv_monitor_thread(InnoDB监控打印线程):如果开启了InnoDB监控器,那么每隔5秒打印一次InnoDB监视器采集的信息
srv_worker_thread(InnoDB工作线程):InnoDB的实际工作线程,轮询从任务队列中取出任务(row select、row insert等)并执行
buf_dump_thread(InnoDB缓冲池导入/导出线程):InnoDB缓冲池热点数据页导入/导出的线程
dict_stats_thread(InnoDB后台统计线程):负责InnoDB表统计信息更新的后台线程
signal_handler(信号处理线程):负责SIGTERM、SIGQUIT、SIGHUP信号处理的线程
收藏
收藏
0 条评论
下一页