MySQL架构
- 目前主流的架构大致如下,各种封装的客户端连接到MySQL连接池,账户密码式登录。
- SQL语句经过优化器优化后被执行器执行,并调用存储引擎获取数据。
- 主流的存储引擎基本都是InnoDB,虽然也还有MyISAM和Memory等其他存储引擎,但基本现在建表都不用了。
- 具体的数据、索引以文件形式存储在磁盘中;执行过程会生成日志文件,并依靠日志系统实现事务执行等其他功能。
MySQL锁类型
从数据层面划分
- 表锁
- 行锁
从功能划分
-
共享锁
-
共享锁即读锁
-
排他锁即写锁
delete/update/insert语句会自动加上排它锁。 手动加排他锁 select * from student where id=1 FOR UPDATE;
加锁场景
-
哪些场景下我们的MySQL会对表进行加锁?
-
为表创建索引时会锁表。所以对于线上生产环境,加索引的时机需要选好,并且大表加索引需要慎重,防止锁表造成线上生产事故。
加锁机制
MySQL事务实现原理
MySQL事务的特征
- Atom 原子性
- Consistent 一致性
- Isolation 隔离性
- Durability 持久性
事务隔离级别
| 隔离级别 | 描述 |
|---|---|
| Read-Uncommit | 读未提交 |
| Read-Committed | 读已提交 |
| Replicate Read | 可重复读 |
| Serialize | 串行执行 |
日志系统
-
redo log
- redo log 记录事务执行成功后的值,并持久化,当事务执行失败,需要恢复数据时,只需要将redo log中的记录重新执行就能恢复正确数据。所以redo log保证事务的持久性。
-
undo log
- undo log 可以理解为事务提交前会在undo log中先写入一条对应的回滚SQL,当事务需要回滚时直接执行回滚SQL。因此undo log保证事务的原子性,即操作要么成功要么失败并回滚到最初状态。
-
bin log
- 利用binlog恢复数据。
赃读
- 两个事务,其中一个事务读取了另外一个事务未提交的数据
幻读
- 同一个事务,读取同一记录两次,两次结果不一样
- 如何解决幻读问题:事务读取的时候,不允许更新数据
不可重复读
-
一个事务在读取某些数据时,数据已经发生了变化,或者已经被删除了,这种现象就叫不可重复读。
-
用哪些锁去解决上述问题
MVCC
-
InnsoDB在每行记录后面保存两个隐藏的列,分别保存了这个行的创建时间和行的删除时间。这里存储的并不是实际的时间值,而是系统版本号,当数据被修改时,版本号+1。
-
在读取事务开始时,系统会给当前读事务一个版本号,事务会读取版本号<=当前版本号的数据,此时如果其他写事务修改了这条数据,那么这条数据的版本号+1,从而比当前读事务的版本号高,读事务自然就读不到更新后的数据了。
索引类型
- 索引类型
- 唯一索引
- 普通单值索引
- 联合索引
- 组合索引
- 聚簇索引
- 全文索引
- 二级索引
索引数据结构的选型逻辑
-
HashTable
- 内存存储引擎
-
B Tree/B+ Tree
- B+树与B树的区别是B+树的非叶子节点不存储数据,而B树会存储实际数据,
索引构建流程
索引优化案例
-
最左前缀匹配原理
-
全文索引优化like
-
从Spring Transaction 到MySQL的事务过程