说一下MySQL的基础架构?
包括连接层、服务层和存储引擎层
- 连接层主要负责管理客户端的连接,包括用户认证,权限管理、连接管理等。可以通过数据库连接池来提升连接的处理效率。
- 服务层是MySQL的核心,负责SQL查询的解析、优化等操作。解析优化完成后会转发到存储引擎层执行。这一层包括解析器、优化器(包括执行计划生成器)、执行器,binlog模块等。
- 存储引擎层负责数据实际的存储和提取。
binlog写入在哪一层?
在服务层,负责记录导致数据变化的事件,记录了所有对数据库进行更改的操作,用于数据恢复、主从复制等。
一条查询语句是如何被执行的?
一条SQL语句需要经过解析和优化,然后在数据引擎层中实际执行,最后返回结果
- 客户端发送SQL语句到MySQL服务器。
- 连接器开始处理这个请求,跟客户端验证连接权限、建立连接、管理连接。
- 解析器对SQL语句进行解析,进行词法分析、语法分析和语义分析,并进行操作权限验证。
- 优化器负责确定SQL语句的执行计划,包括选择索引,以及确定表之间的连接顺序等。
- 执行器调用存储引擎的API进行实际的数据查询。
- 存储引擎负责查询数据,并将执行结果返回给执行器,执行器再返回给客户端。
一条更新语句是如何执行的?
和查询语句一样,都要经过连接器、解析器、优化器和执行器,重点差异在于存储引擎里,存储引擎通过WHERE语句定位到要更新的行并返回给执行器,执行器修改这一行之后再调用存储引擎的API更新这一行。存储引擎的具体执行流程为:
- 查找数据:通过WHERE语句定位要更新的行
- 加锁:对要更新的行加写锁
- 写入undo log:记录旧值(a的原始值)用于事务回滚
- 写入数据:更新内存中的数据页,标记为脏页,此时数据仍然在内存的 buffer pool 中,不会立即写入磁盘。后台线程会在适当的时候将脏页刷盘,以提高性能。
- 写入redo log:事务状态为prepare,用于崩溃恢复
- 写入binlog:记录逻辑操作,用于主从复制
- 提交事务:redo log将事务状态改为commit,释放锁
说说MySQL的段区页行
MySQL以表的形式存储数据,而表空间的结构又可以分为段、区、页、行。
- 段:表空间划分为多个段,不同类型的数据逻辑分离,包括数据段(叶子节点段),索引段(非叶子节点段)和回滚段(旧数据用于回滚)
- 区:每个段可以分为多个区,区是一组连续的页,通常一个区包含64个页,也就是1M。使用区可以优化空间分配,减少频繁的空间申请开销,减少磁盘碎片,提升顺序I/O性能。
- 页:读写数据的基本单元,一页为16KB,意味着每次读写都是以16KB为单位,以优化I/O效率,避免每读一行都要一次磁盘I/O。索引树上的一个节点就是一个页
- 行:应用逻辑的最小单位,InnoDB采用行存储方式,数据按照行进行组织和管理,行有不同的格式,MySQL默认是DYNAMIC,意味着单行数据如果超过了页大小的一半,则会被存储在溢出页中,原页中保留20字节的指针。