(一)InnoDB存储引擎
InnoDB是MySQL最常用的存储引擎之一,有支持事务处理、行级锁定和外键约束等高级功能而著称。
1、InnoDB架构
物理结构
表空间:InnoDB的数据存储空间在表空间中,表空间可以分为系统表空间、文件表空间和通用表空间。
-
系统表空间:默认存储在
ibdata1
文件中,包含系统表、数据字典、回滚段等。 -
文件表空间:每个表对应一个
.ibd
文件,存储表的数据和索引。 -
通用表结构:可以包含多个表的数据和索引。
逻辑结构
-
表(Table):逻辑上的数据集合。
-
索引(Index):用于加速数据检索。
-
页(Page):InnoDB的最小存储单位,默认大小是16KB。
-
区(Extent):包含64个连续的页,大小为1MB。
-
段(Segment):由多个区(Extent)组成,每个区包含64个连续的页。
2、数据存储
表结构
-
数据行(Row):每行数据包含多个字段,每个字段有固有的或可变的长度。
-
聚簇索引(Clustered Index):InnoDB使用聚簇索引存储数据,数据行按照主键顺序存储B+树中;每个表只能有一个聚簇索引;主键值唯一且不能为空;如果没有显示定义主键,InnoDB会自动创建一个隐藏的聚簇索引。
-
二级索引(Secondary Index):除了主键索引外,其他索引称为二级索引,二级索引的叶子节点存储的是主键值;可以有多个二级索引;二级索引的叶子节点存储的是主键值,而不是数据行的物理地址。
表空间管理
-
数据文件:数据文件(如ibdata1和.ibd文件)存储表的数据和索引。
-
数据页:每个页包含多个数据行,页头包含元数据信息。
-
页链表:页之间通过链表连接,形成逻辑上的连续存储。
3、事务处理
事务日志(Redo Log)
-
Redo日志记录了对数据页的所有修改操作,用于恢复数据。
-
保证了事务的持久性,减少了对磁盘的写操作,提高性能。
回滚日志(Undo Log)
-
Undo日志记录了事务的修改前的数据状态,用于事务回滚和多版本并发控制(MVCC)。
-
保证了事务的原子性和一致性,支持多版本并发控制。
4、并发控制
InnoDB使用行级锁来提高并发控制。(锁机制看上一篇文章)
5、多版本并发控制(MVCC)
-
定义:MVCC通过为数据记录生成多个版本,允许不同事务看到不同时间点的数据快照,从而减少锁的竞争。
-
实现:
每个数据行包含多个版本,每个版本记录了生成该版本的事务ID。
事务在读取数据时,会根据事务快照选择合适的数据版本。
6、优化与维护
索引优化
-
选择合适的索引类型:根据查询需求选择合适的索引类型,如B+树索引,全文索引等。
-
避免过度索引:过多的索引会增加写操作的开销,影响性能。
缓冲优化
缓冲池(Buffer Poll)是InnoDB用于缓存数据页和索引页的内存区域。用来减少磁盘I/O操作,提高性能;缓存最近访问的数据页,加快数据访问速度。
日志缓冲用于暂存Redo日志,定期刷新磁盘。
-
调整缓冲池的大小:根据系统内存和数据量调整缓冲区大小,提高缓冲命中率。
-
定期检查缓存状态:监控缓存使用情况,及时调整配置。
维护操作
-
定期分析和优化表:使用analyze table和optimize table命令分析和优化表结构。
-
备份和恢复:定期备份数据,确保数据安全。
InnoDB 存储引擎通过其强大的事务处理、行级锁定、多版本并发控制和高效的数据存储机制,成为 MySQL 中最常用的存储引擎之一。
(二)多版本并发控制(MVCC)简介
多版本并发控制(Multi - Version Concurrency Control,简称MVCC)是一种数据库管理系统中的并发控制方法,用于提高数据库系统的并发性能,同时保证数据的一致性和隔离性。
核心思想:MVCC通过为数据记录生成多个版本,允许不同事务看到不同时间点的数据快照,从而减少锁的竞争,提高并发性能。
MVCC的工作原理
1、版本生成:
-
每次对数据进行修改(插入、更新、删除)时,数据库会生成一个新的数据版本。
-
每个版本包含一个事务ID和可能的前一个版本的指针。
2、事务快照:
-
每个事务开始时,数据库会生成一个事务快照,记录当前活动的事务ID。
-
事务在读取数据时,会根据快照选择合适的数据版本。
3、读操作和写操作:
-
读操作不会阻塞其他读操作或写操作。
-
读操作会根据事务快照选择一个可见的数据版本。
-
写操作会生成新的数据版本,但不会立即删除旧版本。
-
写操作可能会阻塞其他写操作,但不会阻塞读操作。
MVCC的优点和缺点
优点:
-
读操作不需要获取锁,减少了锁的竞争,提高了并发性能。
-
由于读操作不需要锁,系统可以处理更多的并发请求,减少了锁管理的开销。
-
读操作可以快速返回结果,提高了系统的响应速度。
缺点:
-
生成多个数据版本会增加存储开销,尤其是在频繁更新的场景下。
-
旧版本的数据需要定期清理,增加了垃圾回收的复杂性。
实现细节
事务 ID:每个事务在开始时都会被分配一个唯一的事务 ID。
版本链:每个数据记录都有一个版本链,链中的每个节点代表一个版本。
可见性规则:事务在读取数据时,会根据事务快照和版本链中的事务 ID 判断数据版本的可见性。
示例:
假设有一个简单的表 users
,包含以下数据:
id | name | version |
---|---|---|
1 | Alice | 1 |
-
事务 T1 开始,事务 ID 为 100。
-
事务 T1 更新
users
表,将name
从Alice
改为Bob
。-
生成新版本,版本号为 100。
-
版本链变为:
-
id=1, name=Alice, version=1
-
id=1, name=Bob, version=100
-
-
-
事务 T2 开始,事务 ID 为 101。
-
事务 T2 查询
users
表。-
事务 T2 在开始时会生成一个事务快照,这个快照包含了事务开始时所有可见的数据版本。
-
事务 T2 只能看到在其开始之前已经提交的事务生成的版本,
id=1, name=Alice, version=1
这个版本,因为事务 T1 尚未提交,版本id=1, name=Bob, version=100
不可见。
-
-
事务 T1 提交。(事务T1提交后,版本
id=1, name=Bob, version=100
成为已提交的版本。) -
事务 T3 开始,事务 ID 为 102。
-
事务 T3 查询
users
表。-
根据事务快照,T3 可以看到
id=1, name=Bob, version=100
这个版本。
-
示例总结
-
事务 T1:更新
users
表,生成新版本id=1, name=Bob, version=100
,但未提交。 -
事务 T2:查询
users
表,只能看到id=1, name=Alice, version=1
,因为事务 T1 尚未提交。 -
事务 T1 提交:版本
id=1, name=Bob, version=100
成为已提交的版本。 -
事务 T3:查询
users
表,可以看到id=1, name=Bob, version=100
,因为事务 T1 已经提交。
MVCC 是一种高效的并发控制机制,通过生成多个数据版本,减少了锁的竞争,提高了系统的并发性能。虽然它会增加存储开销和垃圾回收的复杂性,但在大多数情况下,这些开销是可以接受的,特别是在高并发的场景下。
(三)Redis简介
Redis(Remote Dictionary Server)是一个开源的、基于键值对存储的非关系型数据库NoSQL,它支持多种数据结构如字符串(Strings)、哈希(Hashes)、列表(Lists)、集合(Sets)、有序集合(Sorted Sets)等。Redis以其高性能、丰富的功能和灵活的数据模型而闻名,广泛应用于缓存、消息队列、会话存储等场景。
基本数据类型
-
String
-
单值存储,通过
set [key] [value]
命令设置键值对。 -
支持原子性的递增递减操作,如
incr
和decr
。
-
-
Hash
-
存储字段和值的映射关系,适用于存储对象。
-
使用
hset [table] [key] [value]
命令可以向哈希表中添加或更新字段值,例如向购物车中添加商品。
-
-
List
-
双向链表实现,支持从两端插入和删除元素。
-
lpush [key] [value]
将一个值插入到列表的头部。
-
-
Set
-
无序集合,不允许重复元素。
-
使用
sadd [key] [元素]
向集合中添加成员,如果成员已存在,则不会重复添加,适合用于抽奖等场景。
-
-
Sorted Set
-
有序集合,每个成员关联一个分数,用于排序。
-
通过
zadd [key] [分值] [元素]
添加带有分数的成员,可用于实现排行榜等功能。
-
高级特性
-
持久化
-
Redis提供了RDB(快照)和AOF(追加日志)两种持久化方式,以确保数据的安全性和可靠性。
-
RDB是在指定的时间间隔内创建内存状态的一个快照,而AOF则是记录服务器接收到的所有写操作命令。
-
-
Redis企业版
-
采用Redis on Flash分层存储技术,结合内存、闪存和磁盘,提高成本效益。
-
Active-Active地理分布式架构支持跨地理位置的同时读写操作,提供低延迟和高吞吐量。
-
-
性能优化
-
Redis是单线程处理客户端请求,但通过异步IO和多路复用技术实现了非常高的并发性能。
-
数据全部存储在内存中,访问速度快,但内存资源有限,因此合理使用Redis的内存管理机制非常重要。
-