思考:Mysql需要重点学习什么:
- 索引:索引存储结构、索引优化......
- 事务:锁机制与隔离级别、日志、
- 集群架构
本文是对Mysql架构进行初步学习
1、Mysql链接
Mysql监听器是长连接 BIO(阻塞同步IO调用), 不是NIO.
为什么这么设计, 因为mysql影响性能的关键是磁盘IO操作而非并发
2、一个mysql查询语句执行过程
Mysql服务器
- Server层:涵盖Mysql大多数核心业务,以及所有内置函数。
- 存储引擎层:负责数据的检索和存储,其架构模式是插件式的,支持InnoDB、MyISAM等多种存储引擎。从Mysql5.5.5InnoDB成为默认存储引擎,也可以在创建表的时候制定存储引擎。
Server
- 客户端:执行sql语句请求,比如navicat工具
- 查询缓存:用处不大,Mysql8.0就去掉了。 变更操作会清空缓存,同时还需要保障缓存和DB的一致性,变更操作可能比较频繁,数据一致性保障对mysql服务性能也有影响,所以用处不大。
- 参数query_cache_type,设置使用缓存的场景
- 0 (OFF)全不使用
- 1(ON)除了显示要求不使用缓存的,其余都走缓存
- 2(DEMOND) 除了显示要求使用缓存的,都不走缓存
- select SQL_CACHE * from user where id=1
- 参数query_cache_type,设置使用缓存的场景
- 连接器:mysql服务部署在服务器上,并开放某个端口(127.0.0.1:3306), 客户端需要和这个端口建立连接,从而实现与mysql服务器的通信。这部分由连接器完成。
- 客户端建立连接后,如果长时间没有动静,连接器就会将它断开。由参数wait_timeout控制,默认8小时。
- 项目中连接数据库一般使用线程池,这样可以复用现有的连接,而不是频繁的创建和销毁他们。
- 分析器:词法分析+语法分析。
- 将sql语句中的关键字识别出来,也会识别出表名、字段名。
- 语法分析就是校验这个sql是否能满足sql语法的规范以及是否能正常执行。
- 优化器:explain 、执行计划 、成本分析 、索引选择 都是在优化器中实现
- 是否使用索引,使用哪个索引
- join语句中, 先查询哪个表(一般先查小表)问题:A join B , A的量比B多, 但是A加了限定条件后比B加了限定条件后数据量少, 这时先查哪个表?
- 执行器:操作引擎,返回结果
- 判断用户有没有表的操作权限。分析器可以做一些初步的校验,但是SQL执行过程中涉及的表可能不止字面上的表,有可能会有触发器这种在运行时才确定的过程, 分析器是不能对这种运行时才确定的表做校验
InnoDB
- Mysql默认的存储引擎,支持事务、行级锁和外键约束。
- InnoDB有自己的日志系统,称作redo log(重做日志)和undo log(撤销日志)。正是因为有日志,所以才支持事务。
- redo log用于保障数据库的持久性,在数据库宕机的时候可以用来恢复日志。
- undo log用来支持事务的原子性和多版本并发控制(MVCC), 可用于在事务需要回滚的时候撤销sql的执行。
2、一个mysql更新语句执行过程
sql执行时如果每次更新都写磁盘, IO成本很高。先写内存日志再写磁盘(预写式日志) 称作WAL技术(Write-Ahead-Logging)
更新与查询流程不一样,更新语句涉及到两个重要日志, redo log(重做日志) 和 binlog(归档日志)。
- redo log是InnoDb引擎带来的。是物理日志,记录的是“在某个数据页修改了什么”。 内存空间有限,循环写, 写满时就写回磁盘。
- binlog是mysql Server自带的。是逻辑日志,记录的这个语句的原始逻辑。追加写,不会覆盖之前的内容。
根据这两个日志,再分析update的执行过程:
(update T set c = c+1 where id = 2;)
- 写redolog和binlog是两个独立的过程, 应该要保障其事务性。Mysql内部使用两阶段提交,保障两份日志的一致性。
- redo log buffer : 是一块内存,commit之前的多条sql语句对应的日志,先写入rodo log buffer, 在commit的时候才把日志真正写入redo log 文件(文件名是ib_logfile+数字)
场景分析1: binlog写完, redolog还没commit时crash, 崩溃恢复的时候Mysql怎么处理?
答:事务可以被提交