依然使用InnoDB引擎
一、Server层
1. 连接器:连接建立后的权限变更不会对原有连接起作用,重新建立连接后才生效;show processlist命令可以查看系统中的连接,Command列为Sleep的连接为空闲连接;长时间没有动静(默认8小时,参数wait_timeout控制),连接会自动断开;数据库连接使用长连接有个问题就是,数据库操作使用的临时内存是存在连接对象中,只有连接断开后才释放,目前数据库连接池(如druid)已经通过设置无效连接判断等配置方法解决此问题。
2. 查询缓存:不建议使用,因为查询缓存弊大于利,而且MySQL8.0开始已经废弃这个功能
3. 分析器:词法分析和语法分析
4. 优化器:如对使用哪个索引进行选择,如表关联时决定各个表的连接顺序
5. 执行器:先判断是否有权限,然后再执行操作
二、InnoDB存储引擎层:磁盘文件结构包括表空间文件和redo log,内存结构包括缓冲池和日志缓冲区redo log
1. 表空间文件包含系统表空间(数据字典、双写缓冲区、修改缓冲区、回滚段undo logs、索引段)和用户表空间(每个表对应一个用户表空间,存放当前表数据和索引)
2. redo log:是一组大小固定且能循环使用的一组文件
3. 缓冲池:数据页:磁盘上的数据在内存中的备份;索引页:磁盘上的索引在内存中的备份;数据字典:表、索引、外键等对象的定义;undo log缓冲区:记录回滚日志
4. InnoDB逻辑存储结构解读
用户表空间:存有数据和索引,这些数据以段的形式存储在文件中,有叶节点段(数据段)、非叶节点段(索引段)、回滚段
段:每一个段又分成多个区
区:每个区由64个页组成,一个页默认大小为16K,区大小为1M;为了保证区中页的连续性,区扩展时,InnoDB会一次性从磁盘中申请4~5个区
页:每个页又有多条记录组成,InnoDB中每个页的默认大小为16KB,是InnoDB读写数据的基本单位
记录:存有具体数据,如有列字段、回滚指针和事务ID
5. InnoDB内存结构:数据新增或修改操作,先写入到redo log buffer,再写入到buffer pool中,然后再写入到redo log文件,提交事务。脏页落盘是根据checkpoint执行的。
Buffer Pool:数据页(data page)和索引页(index page)在内存中使用的数据淘汰策略都是LRU算法;insert buffer page后面改名为change buffer page,修改缓冲区,对要插入或修改的数据暂存在修改缓冲区中,等积累到一定数量再刷新到磁盘,这样就减少了IO操作,也利于提高维护辅助索引性能;锁信息(lock info)为了支持对共享资源进行并发访问,提供数据的完整性和一致性;数据字典(data dictionary)存放的是表定义和索引信息,避免每次使用时都重新在磁盘读取;自适应哈希索引(adaptive hash index),对某些满足创建自适应哈希索引条件的查询语句,MySQL会自动创建自适应哈希索引指向相应的数据页,提高查询效率。
double write:执行checkpoint之后,脏页需要落盘,会先将数据先写入双写缓冲区,然后再写入系统表空间一份作为备份,再写入用户表空间,这样是防止写入用户表空间时系统出问题时,可以使用系统表空间的备份数据再进行数据页中脏数据落盘。
注意:double write和redo log没关系,double write是保证脏页可以正常写入用户表空间,如果整个double write出错,脏页数据丢失,只能依赖redo log来恢复数据了
redo log buffer:主要是提高写入redo log文件性能,先写入redo log buffer再写入redo log文件,减少IO操作;只有写入redo log文件的数据才算成功;当插入或修改数据时,先写入redo log buffer,然后再写入change buffer,然后写入redo log文件,数据落盘,提交事务;redo log buffer写入redo log文件的配置由innodb_flush_log_at_trx_commit控制,默认为1,0表示事务提交时,等待主线程每秒按时写入redo log;1表示事务提交时,直接写入redo log文件系统缓存,同时调用fsync,将文件系统缓存中数据写入磁盘,可以保证数据不会丢失;2表示事务提交时,同时写入redo log文件系统缓存,不会调用fsync,而是等待文件系统自己将数据写入磁盘
Additional Memory Pool:已废除。
6. 内存数据(buffer pool中数据)落盘:当对数据进行插入或修改后,虽然写入了redo log,同时也修改了buffer pool中的相关缓存数据,造成内存中数据和磁盘中数据不一致,称内存中数据为脏页。脏页落盘,依赖于checkpoint自动执行,其执行时机如下:
sharp checkpoint:关闭数据库时,执行强制落盘。
fuzzy checkopoint:数据库运行中进行落盘,其落盘时机如下
1)、根据一定时间频率,默认10秒,对部分脏页数据进行落盘
2)、当buffer pool中数据写满,进行LRU算法清理数据时,会优先对要清理的脏页数据进行落盘
3)、脏页过多,达到innodb_max_dirty_pages_pct配置的阈值时,默认90,即buffer pool的90%,就会执行脏页落盘
4)、当redo log写满时,也会对脏页进行落盘,以便重用redo log空间
脏页落盘后就需要对redo log中的数据进行相应处理,分为异步落盘和同步落盘,具体操作根据同步(sync_water_mark=90%*innodb_log_file_size)或异步(async_water_mark=75%*innodb_log_file_size)操作标准值和checkpooint_age进行比较来确定。checkpoint_age=redolog_lsn - checkpoint_lsn,lsn(Log Sequence Number)表示日志版本号,redo log和buffer pool是可以通过lsn进行关联的,这样脏页落盘后,可以根据lsn来判断redo log中的哪些数据可以被覆盖。不管是同步还是异步flush checkpoint,都不会阻塞用户查询进程
1)、当checkpoint_age < async_water_mark时,即redo log剩余空间超过25%时无需执行flush checkpoint;
2)、当async_water_mark < checkpoint_age < async_water_mark时,执行异步 flush checkpoint,直到满足checkpoint_age < async_water_mark
3)、当checkpoint_age > async_water_mark时,执行同步flush checkpoint,直到满足checkpoint_age < async_water_mark