MySQL原理
MySQL的底层原理浅析
一、连接阶段
本地连接
在生产环境中,往往采用数据库和项目一同部署在同一服务器上,这种方式采用的连接则是本地连接。 而又因为生产服务器大都是Linux或者Unix服务器, 本地连接的通常是Unix套接字连接。 这种方式不需要发送网络请求,也不收网络请求限制。
网络连接
网络连接这种常出现在开发环境,多个开发者共用一个数据库,通过远程连接内网或外网的形式访问。 这种方式实现是基于TCP/IP协议访问,进行ACK标志多次握手构建长连接请求。
身份验证
校验链接地址中配置的账号密码是否正确
开发人员需要关注的细节
- 最大连接数
-- 查看当前链接数 -- SHOW STATUS LIKE 'Threads_connected'; -- 查看最大链接容量数 -- SHOW VARIABLES LIKE 'max_connections'; -- 单个连接消耗的内存大小 -- 此值不可过大,也不可过小,过小会造成复杂查询无法实现,过大会导致并发时消耗大量内存 SHOW VARIABLES LIKE 'thread_stack'此处应满足当前连接数小于最大链接容量,不然就超出了最大连接数
- 连接池
常见连接池有HikariCP(SpringBoot)、C3P0(老项目)、Druid(阿里巴巴开源)
- 最大连接数
在SQL解析前,会有一层缓存层,如若命中缓存层,则会直接跳过解析,优化以及执行阶段
- 在 MySQL 8以前是默认开启的,在8版本之后默认是关闭的
- 查看缓存是否开启
SHOW VARIABLES LIKE '%query_cache',结果为YES开启反之关闭- 缓存在表进行了更新(增删改)操作后失效
- 若当前SQL与缓存SQL字符不一也不会命中,特别的,注释不一样也不会命中
- 每条SQL解析前都会去查找缓存
解析阶段
- 词法分析:将SQL语句分解成一系列的词法单元(tokens)比如识别查询语句SELECT为关键字,account为表名
- 语法分析:检查这些词法单元是否符合SQL语言的语法规则,例如语法不对则抛出
You have an error in your SQL syntax的报错
优化阶段
查询优化器
- 正常来说,一条sql往往有着多种执行方式,查询优化器的作用就是在诸多方式中选择其认为最优的查询方法
- 首先是索引的选择,优化器会根据索引选择它认为最优的索引
- 其次是表的重新组合,这部分常常是SQL优化的关键,通过一些技巧可以让表的组合指定
生成执行计划
执行阶段
一条查询SQL的执行过程
FROM->ON->JOIN->WHERE->GROUP BY- ->
HAVING->SELECT->DISTINCT->ORDER BY->LIMIT
返回结果阶段
日志记录阶段
- 二进制日志
- binLog 二进制日志
- 是把对数据库操作有变更的操作都记录到日志来,即有增删改都会被记录到binLog日志中。
- binLog 通常是作为数据恢复和主从同步的关键
- 数据恢复 使用mysqlbinlog工具来恢复
- 主从同步 主节点开启binlog,从节点只需要根据主节点的binlog重放即可同步数据
- binlog 通常有三种格式:ROW,STATEMENT,MIXED
在MySQL5.7以前默认的格式为STATEMENT,之后则是默认展示ROW格式的
ROW模式:记录被修改数据行数,不记录SQL语句的上下文信息(即SQL语句)STATEMENT: 对进行增删改的每条SQL都进行记录MIXED:以STATEMENT为主,ROW为辅,在多数情况下用前者记录,只有遇到一些无法记录的函数用ROW记录- 三种模式总结
ROW: 虽然能够详细记录那些行受影响,并且在重放或者恢复的时候保证数据的一致性, 但是如果是一条SQL更新五十行的时候就会出现50条日志,会造成大量的空间浪费和性能问题
STATEMENT虽然性能和IO都比较优秀,但是一条SQL执行会取决于前面的时间,数据变化而导致在出现问题需要重复的时候会出现不一致的问题
MIXED虽然糅合了ROW和STATEMENT,但是仍然会出现像STATEMENT一样的造成数据不一致的问题
binLog 写入策略
首先我们肯定希望在日志写入的时候能保证有效和准确性, 因为在之后的故障恢复时或者日志查看时都能提供有力的保证,同时也需要考虑写入日志到磁盘时对数据库的性能效率考量。对于
Innodb引擎来说,日志不是直接写入磁盘的,通常是先放入binLog Cache中,找合适时机再写入磁盘中。
通过sync_binlog参数来控制实际binLog的刷盘时机。取值为0到N- 如果 sync_binlog 为0,那么每次提交事务并不会立马刷入盘中,而是先存入 Page Cache 中,由系统判断何时刷入盘中
- 如果 sync_binlog 为1,那么每次事务提交之后都会立马写入到磁盘中,此为强一致性配置
- 如果 sync_binlog 为N, 那么每次事务提交之后 都会在积累的个数达到了N个事务才会刷入磁盘
- redoLog
- undoLog
- binLog 二进制日志
- 慢查询日志