Mysql架构相关整理
1. Mysql整体架构
1. Connectors
连接器,例如JDBC。
2. Manageement Services & Utilities
系统管理和控制工具。
3. Connection Pool
mysql连接池,接收请求,建立连接。
4. Sql Interface
SQL接口 接受用户命令,执行后续操作,并且返回SQL的操作结果。
5. Parse
解析器,解析验证sql,若是错误sql将在次层直接返回,并sql语句解析为语法树。
6. Optimizer
sql查询优化器,explain就是此层处理的结果。
7. Cache Buffer
查询缓存,缓存用户查询结果集,与sql的hash值组成key,value形式储存在缓存中。
8. Pluggable Storage Engines
存储引擎,负责数据的处理。
2. Mysql层级
1. Mysql server层
一条select语句执行流程整理。
1)连接器
管理连接,权限验证等操作。
2)查询缓存–OR—分析器
若是存在缓存直接使用缓存中的结果返回数据。
不存在缓存则需要分析器执行 词法分析、语法分析,形成语法树进行后续流程。
注:查询缓存在8.0版本已经移除,因为它失效频繁,利大于弊。
3)优化器
优化查询sql,生成执行计划,选择索引。
1. 索引选择。
2. join时各个表的连接顺序。
4)执行器
1. 判断是否具有查询权限。
2. 有权限就调用储存引擎接口。
2. Mysql 储存引擎层
1)MyISAM
查询,插入速度高,不支持事务。
2)InnoDB
支持事务,行级锁,稍慢于 MyISAM 。
3)Memory
内存存储引擎,拥有极高的插入,更新和查询效率,重启丢失。
3. InnoDB引擎架构
1. 磁盘文件
1)重做日志文件 redo log
当InnoDB的数据存储文件发生错误时,重做日志文件就能派上用场。保证数据库数据的完整性。
用户可以使用innodb_log_file_size来设置重做日志文件的大小,这对InnoDB存储引擎的性能有着非常
大的影响。
如果重做日志文件设置的太大,数据丢失时,恢复时可能需要很长的时间;
另一方面,如果设置的太小,重做日志文件太小会导致依据checkpoint的检查需要频繁刷新脏页
到磁盘中,导致性能的抖动。
2)系统表空间,用户表空间
-
系统表空间(ibdata1)
用户可以使用 innodb_data_file_path 对数据文件的大小和数量进行配置。
- InnoDB数据字典(元数据以及相关对象)。
- double write buffer
- change buffer
- undo logs
- 用户在系统表空间创建的表数据和索引数据。
-
用户表空间
用户表空间只存储该表的数据、索引信息,其余信息还是存放在默认的系统表空间中
3) InnoDB逻辑存储解构
- 表空间
- 独占表空间
- 通用表空间
- 临时表空间
- Undo表空间
- 段
- 数据段
- 索引段
- 回滚段
- 区 64个连续的页组成 1M
- 页 一页16K,InnoDB IO的最小单位
- 行
2. InnoDB内存结构
1)Buffer Pool
缓冲池的大小直接影响着数据库的整体性能,可以通过配置参数 innodb_buffer_pool_size 来设置
- 索引页
- 数据页
- undo页
- 插入缓冲(insert buffer)、
- 自适应哈希索引(adaptive hash index)
- InnoDB存储的锁信息(lock info)
- 数据字典信息(data dictionary)
2)Addtional memory pool
额外内存池是InnoDB存储引擎用来存放数据字典信息以及一些内部数据结构的内存空间
3)Redo log Buffer
innodb_flush_log_at_trx_commit 三种落盘模式
- 事务提交时,不会对重做日志进行写入操作,而是等待主线程按时写入每秒写入一次;
- 事务提交时,会将重做日志写入操作系统缓存,并且调用操作系统的fsync,将操作系统缓冲中的数据真正写入磁盘存储,确保不会出现数据丢失
- 事务提交时,也会将日志文件写入操作系统缓存,但是不会调用fsync,而是让操作系统自己去判断何时将缓存写入磁盘。
4)CheckPoint检查点机制
① 作用
- 缩短数据库的恢复时间。
- 缓冲池不够用时,将脏页刷新到磁盘。
- 重做日志不可用时,刷新脏页。
当数据库发生宕机时,数据库不需要重做所有的日志,因为Checkpoint之前的页都已经刷新回磁盘。数据库只需对Checkpoint后的重做日志进行恢复,这样就大大缩短了恢复的时间。
当缓冲池不够用时,根据LRU算法会溢出最近最少使用的页,若此页为脏页,那么需要强制执行Checkpoint,将脏页也就是页的新版本刷回磁盘。
当重做日志出现不可用时,因为当前事务数据库系统对重做日志的设计都是循环使用的,并不是让其无限增大的。重做日志可以被重用的部分是指这些重做日志已经不再需要,当数据库发生宕机时,数据库恢复操作不需要这部分的重做日志,因此这部分就可以被覆盖重用。如果重做日志还需要使用,那么必须强制Checkpoint,将缓冲池中的页至少刷新到当前重做日志的位置。
② 分类
-
Sharp Checkpoint
在关闭数据库的时候,将buffer pool中的脏页全部刷新到磁盘中。
-
Fuzzy Checkpoint
数据库正常运行时,在不同的时机,将部分脏页写入磁盘。仅刷新部分脏页到磁盘,也是为了避免一次刷新全部的脏页造成的性能问题。
-
Master Thread Checkpoint
在Master Thread中,会以每秒或者每10秒一次的频率,将部分脏页从内存中刷新到磁盘,这个过程是异步的。正常的用户线程对数据的操作不会被阻塞。
-
FLUSH_LRU_LIST Checkpoint
在单独的page cleaner线程中执行,MySQL对缓存的管理是通过buffer pool中的LRU列表实现的,LRU 空闲列表中要保留一定数量的空闲页面,来保证buffer pool中有足够的空闲页面来相应外界对数据库的请求。当这个空间页面数量不足的时候,发生FLUSH_LRU_LIST checkpoint。
-
Async/Sync Flush Checkpoint
发生在重做日志不可用的时候,将buffer pool中的一部分脏页刷新到磁盘中,在脏页写入磁盘之后,事务对应的重做日志也就可以释放了。
由于磁盘是一种相对较慢的存储设备,内存与磁盘的交互是一个相对较慢的过程由于innodb_log_file_size定义的是一个相对较大的值,正常情况下,由前面两种checkpoint刷新脏页到磁盘,在前面两种checkpoint刷新脏页到磁盘之后,脏页对应的redo log空间随即释放,一般不会发生Async/Sync Flush checkpoint。同时也要意识到,为了避免频繁低发生Async/SyncFlush checkpoint,也应该将innodb_log_file_size配置的相对较大一些。
-
Dirty Page too much Checkpoint
buffer pool中的脏页过多,执行checkpoint脏页刷入磁盘
innodb_max_dirty_pages_pct的默认值是75%。
-
5) Double Write
Double Write由两部分组成,一部分是内存中的double write buffer,大小为2MB,另一部分是物理磁盘上共享表空间连续的128个页,大小也为2MB。
在对缓冲池的脏页进行刷新时,并不直接写磁盘,而是通过memcpy函数将脏页先复制到内存中的double write buffer区域,之后通过double write buffer再分两次,每次1MB顺序地写入共享表空间的物理磁盘上,然后马上调用fsync函数,同步磁盘,避免操作系统缓冲写带来的问题。在完成doublewrite页的写入后,再讲double wirite buffer中的页写入各个表空间文件中。如果操作系统在将页写入磁盘的过程中发生了崩溃,在恢复过程中,InnoDB存储引擎可以从共享表空间中的double write中找到该页的一个副本,将其复制到表空间文件中,再应用重做日志。